diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-07-14 17:41:05 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2016-08-04 12:37:36 +0000 |
commit | 399c965b6064c440ddcf4015f5f8e9d131c7a0a6 (patch) | |
tree | 6b06b60ff365abef0e13b3503d593a0df48d20e8 /chromium/cc | |
parent | 7366110654eec46f21b6824f302356426f48cd74 (diff) | |
download | qtwebengine-chromium-399c965b6064c440ddcf4015f5f8e9d131c7a0a6.tar.gz |
BASELINE: Update Chromium to 52.0.2743.76 and Ninja to 1.7.1
Change-Id: I382f51b959689505a60f8b707255ecb344f7d8b4
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/cc')
594 files changed, 27213 insertions, 23325 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn index 47bf6a837b2..0696bf7973f 100644 --- a/chromium/cc/BUILD.gn +++ b/chromium/cc/BUILD.gn @@ -20,21 +20,16 @@ component("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", - "animation/layer_animation_controller.h", - "animation/layer_animation_event_observer.h", - "animation/layer_animation_value_observer.h", - "animation/layer_animation_value_provider.h", "animation/scroll_offset_animation_curve.cc", "animation/scroll_offset_animation_curve.h", + "animation/scroll_offset_animations_impl.cc", + "animation/scroll_offset_animations_impl.h", "animation/target_property.cc", "animation/target_property.h", "animation/timing_function.cc", @@ -52,10 +47,6 @@ component("cc") { "debug/devtools_instrumentation.h", "debug/frame_rate_counter.cc", "debug/frame_rate_counter.h", - "debug/frame_timing_request.cc", - "debug/frame_timing_request.h", - "debug/frame_timing_tracker.cc", - "debug/frame_timing_tracker.h", "debug/frame_viewer_instrumentation.cc", "debug/frame_viewer_instrumentation.h", "debug/invalidation_benchmark.cc", @@ -124,16 +115,14 @@ component("cc") { "layers/heads_up_display_layer.h", "layers/heads_up_display_layer_impl.cc", "layers/heads_up_display_layer_impl.h", - "layers/io_surface_layer.cc", - "layers/io_surface_layer.h", - "layers/io_surface_layer_impl.cc", - "layers/io_surface_layer_impl.h", "layers/layer.cc", "layers/layer.h", "layers/layer_client.h", "layers/layer_collections.h", "layers/layer_impl.cc", "layers/layer_impl.h", + "layers/layer_impl_test_properties.cc", + "layers/layer_impl_test_properties.h", "layers/layer_iterator.h", "layers/layer_list_iterator.cc", "layers/layer_list_iterator.h", @@ -210,7 +199,6 @@ component("cc") { "output/compositor_frame_ack.h", "output/compositor_frame_metadata.cc", "output/compositor_frame_metadata.h", - "output/context_provider.cc", "output/context_provider.h", "output/copy_output_request.cc", "output/copy_output_request.h", @@ -277,12 +265,16 @@ component("cc") { "output/texture_mailbox_deleter.h", "output/viewport_selection_bound.cc", "output/viewport_selection_bound.h", + "output/vulkan_context_provider.h", + "output/vulkan_in_process_context_provider.cc", + "output/vulkan_in_process_context_provider.h", "playback/clip_display_item.cc", "playback/clip_display_item.h", "playback/clip_path_display_item.cc", "playback/clip_path_display_item.h", "playback/compositing_display_item.cc", "playback/compositing_display_item.h", + "playback/decoded_draw_image.cc", "playback/decoded_draw_image.h", "playback/discardable_image_map.cc", "playback/discardable_image_map.h", @@ -335,8 +327,6 @@ component("cc") { "quads/draw_polygon.h", "quads/draw_quad.cc", "quads/draw_quad.h", - "quads/io_surface_draw_quad.cc", - "quads/io_surface_draw_quad.h", "quads/largest_draw_quad.cc", "quads/largest_draw_quad.h", "quads/picture_draw_quad.cc", @@ -361,16 +351,18 @@ component("cc") { "quads/tile_draw_quad.h", "quads/yuv_video_draw_quad.cc", "quads/yuv_video_draw_quad.h", - "raster/bitmap_tile_task_worker_pool.cc", - "raster/bitmap_tile_task_worker_pool.h", + "raster/bitmap_raster_buffer_provider.cc", + "raster/bitmap_raster_buffer_provider.h", + "raster/gpu_raster_buffer_provider.cc", + "raster/gpu_raster_buffer_provider.h", "raster/gpu_rasterizer.cc", "raster/gpu_rasterizer.h", - "raster/gpu_tile_task_worker_pool.cc", - "raster/gpu_tile_task_worker_pool.h", - "raster/one_copy_tile_task_worker_pool.cc", - "raster/one_copy_tile_task_worker_pool.h", + "raster/one_copy_raster_buffer_provider.cc", + "raster/one_copy_raster_buffer_provider.h", "raster/raster_buffer.cc", "raster/raster_buffer.h", + "raster/raster_buffer_provider.cc", + "raster/raster_buffer_provider.h", "raster/scoped_gpu_raster.cc", "raster/scoped_gpu_raster.h", "raster/single_thread_task_graph_runner.cc", @@ -379,8 +371,9 @@ component("cc") { "raster/staging_buffer_pool.h", "raster/synchronous_task_graph_runner.cc", "raster/synchronous_task_graph_runner.h", + "raster/task.cc", + "raster/task.h", "raster/task_category.h", - "raster/task_graph_runner.cc", "raster/task_graph_runner.h", "raster/task_graph_work_queue.cc", "raster/task_graph_work_queue.h", @@ -388,12 +381,10 @@ component("cc") { "raster/texture_compressor.h", "raster/texture_compressor_etc1.cc", "raster/texture_compressor_etc1.h", - "raster/tile_task_runner.cc", - "raster/tile_task_runner.h", - "raster/tile_task_worker_pool.cc", - "raster/tile_task_worker_pool.h", - "raster/zero_copy_tile_task_worker_pool.cc", - "raster/zero_copy_tile_task_worker_pool.h", + "raster/tile_task.cc", + "raster/tile_task.h", + "raster/zero_copy_raster_buffer_provider.cc", + "raster/zero_copy_raster_buffer_provider.h", "resources/memory_history.cc", "resources/memory_history.h", "resources/platform_color.h", @@ -474,6 +465,8 @@ component("cc") { "tiles/tile_manager.h", "tiles/tile_priority.cc", "tiles/tile_priority.h", + "tiles/tile_task_manager.cc", + "tiles/tile_task_manager.h", "tiles/tiling_set_eviction_queue.cc", "tiles/tiling_set_eviction_queue.h", "tiles/tiling_set_raster_queue_all.cc", @@ -573,9 +566,6 @@ component("cc") { if (enable_vulkan) { sources += [ - "output/vulkan_context_provider.h", - "output/vulkan_in_process_context_provider.cc", - "output/vulkan_in_process_context_provider.h", "output/vulkan_renderer.cc", "output/vulkan_renderer.h", ] @@ -630,6 +620,8 @@ source_set("test_support") { "test/fake_picture_layer_tiling_client.h", "test/fake_proxy.cc", "test/fake_proxy.h", + "test/fake_raster_buffer_provider.cc", + "test/fake_raster_buffer_provider.h", "test/fake_raster_source.cc", "test/fake_raster_source.h", "test/fake_recording_source.cc", @@ -646,6 +638,8 @@ source_set("test_support") { "test/fake_tile_manager.h", "test/fake_tile_manager_client.cc", "test/fake_tile_manager_client.h", + "test/fake_tile_task_manager.cc", + "test/fake_tile_task_manager.h", "test/fake_ui_resource_layer_tree_host_impl.cc", "test/fake_ui_resource_layer_tree_host_impl.h", "test/fake_video_frame_provider.cc", @@ -662,6 +656,8 @@ source_set("test_support") { "test/layer_tree_pixel_resource_test.h", "test/layer_tree_pixel_test.cc", "test/layer_tree_pixel_test.h", + "test/layer_tree_settings_for_testing.cc", + "test/layer_tree_settings_for_testing.h", "test/layer_tree_test.cc", "test/layer_tree_test.h", "test/mock_helper.h", @@ -718,6 +714,8 @@ 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_layer_tree_host_base.cc", + "test/test_layer_tree_host_base.h", "test/test_occlusion_tracker.h", "test/test_shared_bitmap_manager.cc", "test/test_shared_bitmap_manager.h", @@ -755,16 +753,13 @@ source_set("test_support") { "//skia", "//testing/gmock", "//testing/gtest", + "//third_party/mesa:osmesa", "//ui/gfx", "//ui/gfx:test_support", "//ui/gfx/geometry", "//ui/gl", "//ui/gl:test_support", ] - - if (!is_android) { # TODO(GYP) Enable on Android when osmesa links. - deps += [ "//third_party/mesa:osmesa" ] - } } test("cc_unittests") { @@ -775,7 +770,6 @@ test("cc_unittests") { "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", "animation/transform_operations_unittest.cc", "base/contiguous_container_unittest.cc", @@ -791,7 +785,6 @@ test("cc_unittests") { "base/simple_enclosed_region_unittest.cc", "base/tiling_data_unittest.cc", "base/unique_notifier_unittest.cc", - "debug/frame_timing_tracker_unittest.cc", "debug/layer_tree_debug_state_unittest.cc", "debug/micro_benchmark_controller_unittest.cc", "debug/rendering_stats_unittest.cc", @@ -800,9 +793,9 @@ test("cc_unittests") { "input/scrollbar_animation_controller_linear_fade_unittest.cc", "input/scrollbar_animation_controller_thinning_unittest.cc", "input/top_controls_manager_unittest.cc", + "ipc/cc_param_traits_unittest.cc", "layers/heads_up_display_layer_impl_unittest.cc", "layers/heads_up_display_unittest.cc", - "layers/io_surface_layer_impl_unittest.cc", "layers/layer_impl_unittest.cc", "layers/layer_iterator_unittest.cc", "layers/layer_list_iterator_unittest.cc", @@ -860,11 +853,11 @@ test("cc_unittests") { "quads/draw_polygon_unittest.cc", "quads/draw_quad_unittest.cc", "quads/render_pass_unittest.cc", + "raster/raster_buffer_provider_unittest.cc", "raster/scoped_gpu_raster_unittest.cc", "raster/single_thread_task_graph_runner_unittest.cc", "raster/synchronous_task_graph_runner_unittest.cc", "raster/texture_compressor_etc1_unittest.cc", - "raster/tile_task_worker_pool_unittest.cc", "resources/platform_color_unittest.cc", "resources/resource_pool_unittest.cc", "resources/resource_provider_unittest.cc", @@ -882,6 +875,7 @@ test("cc_unittests") { "test/mock_helper_unittest.cc", "test/ordered_simple_task_runner_unittest.cc", "test/test_web_graphics_context_3d_unittest.cc", + "tiles/gpu_image_decode_controller_unittest.cc", "tiles/picture_layer_tiling_set_unittest.cc", "tiles/picture_layer_tiling_unittest.cc", "tiles/software_image_decode_controller_unittest.cc", @@ -938,14 +932,17 @@ test("cc_unittests") { ] configs += [ "//build/config:precompiled_headers" ] - data = [ - "test/data/", - ] + if (!is_android) { + data = [ + "test/data/", + ] + } deps = [ ":cc", ":test_support", "//base/test:test_support", + "//cc/ipc", "//cc/proto", "//cc/surfaces", "//cc/surfaces:surface_id", @@ -972,16 +969,16 @@ test("cc_unittests") { test("cc_perftests") { sources = [ "animation/animation_host_perftest.cc", + "ipc/cc_param_traits_perftest.cc", "layers/layer_perftest.cc", "layers/picture_layer_impl_perftest.cc", "quads/draw_quad_perftest.cc", + "raster/raster_buffer_provider_perftest.cc", "raster/task_graph_runner_perftest.cc", "raster/texture_compressor_perftest.cc", - "raster/tile_task_worker_pool_perftest.cc", "surfaces/surface_aggregator_perftest.cc", "test/cc_test_suite.cc", "test/run_all_perftests.cc", - "tiles/picture_layer_tiling_perftest.cc", "tiles/tile_manager_perftest.cc", "trees/layer_tree_host_common_perftest.cc", "trees/layer_tree_host_perftest.cc", @@ -993,6 +990,7 @@ test("cc_perftests") { ":test_support", "//base", "//base/test:test_support", + "//cc/ipc", "//cc/surfaces", "//cc/surfaces:surface_id", "//gpu", @@ -1009,9 +1007,8 @@ test("cc_perftests") { "//ui/gl:test_support", ] - if (is_android) { - isolate_file = "cc_perftests.isolate" - } + # This target should not require the Chrome executable to run. + assert_no_deps = [ "//chrome" ] } # 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/PRESUBMIT.py b/chromium/cc/PRESUBMIT.py index d79ca8005f7..c1f2ad20b17 100644 --- a/chromium/cc/PRESUBMIT.py +++ b/chromium/cc/PRESUBMIT.py @@ -152,7 +152,7 @@ def CheckDoubleAngles(input_api, output_api, white_list=CC_SOURCE_FILES, return [output_api.PresubmitError('Use >> instead of > >:', items=errors)] return [] -def CheckScopedPtr(input_api, output_api, +def CheckUniquePtr(input_api, output_api, white_list=CC_SOURCE_FILES, black_list=None): black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST) source_file_filter = lambda x: input_api.FilterSourceFile(x, @@ -162,20 +162,20 @@ def CheckScopedPtr(input_api, output_api, for f in input_api.AffectedSourceFiles(source_file_filter): for line_number, line in f.ChangedContents(): # Disallow: - # return scoped_ptr<T>(foo); - # bar = scoped_ptr<T>(foo); + # return std::unique_ptr<T>(foo); + # bar = std::unique_ptr<T>(foo); # But allow: - # return scoped_ptr<T[]>(foo); - # bar = scoped_ptr<T[]>(foo); - if re.search(r'(=|\breturn)\s*scoped_ptr<.*?(?<!])>\([^)]+\)', line): + # return std::unique_ptr<T[]>(foo); + # bar = std::unique_ptr<T[]>(foo); + if re.search(r'(=|\breturn)\s*std::unique_ptr<.*?(?<!])>\([^)]+\)', line): errors.append(output_api.PresubmitError( - ('%s:%d uses explicit scoped_ptr constructor. ' + - 'Use make_scoped_ptr() instead.') % (f.LocalPath(), line_number))) + ('%s:%d uses explicit std::unique_ptr constructor. ' + + 'Use base::WrapUnique() instead.') % (f.LocalPath(), line_number))) # Disallow: - # scoped_ptr<T>() - if re.search(r'\bscoped_ptr<.*?>\(\)', line): + # std::unique_ptr<T>() + if re.search(r'\bstd::unique_ptr<.*?>\(\)', line): errors.append(output_api.PresubmitError( - '%s:%d uses scoped_ptr<T>(). Use nullptr instead.' % + '%s:%d uses std::unique_ptr<T>(). Use nullptr instead.' % (f.LocalPath(), line_number))) return errors @@ -318,7 +318,7 @@ def CheckChangeOnUpload(input_api, output_api): results += CheckChangeLintsClean(input_api, output_api) results += CheckTodos(input_api, output_api) results += CheckDoubleAngles(input_api, output_api) - results += CheckScopedPtr(input_api, output_api) + results += CheckUniquePtr(input_api, output_api) results += CheckNamespace(input_api, output_api) results += CheckForUseOfWrongClock(input_api, output_api) results += FindUselessIfdefs(input_api, output_api) diff --git a/chromium/cc/animation/animation.cc b/chromium/cc/animation/animation.cc index 5d3462773ad..f6c3a104de4 100644 --- a/chromium/cc/animation/animation.cc +++ b/chromium/cc/animation/animation.cc @@ -6,6 +6,7 @@ #include <cmath> +#include "base/memory/ptr_util.h" #include "base/strings/string_util.h" #include "base/trace_event/trace_event.h" #include "cc/animation/animation_curve.h" @@ -32,15 +33,16 @@ static_assert(static_cast<int>(cc::Animation::LAST_RUN_STATE) + 1 == namespace cc { -scoped_ptr<Animation> Animation::Create(scoped_ptr<AnimationCurve> curve, - int animation_id, - int group_id, - TargetProperty::Type target_property) { - return make_scoped_ptr( +std::unique_ptr<Animation> Animation::Create( + std::unique_ptr<AnimationCurve> curve, + int animation_id, + int group_id, + TargetProperty::Type target_property) { + return base::WrapUnique( new Animation(std::move(curve), animation_id, group_id, target_property)); } -Animation::Animation(scoped_ptr<AnimationCurve> curve, +Animation::Animation(std::unique_ptr<AnimationCurve> curve, int animation_id, int group_id, TargetProperty::Type target_property) @@ -51,16 +53,16 @@ Animation::Animation(scoped_ptr<AnimationCurve> curve, run_state_(WAITING_FOR_TARGET_AVAILABILITY), iterations_(1), iteration_start_(0), - direction_(DIRECTION_NORMAL), + direction_(Direction::NORMAL), playback_rate_(1), - fill_mode_(FILL_MODE_BOTH), + fill_mode_(FillMode::BOTH), needs_synchronized_start_time_(false), received_finished_event_(false), suspended_(false), is_controlling_instance_(false), is_impl_only_(false), - affects_active_observers_(true), - affects_pending_observers_(true) {} + affects_active_elements_(true), + affects_pending_elements_(true) {} Animation::~Animation() { if (run_state_ == RUNNING || run_state_ == PAUSED) @@ -106,13 +108,9 @@ void Animation::SetRunState(RunState run_state, old_run_state_name, new_run_state_name); - TRACE_EVENT_INSTANT2("cc", - "LayerAnimationController::SetRunState", - TRACE_EVENT_SCOPE_THREAD, - "Name", - TRACE_STR_COPY(name_buffer), - "State", - TRACE_STR_COPY(state_buffer)); + TRACE_EVENT_INSTANT2( + "cc", "ElementAnimations::SetRunState", TRACE_EVENT_SCOPE_THREAD, "Name", + TRACE_STR_COPY(name_buffer), "State", TRACE_STR_COPY(state_buffer)); } void Animation::Suspend(base::TimeTicks monotonic_time) { @@ -143,7 +141,7 @@ bool Animation::IsFinishedAt(base::TimeTicks monotonic_time) const { bool Animation::InEffect(base::TimeTicks monotonic_time) const { return ConvertToActiveTime(monotonic_time) >= base::TimeDelta() || - (fill_mode_ == FILL_MODE_BOTH || fill_mode_ == FILL_MODE_BACKWARDS); + (fill_mode_ == FillMode::BOTH || fill_mode_ == FillMode::BACKWARDS); } base::TimeDelta Animation::ConvertToActiveTime( @@ -227,9 +225,9 @@ base::TimeDelta Animation::TrimTimeToCurrentIteration( // Check if we are running the animation in reverse direction for the current // iteration bool reverse = - (direction_ == DIRECTION_REVERSE) || - (direction_ == DIRECTION_ALTERNATE && iteration % 2 == 1) || - (direction_ == DIRECTION_ALTERNATE_REVERSE && iteration % 2 == 0); + (direction_ == Direction::REVERSE) || + (direction_ == Direction::ALTERNATE_NORMAL && iteration % 2 == 1) || + (direction_ == Direction::ALTERNATE_REVERSE && iteration % 2 == 0); // If we are running the animation in reverse direction, reverse the result if (reverse) @@ -238,9 +236,9 @@ base::TimeDelta Animation::TrimTimeToCurrentIteration( return iteration_time; } -scoped_ptr<Animation> Animation::CloneAndInitialize( +std::unique_ptr<Animation> Animation::CloneAndInitialize( RunState initial_run_state) const { - scoped_ptr<Animation> to_return( + std::unique_ptr<Animation> to_return( new Animation(curve_->Clone(), id_, group_, target_property_)); to_return->run_state_ = initial_run_state; to_return->iterations_ = iterations_; diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h index c1463223b74..07702dc8756 100644 --- a/chromium/cc/animation/animation.h +++ b/chromium/cc/animation/animation.h @@ -5,8 +5,9 @@ #ifndef CC_ANIMATION_ANIMATION_H_ #define CC_ANIMATION_ANIMATION_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/animation/target_property.h" #include "cc/base/cc_export.h" @@ -44,24 +45,15 @@ class CC_EXPORT Animation { LAST_RUN_STATE = ABORTED_BUT_NEEDS_COMPLETION }; - enum Direction { - DIRECTION_NORMAL, - DIRECTION_REVERSE, - DIRECTION_ALTERNATE, - DIRECTION_ALTERNATE_REVERSE - }; + enum class Direction { NORMAL, REVERSE, ALTERNATE_NORMAL, ALTERNATE_REVERSE }; - enum FillMode { - FILL_MODE_NONE, - FILL_MODE_FORWARDS, - FILL_MODE_BACKWARDS, - FILL_MODE_BOTH - }; + enum class FillMode { NONE, FORWARDS, BACKWARDS, BOTH }; - static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve, - int animation_id, - int group_id, - TargetProperty::Type target_property); + static std::unique_ptr<Animation> Create( + std::unique_ptr<AnimationCurve> curve, + int animation_id, + int group_id, + TargetProperty::Type target_property); virtual ~Animation(); @@ -144,7 +136,8 @@ class CC_EXPORT Animation { base::TimeDelta TrimTimeToCurrentIteration( base::TimeTicks monotonic_time) const; - scoped_ptr<Animation> CloneAndInitialize(RunState initial_run_state) const; + std::unique_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; @@ -156,25 +149,25 @@ class CC_EXPORT Animation { 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 set_affects_active_observers(bool affects_active_observers) { - affects_active_observers_ = affects_active_observers; + void set_affects_active_elements(bool affects_active_elements) { + affects_active_elements_ = affects_active_elements; } - bool affects_active_observers() const { return affects_active_observers_; } + bool affects_active_elements() const { return affects_active_elements_; } - void set_affects_pending_observers(bool affects_pending_observers) { - affects_pending_observers_ = affects_pending_observers; + void set_affects_pending_elements(bool affects_pending_elements) { + affects_pending_elements_ = affects_pending_elements; } - bool affects_pending_observers() const { return affects_pending_observers_; } + bool affects_pending_elements() const { return affects_pending_elements_; } private: - Animation(scoped_ptr<AnimationCurve> curve, + Animation(std::unique_ptr<AnimationCurve> curve, int animation_id, int group_id, TargetProperty::Type target_property); base::TimeDelta ConvertToActiveTime(base::TimeTicks monotonic_time) const; - scoped_ptr<AnimationCurve> curve_; + std::unique_ptr<AnimationCurve> curve_; // IDs must be unique. int id_; @@ -227,18 +220,18 @@ class CC_EXPORT Animation { bool is_impl_only_; // When pushed from a main-thread controller to a compositor-thread - // controller, an animation will initially only affect pending observers + // controller, an animation will initially only affect pending elements // (corresponding to layers in the pending tree). Animations that only - // affect pending observers are able to reach the STARTING state and tick - // pending observers, but cannot proceed any further and do not tick active - // observers. After activation, such animations affect both kinds of observers + // affect pending elements are able to reach the STARTING state and tick + // pending elements, but cannot proceed any further and do not tick active + // elements. After activation, such animations affect both kinds of elements // and are able to proceed past the STARTING state. When the removal of // an animation is pushed from a main-thread controller to a // compositor-thread controller, this initially only makes the animation - // stop affecting pending observers. After activation, such animations no - // longer affect any observers, and are deleted. - bool affects_active_observers_; - bool affects_pending_observers_; + // stop affecting pending elements. After activation, such animations no + // longer affect any elements, and are deleted. + bool affects_active_elements_; + bool affects_pending_elements_; DISALLOW_COPY_AND_ASSIGN(Animation); }; diff --git a/chromium/cc/animation/animation_curve.h b/chromium/cc/animation/animation_curve.h index 68bad3ba3b5..a54480c5e8c 100644 --- a/chromium/cc/animation/animation_curve.h +++ b/chromium/cc/animation/animation_curve.h @@ -5,7 +5,8 @@ #ifndef CC_ANIMATION_ANIMATION_CURVE_H_ #define CC_ANIMATION_ANIMATION_CURVE_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/output/filter_operations.h" @@ -33,7 +34,7 @@ class CC_EXPORT AnimationCurve { virtual base::TimeDelta Duration() const = 0; virtual CurveType Type() const = 0; - virtual scoped_ptr<AnimationCurve> Clone() const = 0; + virtual std::unique_ptr<AnimationCurve> Clone() const = 0; const ColorAnimationCurve* ToColorAnimationCurve() const; const FloatAnimationCurve* ToFloatAnimationCurve() const; diff --git a/chromium/cc/animation/animation_delegate.h b/chromium/cc/animation/animation_delegate.h index aee077cd170..c7ec2bb3321 100644 --- a/chromium/cc/animation/animation_delegate.h +++ b/chromium/cc/animation/animation_delegate.h @@ -24,10 +24,11 @@ class CC_EXPORT AnimationDelegate { TargetProperty::Type target_property, int group) = 0; - virtual void NotifyAnimationTakeover(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - double animation_start_time, - scoped_ptr<AnimationCurve> curve) = 0; + virtual void NotifyAnimationTakeover( + base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + double animation_start_time, + std::unique_ptr<AnimationCurve> curve) = 0; protected: virtual ~AnimationDelegate() {} diff --git a/chromium/cc/animation/animation_events.cc b/chromium/cc/animation/animation_events.cc index e747f8bec2a..8c39e26a776 100644 --- a/chromium/cc/animation/animation_events.cc +++ b/chromium/cc/animation/animation_events.cc @@ -7,12 +7,12 @@ namespace cc { AnimationEvent::AnimationEvent(AnimationEvent::Type type, - int layer_id, + ElementId element_id, int group_id, TargetProperty::Type target_property, base::TimeTicks monotonic_time) : type(type), - layer_id(layer_id), + element_id(element_id), group_id(group_id), target_property(target_property), monotonic_time(monotonic_time), @@ -21,7 +21,7 @@ AnimationEvent::AnimationEvent(AnimationEvent::Type type, AnimationEvent::AnimationEvent(const AnimationEvent& other) { type = other.type; - layer_id = other.layer_id; + element_id = other.element_id; group_id = other.group_id; target_property = other.target_property; monotonic_time = other.monotonic_time; @@ -36,7 +36,7 @@ AnimationEvent::AnimationEvent(const AnimationEvent& other) { AnimationEvent& AnimationEvent::operator=(const AnimationEvent& other) { type = other.type; - layer_id = other.layer_id; + element_id = other.element_id; group_id = other.group_id; target_property = other.target_property; monotonic_time = other.monotonic_time; diff --git a/chromium/cc/animation/animation_events.h b/chromium/cc/animation/animation_events.h index 73a705895d6..fc0c41e9d1c 100644 --- a/chromium/cc/animation/animation_events.h +++ b/chromium/cc/animation/animation_events.h @@ -5,13 +5,14 @@ #ifndef CC_ANIMATION_ANIMATION_EVENTS_H_ #define CC_ANIMATION_ANIMATION_EVENTS_H_ +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" #include "cc/animation/animation.h" #include "cc/animation/animation_curve.h" #include "cc/base/cc_export.h" #include "cc/output/filter_operations.h" +#include "cc/trees/mutator_host_client.h" #include "ui/gfx/transform.h" namespace cc { @@ -20,7 +21,7 @@ struct CC_EXPORT AnimationEvent { enum Type { STARTED, FINISHED, ABORTED, PROPERTY_UPDATE, TAKEOVER }; AnimationEvent(Type type, - int layer_id, + ElementId element_id, int group_id, TargetProperty::Type target_property, base::TimeTicks monotonic_time); @@ -31,7 +32,7 @@ struct CC_EXPORT AnimationEvent { ~AnimationEvent(); Type type; - int layer_id; + ElementId element_id; int group_id; TargetProperty::Type target_property; base::TimeTicks monotonic_time; @@ -42,7 +43,7 @@ struct CC_EXPORT AnimationEvent { // For continuing a scroll offset animation on the main thread. double animation_start_time; - scoped_ptr<AnimationCurve> curve; + std::unique_ptr<AnimationCurve> curve; }; class CC_EXPORT AnimationEvents { diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc index 61a24a9d223..71f9c0ccecc 100644 --- a/chromium/cc/animation/animation_host.cc +++ b/chromium/cc/animation/animation_host.cc @@ -7,11 +7,13 @@ #include <algorithm> #include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_argument.h" #include "cc/animation/animation_delegate.h" #include "cc/animation/animation_events.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" @@ -21,149 +23,27 @@ 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(), - ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA); - curve->SetInitialValue(current_offset); - - scoped_ptr<Animation> animation = Animation::Create( - std::move(curve), AnimationIdProvider::NextAnimationId(), - AnimationIdProvider::NextGroupId(), TargetProperty::SCROLL_OFFSET); - animation->set_is_impl_only(true); - - DCHECK(scroll_offset_animation_player_); - DCHECK(scroll_offset_animation_player_->animation_timeline()); - - ReattachScrollOffsetPlayerIfNeeded(layer_id); - - scroll_offset_animation_player_->AddAnimation(std::move(animation)); - } - - 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_); - if (!scroll_offset_animation_player_->element_animations()) - return false; - - DCHECK_EQ(layer_id, scroll_offset_animation_player_->layer_id()); - - Animation* animation = scroll_offset_animation_player_->element_animations() - ->layer_animation_controller() - ->GetAnimation(TargetProperty::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; - } - - void ScrollAnimationAbort(bool needs_completion) { - DCHECK(scroll_offset_animation_player_); - scroll_offset_animation_player_->AbortAnimations( - TargetProperty::SCROLL_OFFSET, needs_completion); - } - - // AnimationDelegate implementation. - void NotifyAnimationStarted(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override {} - void NotifyAnimationFinished(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override { - DCHECK_EQ(target_property, TargetProperty::SCROLL_OFFSET); - DCHECK(animation_host_->mutator_host_client()); - animation_host_->mutator_host_client()->ScrollOffsetAnimationFinished(); - } - void NotifyAnimationAborted(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override {} - void NotifyAnimationTakeover(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - double animation_start_time, - scoped_ptr<AnimationCurve> curve) override {} - - private: - void ReattachScrollOffsetPlayerIfNeeded(int layer_id) { - if (scroll_offset_animation_player_->layer_id() != layer_id) { - if (scroll_offset_animation_player_->layer_id()) - scroll_offset_animation_player_->DetachLayer(); - if (layer_id) - scroll_offset_animation_player_->AttachLayer(layer_id); - } - } - - 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( +std::unique_ptr<AnimationHost> AnimationHost::Create( ThreadInstance thread_instance) { - return make_scoped_ptr(new AnimationHost(thread_instance)); + return base::WrapUnique(new AnimationHost(thread_instance)); } AnimationHost::AnimationHost(ThreadInstance thread_instance) - : animation_registrar_(AnimationRegistrar::Create()), - mutator_host_client_(nullptr), - thread_instance_(thread_instance) { + : mutator_host_client_(nullptr), + thread_instance_(thread_instance), + supports_scroll_animations_(false), + animation_waiting_for_deletion_(false) { if (thread_instance_ == ThreadInstance::IMPL) - scroll_offset_animations_ = - make_scoped_ptr(new ScrollOffsetAnimations(this)); + scroll_offset_animations_impl_ = + base::WrapUnique(new ScrollOffsetAnimationsImpl(this)); } AnimationHost::~AnimationHost() { - scroll_offset_animations_ = nullptr; + scroll_offset_animations_impl_ = nullptr; ClearTimelines(); DCHECK(!mutator_host_client()); - DCHECK(layer_to_element_animations_map_.empty()); + DCHECK(element_to_animations_map_.empty()); } AnimationTimeline* AnimationHost::GetTimelineById(int timeline_id) const { @@ -197,54 +77,57 @@ void AnimationHost::RemoveAnimationTimeline( id_to_timeline_map_.erase(timeline->id()); } -void AnimationHost::RegisterLayer(int layer_id, LayerTreeType tree_type) { - ElementAnimations* element_animations = - GetElementAnimationsForLayerId(layer_id); +void AnimationHost::RegisterElement(ElementId element_id, + ElementListType list_type) { + scoped_refptr<ElementAnimations> element_animations = + GetElementAnimationsForElementId(element_id); if (element_animations) - element_animations->LayerRegistered(layer_id, tree_type); + element_animations->ElementRegistered(element_id, list_type); } -void AnimationHost::UnregisterLayer(int layer_id, LayerTreeType tree_type) { - ElementAnimations* element_animations = - GetElementAnimationsForLayerId(layer_id); +void AnimationHost::UnregisterElement(ElementId element_id, + ElementListType list_type) { + scoped_refptr<ElementAnimations> element_animations = + GetElementAnimationsForElementId(element_id); if (element_animations) - element_animations->LayerUnregistered(layer_id, tree_type); + element_animations->ElementUnregistered(element_id, list_type); } -void AnimationHost::RegisterPlayerForLayer(int layer_id, - AnimationPlayer* player) { - DCHECK(layer_id); +void AnimationHost::RegisterPlayerForElement(ElementId element_id, + AnimationPlayer* player) { + DCHECK(element_id); DCHECK(player); - ElementAnimations* element_animations = - GetElementAnimationsForLayerId(layer_id); + scoped_refptr<ElementAnimations> element_animations = + GetElementAnimationsForElementId(element_id); if (!element_animations) { - auto new_element_animations = ElementAnimations::Create(this); - element_animations = new_element_animations.get(); + element_animations = ElementAnimations::Create(); + element_animations->SetElementId(element_id); + RegisterElementAnimations(element_animations.get()); + } - layer_to_element_animations_map_[layer_id] = - std::move(new_element_animations); - element_animations->CreateLayerAnimationController(layer_id); + if (element_animations->animation_host() != this) { + element_animations->SetAnimationHost(this); + element_animations->InitAffectedElementTypes(); } - DCHECK(element_animations); element_animations->AddPlayer(player); } -void AnimationHost::UnregisterPlayerForLayer(int layer_id, - AnimationPlayer* player) { - DCHECK(layer_id); +void AnimationHost::UnregisterPlayerForElement(ElementId element_id, + AnimationPlayer* player) { + DCHECK(element_id); DCHECK(player); - ElementAnimations* element_animations = - GetElementAnimationsForLayerId(layer_id); + scoped_refptr<ElementAnimations> element_animations = + GetElementAnimationsForElementId(element_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; + element_animations->ClearAffectedElementTypes(); + UnregisterElementAnimations(element_animations.get()); + element_animations->SetAnimationHost(nullptr); } } @@ -269,6 +152,7 @@ void AnimationHost::PushPropertiesTo(AnimationHost* host_impl) { PushTimelinesToImplThread(host_impl); RemoveTimelinesFromImplThread(host_impl); PushPropertiesToImplThread(host_impl); + animation_waiting_for_deletion_ = false; } void AnimationHost::PushTimelinesToImplThread(AnimationHost* host_impl) const { @@ -301,8 +185,7 @@ void AnimationHost::RemoveTimelinesFromImplThread( } void AnimationHost::PushPropertiesToImplThread(AnimationHost* host_impl) { - // Firstly, sync all players with impl thread to create ElementAnimations and - // layer animation controllers. + // Firstly, sync all players with impl thread to create ElementAnimations. for (auto& kv : id_to_timeline_map_) { AnimationTimeline* timeline = kv.second.get(); AnimationTimeline* timeline_impl = @@ -311,294 +194,359 @@ void AnimationHost::PushPropertiesToImplThread(AnimationHost* host_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.get(); - ElementAnimations* element_animations_impl = - host_impl->GetElementAnimationsForLayerId(kv.first); + // Secondly, sync properties for created ElementAnimations. + for (auto& kv : element_to_animations_map_) { + const auto& element_animations = kv.second; + auto element_animations_impl = + host_impl->GetElementAnimationsForElementId(kv.first); if (element_animations_impl) - element_animations->PushPropertiesTo(element_animations_impl); + element_animations->PushPropertiesTo(std::move(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.get(); +scoped_refptr<ElementAnimations> +AnimationHost::GetElementAnimationsForElementId(ElementId element_id) const { + DCHECK(element_id); + auto iter = element_to_animations_map_.find(element_id); + return iter == element_to_animations_map_.end() ? nullptr : iter->second; } void AnimationHost::SetSupportsScrollAnimations( bool supports_scroll_animations) { - animation_registrar_->set_supports_scroll_animations( - supports_scroll_animations); + supports_scroll_animations_ = supports_scroll_animations; } bool AnimationHost::SupportsScrollAnimations() const { - return animation_registrar_->supports_scroll_animations(); + return supports_scroll_animations_; } bool AnimationHost::NeedsAnimateLayers() const { - return animation_registrar_->needs_animate_layers(); + return !active_element_to_animations_map_.empty(); } bool AnimationHost::ActivateAnimations() { - return animation_registrar_->ActivateAnimations(); + if (!NeedsAnimateLayers()) + return false; + + TRACE_EVENT0("cc", "AnimationHost::ActivateAnimations"); + ElementToAnimationsMap active_element_animations_map_copy = + active_element_to_animations_map_; + for (auto& it : active_element_animations_map_copy) + it.second->ActivateAnimations(); + + return true; } bool AnimationHost::AnimateLayers(base::TimeTicks monotonic_time) { - return animation_registrar_->AnimateLayers(monotonic_time); -} + if (!NeedsAnimateLayers()) + return false; -bool AnimationHost::UpdateAnimationState(bool start_ready_animations, - AnimationEvents* events) { - return animation_registrar_->UpdateAnimationState(start_ready_animations, - events); -} + TRACE_EVENT0("cc", "AnimationHost::AnimateLayers"); + ElementToAnimationsMap active_element_animations_map_copy = + active_element_to_animations_map_; + for (auto& it : active_element_animations_map_copy) + it.second->Animate(monotonic_time); -scoped_ptr<AnimationEvents> AnimationHost::CreateEvents() { - return animation_registrar_->CreateEvents(); + return true; } -void AnimationHost::SetAnimationEvents(scoped_ptr<AnimationEvents> events) { - return animation_registrar_->SetAnimationEvents(std::move(events)); -} +bool AnimationHost::UpdateAnimationState(bool start_ready_animations, + AnimationEvents* events) { + if (!NeedsAnimateLayers()) + return false; -bool AnimationHost::ScrollOffsetAnimationWasInterrupted(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->scroll_offset_animation_was_interrupted() - : false; + TRACE_EVENT0("cc", "AnimationHost::UpdateAnimationState"); + ElementToAnimationsMap active_element_animations_map_copy = + active_element_to_animations_map_; + for (auto& it : active_element_animations_map_copy) + it.second->UpdateState(start_ready_animations, events); + + return true; +} + +std::unique_ptr<AnimationEvents> AnimationHost::CreateEvents() { + return base::WrapUnique(new AnimationEvents()); +} + +void AnimationHost::SetAnimationEvents( + std::unique_ptr<AnimationEvents> events) { + for (size_t event_index = 0; event_index < events->events_.size(); + ++event_index) { + int event_layer_id = events->events_[event_index].element_id; + + // Use the map of all ElementAnimations, not just active ones, since + // non-active ElementAnimations may still receive events for impl-only + // animations. + const ElementToAnimationsMap& all_element_animations = + element_to_animations_map_; + auto iter = all_element_animations.find(event_layer_id); + if (iter != all_element_animations.end()) { + switch (events->events_[event_index].type) { + case AnimationEvent::STARTED: + (*iter).second->NotifyAnimationStarted(events->events_[event_index]); + break; + + case AnimationEvent::FINISHED: + (*iter).second->NotifyAnimationFinished(events->events_[event_index]); + break; + + case AnimationEvent::ABORTED: + (*iter).second->NotifyAnimationAborted(events->events_[event_index]); + break; + + case AnimationEvent::PROPERTY_UPDATE: + (*iter).second->NotifyAnimationPropertyUpdate( + events->events_[event_index]); + break; + + case AnimationEvent::TAKEOVER: + (*iter).second->NotifyAnimationTakeover(events->events_[event_index]); + break; + } + } + } } -static LayerAnimationController::ObserverType ObserverTypeFromTreeType( - LayerTreeType tree_type) { - return tree_type == LayerTreeType::ACTIVE - ? LayerAnimationController::ObserverType::ACTIVE - : LayerAnimationController::ObserverType::PENDING; +bool AnimationHost::ScrollOffsetAnimationWasInterrupted( + ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->scroll_offset_animation_was_interrupted() + : false; } -bool AnimationHost::IsAnimatingFilterProperty(int layer_id, - LayerTreeType tree_type) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, ObserverTypeFromTreeType(tree_type)) +bool AnimationHost::IsAnimatingFilterProperty(ElementId element_id, + ElementListType list_type) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, list_type) : false; } -bool AnimationHost::IsAnimatingOpacityProperty(int layer_id, - LayerTreeType tree_type) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, ObserverTypeFromTreeType(tree_type)) +bool AnimationHost::IsAnimatingOpacityProperty( + ElementId element_id, + ElementListType list_type) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, list_type) : false; } bool AnimationHost::IsAnimatingTransformProperty( - int layer_id, - LayerTreeType tree_type) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->IsCurrentlyAnimatingProperty( - TargetProperty::TRANSFORM, - ObserverTypeFromTreeType(tree_type)) + ElementId element_id, + ElementListType list_type) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->IsCurrentlyAnimatingProperty( + TargetProperty::TRANSFORM, list_type) : false; } bool AnimationHost::HasPotentiallyRunningFilterAnimation( - int layer_id, - LayerTreeType tree_type) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->IsPotentiallyAnimatingProperty( - TargetProperty::FILTER, ObserverTypeFromTreeType(tree_type)) + ElementId element_id, + ElementListType list_type) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->IsPotentiallyAnimatingProperty( + TargetProperty::FILTER, list_type) : false; } bool AnimationHost::HasPotentiallyRunningOpacityAnimation( - int layer_id, - LayerTreeType tree_type) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, ObserverTypeFromTreeType(tree_type)) + ElementId element_id, + ElementListType list_type) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, list_type) : false; } bool AnimationHost::HasPotentiallyRunningTransformAnimation( - int layer_id, - LayerTreeType tree_type) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->IsPotentiallyAnimatingProperty( - TargetProperty::TRANSFORM, - ObserverTypeFromTreeType(tree_type)) + ElementId element_id, + ElementListType list_type) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->IsPotentiallyAnimatingProperty( + TargetProperty::TRANSFORM, list_type) : false; } bool AnimationHost::HasAnyAnimationTargetingProperty( - int layer_id, + ElementId element_id, TargetProperty::Type property) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - if (!controller) - return false; - - return !!controller->GetAnimation(property); -} - -bool AnimationHost::FilterIsAnimatingOnImplOnly(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - if (!controller) - return false; - - Animation* animation = controller->GetAnimation(TargetProperty::FILTER); - return animation && animation->is_impl_only(); -} - -bool AnimationHost::OpacityIsAnimatingOnImplOnly(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - if (!controller) + auto element_animations = GetElementAnimationsForElementId(element_id); + if (!element_animations) return false; - Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); - return animation && animation->is_impl_only(); + return !!element_animations->GetAnimation(property); } -bool AnimationHost::ScrollOffsetIsAnimatingOnImplOnly(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - if (!controller) +bool AnimationHost::ScrollOffsetIsAnimatingOnImplOnly( + ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + if (!element_animations) return false; Animation* animation = - controller->GetAnimation(TargetProperty::SCROLL_OFFSET); + element_animations->GetAnimation(TargetProperty::SCROLL_OFFSET); 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(TargetProperty::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::HasFilterAnimationThatInflatesBounds( + ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->HasFilterAnimationThatInflatesBounds() + : false; } bool AnimationHost::HasTransformAnimationThatInflatesBounds( - int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->HasTransformAnimationThatInflatesBounds() - : false; + ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->HasTransformAnimationThatInflatesBounds() + : false; } -bool AnimationHost::HasAnimationThatInflatesBounds(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->HasAnimationThatInflatesBounds() : false; +bool AnimationHost::HasAnimationThatInflatesBounds(ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->HasAnimationThatInflatesBounds() + : false; } -bool AnimationHost::FilterAnimationBoundsForBox(int layer_id, +bool AnimationHost::FilterAnimationBoundsForBox(ElementId element_id, const gfx::BoxF& box, gfx::BoxF* bounds) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->FilterAnimationBoundsForBox(box, bounds) - : false; + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->FilterAnimationBoundsForBox(box, bounds) + : false; } -bool AnimationHost::TransformAnimationBoundsForBox(int layer_id, +bool AnimationHost::TransformAnimationBoundsForBox(ElementId element_id, const gfx::BoxF& box, gfx::BoxF* bounds) const { *bounds = gfx::BoxF(); - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->TransformAnimationBoundsForBox(box, bounds) - : true; + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->TransformAnimationBoundsForBox(box, bounds) + : true; } bool AnimationHost::HasOnlyTranslationTransforms( - int layer_id, - LayerTreeType tree_type) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->HasOnlyTranslationTransforms( - ObserverTypeFromTreeType(tree_type)) + ElementId element_id, + ElementListType list_type) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->HasOnlyTranslationTransforms(list_type) : true; } -bool AnimationHost::AnimationsPreserveAxisAlignment(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->AnimationsPreserveAxisAlignment() : true; +bool AnimationHost::AnimationsPreserveAxisAlignment( + ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->AnimationsPreserveAxisAlignment() + : true; } -bool AnimationHost::MaximumTargetScale(int layer_id, - LayerTreeType tree_type, +bool AnimationHost::MaximumTargetScale(ElementId element_id, + ElementListType list_type, float* max_scale) const { *max_scale = 0.f; - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->MaximumTargetScale( - ObserverTypeFromTreeType(tree_type), max_scale) + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->MaximumTargetScale(list_type, max_scale) : true; } -bool AnimationHost::AnimationStartScale(int layer_id, - LayerTreeType tree_type, +bool AnimationHost::AnimationStartScale(ElementId element_id, + ElementListType list_type, float* start_scale) const { *start_scale = 0.f; - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller - ? controller->AnimationStartScale( - ObserverTypeFromTreeType(tree_type), start_scale) + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations + ? element_animations->AnimationStartScale(list_type, start_scale) : true; } -bool AnimationHost::HasAnyAnimation(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->has_any_animation() : false; +bool AnimationHost::HasAnyAnimation(ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations ? element_animations->has_any_animation() : false; } -bool AnimationHost::HasActiveAnimationForTesting(int layer_id) const { - LayerAnimationController* controller = GetControllerForLayerId(layer_id); - return controller ? controller->HasActiveAnimation() : false; +bool AnimationHost::HasActiveAnimationForTesting(ElementId element_id) const { + auto element_animations = GetElementAnimationsForElementId(element_id); + return element_animations ? element_animations->HasActiveAnimation() : false; } void AnimationHost::ImplOnlyScrollAnimationCreate( - int layer_id, + ElementId element_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); + DCHECK(scroll_offset_animations_impl_); + scroll_offset_animations_impl_->ScrollAnimationCreate( + element_id, target_offset, current_offset); } bool AnimationHost::ImplOnlyScrollAnimationUpdateTarget( - int layer_id, + ElementId element_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); + DCHECK(scroll_offset_animations_impl_); + return scroll_offset_animations_impl_->ScrollAnimationUpdateTarget( + element_id, scroll_delta, max_scroll_offset, frame_monotonic_time); } void AnimationHost::ScrollAnimationAbort(bool needs_completion) { - DCHECK(scroll_offset_animations_); - return scroll_offset_animations_->ScrollAnimationAbort(needs_completion); + DCHECK(scroll_offset_animations_impl_); + return scroll_offset_animations_impl_->ScrollAnimationAbort(needs_completion); +} + +void AnimationHost::DidActivateElementAnimations( + ElementAnimations* element_animations) { + DCHECK(element_animations->element_id()); + active_element_to_animations_map_[element_animations->element_id()] = + element_animations; +} + +void AnimationHost::DidDeactivateElementAnimations( + ElementAnimations* element_animations) { + DCHECK(element_animations->element_id()); + active_element_to_animations_map_.erase(element_animations->element_id()); +} + +void AnimationHost::RegisterElementAnimations( + ElementAnimations* element_animations) { + DCHECK(element_animations->element_id()); + element_to_animations_map_[element_animations->element_id()] = + element_animations; +} + +void AnimationHost::UnregisterElementAnimations( + ElementAnimations* element_animations) { + DCHECK(element_animations->element_id()); + element_to_animations_map_.erase(element_animations->element_id()); + DidDeactivateElementAnimations(element_animations); +} + +const AnimationHost::ElementToAnimationsMap& +AnimationHost::active_element_animations_for_testing() const { + return active_element_to_animations_map_; +} + +const AnimationHost::ElementToAnimationsMap& +AnimationHost::all_element_animations_for_testing() const { + return element_to_animations_map_; +} + +void AnimationHost::OnAnimationWaitingForDeletion() { + animation_waiting_for_deletion_ = true; } } // namespace cc diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h index e7f4ae684d6..976122702cb 100644 --- a/chromium/cc/animation/animation_host.h +++ b/chromium/cc/animation/animation_host.h @@ -5,13 +5,15 @@ #ifndef CC_ANIMATION_ANIMATION_HOST_H_ #define CC_ANIMATION_ANIMATION_HOST_H_ +#include <memory> #include <unordered_map> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/animation/animation.h" +#include "cc/animation/scroll_offset_animations_impl.h" #include "cc/base/cc_export.h" #include "cc/trees/mutator_host_client.h" #include "ui/gfx/geometry/box_f.h" @@ -25,10 +27,8 @@ namespace cc { class AnimationEvents; class AnimationPlayer; -class AnimationRegistrar; class AnimationTimeline; class ElementAnimations; -class LayerAnimationController; class LayerTreeHost; enum class ThreadInstance { MAIN, IMPL }; @@ -41,12 +41,13 @@ enum class ThreadInstance { MAIN, IMPL }; // (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(); + using ElementToAnimationsMap = + std::unordered_map<ElementId, scoped_refptr<ElementAnimations>>; + + static std::unique_ptr<AnimationHost> Create(ThreadInstance thread_instance); + ~AnimationHost(); void AddAnimationTimeline(scoped_refptr<AnimationTimeline> timeline); void RemoveAnimationTimeline(scoped_refptr<AnimationTimeline> timeline); @@ -54,16 +55,15 @@ class CC_EXPORT AnimationHost { 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); + void RegisterElement(ElementId element_id, ElementListType list_type); + void UnregisterElement(ElementId element_id, ElementListType list_type); - ElementAnimations* GetElementAnimationsForLayerId(int layer_id) const; + void RegisterPlayerForElement(ElementId element_id, AnimationPlayer* player); + void UnregisterPlayerForElement(ElementId element_id, + AnimationPlayer* player); - // TODO(loyso): Get rid of LayerAnimationController. - LayerAnimationController* GetControllerForLayerId(int layer_id) const; + scoped_refptr<ElementAnimations> GetElementAnimationsForElementId( + ElementId element_id) const; // Parent LayerTreeHost or LayerTreeHostImpl. MutatorHostClient* mutator_host_client() { return mutator_host_client_; } @@ -77,10 +77,6 @@ class CC_EXPORT AnimationHost { 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; @@ -90,67 +86,87 @@ class CC_EXPORT AnimationHost { bool UpdateAnimationState(bool start_ready_animations, AnimationEvents* events); - scoped_ptr<AnimationEvents> CreateEvents(); - void SetAnimationEvents(scoped_ptr<AnimationEvents> events); + std::unique_ptr<AnimationEvents> CreateEvents(); + void SetAnimationEvents(std::unique_ptr<AnimationEvents> events); - bool ScrollOffsetAnimationWasInterrupted(int layer_id) const; + bool ScrollOffsetAnimationWasInterrupted(ElementId element_id) const; - bool IsAnimatingFilterProperty(int layer_id, LayerTreeType tree_type) const; - bool IsAnimatingOpacityProperty(int layer_id, LayerTreeType tree_type) const; - bool IsAnimatingTransformProperty(int layer_id, - LayerTreeType tree_type) const; + bool IsAnimatingFilterProperty(ElementId element_id, + ElementListType list_type) const; + bool IsAnimatingOpacityProperty(ElementId element_id, + ElementListType list_type) const; + bool IsAnimatingTransformProperty(ElementId element_id, + ElementListType list_type) const; - bool HasPotentiallyRunningFilterAnimation(int layer_id, - LayerTreeType tree_type) const; - bool HasPotentiallyRunningOpacityAnimation(int layer_id, - LayerTreeType tree_type) const; - bool HasPotentiallyRunningTransformAnimation(int layer_id, - LayerTreeType tree_type) const; + bool HasPotentiallyRunningFilterAnimation(ElementId element_id, + ElementListType list_type) const; + bool HasPotentiallyRunningOpacityAnimation(ElementId element_id, + ElementListType list_type) const; + bool HasPotentiallyRunningTransformAnimation(ElementId element_id, + ElementListType list_type) const; - bool HasAnyAnimationTargetingProperty(int layer_id, + bool HasAnyAnimationTargetingProperty(ElementId element_id, TargetProperty::Type property) const; - bool FilterIsAnimatingOnImplOnly(int layer_id) const; - bool OpacityIsAnimatingOnImplOnly(int layer_id) const; - bool ScrollOffsetIsAnimatingOnImplOnly(int layer_id) const; - bool TransformIsAnimatingOnImplOnly(int layer_id) const; + bool ScrollOffsetIsAnimatingOnImplOnly(ElementId element_id) const; - bool HasFilterAnimationThatInflatesBounds(int layer_id) const; - bool HasTransformAnimationThatInflatesBounds(int layer_id) const; - bool HasAnimationThatInflatesBounds(int layer_id) const; + bool HasFilterAnimationThatInflatesBounds(ElementId element_id) const; + bool HasTransformAnimationThatInflatesBounds(ElementId element_id) const; + bool HasAnimationThatInflatesBounds(ElementId element_id) const; - bool FilterAnimationBoundsForBox(int layer_id, + bool FilterAnimationBoundsForBox(ElementId element_id, const gfx::BoxF& box, gfx::BoxF* bounds) const; - bool TransformAnimationBoundsForBox(int layer_id, + bool TransformAnimationBoundsForBox(ElementId element_id, const gfx::BoxF& box, gfx::BoxF* bounds) const; - bool HasOnlyTranslationTransforms(int layer_id, - LayerTreeType tree_type) const; - bool AnimationsPreserveAxisAlignment(int layer_id) const; + bool HasOnlyTranslationTransforms(ElementId element_id, + ElementListType list_type) const; + bool AnimationsPreserveAxisAlignment(ElementId element_id) const; - bool MaximumTargetScale(int layer_id, - LayerTreeType tree_type, + bool MaximumTargetScale(ElementId element_id, + ElementListType list_type, float* max_scale) const; - bool AnimationStartScale(int layer_id, - LayerTreeType tree_type, + bool AnimationStartScale(ElementId element_id, + ElementListType list_type, float* start_scale) const; - bool HasAnyAnimation(int layer_id) const; - bool HasActiveAnimationForTesting(int layer_id) const; + bool HasAnyAnimation(ElementId element_id) const; + bool HasActiveAnimationForTesting(ElementId element_id) const; - void ImplOnlyScrollAnimationCreate(int layer_id, + void ImplOnlyScrollAnimationCreate(ElementId element_id, const gfx::ScrollOffset& target_offset, const gfx::ScrollOffset& current_offset); bool ImplOnlyScrollAnimationUpdateTarget( - int layer_id, + ElementId element_id, const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time); void ScrollAnimationAbort(bool needs_completion); + // Registers the given element animations as active. An active element + // animations is one that has a running animation that needs to be ticked. + void DidActivateElementAnimations(ElementAnimations* element_animations); + + // Unregisters the given element animations. When this happens, the + // element animations will no longer be ticked (since it's not active). + void DidDeactivateElementAnimations(ElementAnimations* element_animations); + + // Registers the given ElementAnimations as alive. + void RegisterElementAnimations(ElementAnimations* element_animations); + // Unregisters the given ElementAnimations as alive. + void UnregisterElementAnimations(ElementAnimations* element_animations); + + const ElementToAnimationsMap& active_element_animations_for_testing() const; + const ElementToAnimationsMap& all_element_animations_for_testing() const; + + bool animation_waiting_for_deletion() const { + return animation_waiting_for_deletion_; + } + void OnAnimationWaitingForDeletion(); + private: explicit AnimationHost(ThreadInstance thread_instance); @@ -160,26 +176,23 @@ class CC_EXPORT AnimationHost { void EraseTimeline(scoped_refptr<AnimationTimeline> timeline); - // TODO(loyso): For now AnimationPlayers share LayerAnimationController object - // if they are attached to the same element(layer). Note that Element can - // contain many Layers. - using LayerToElementAnimationsMap = - std::unordered_map<int, scoped_ptr<ElementAnimations>>; - LayerToElementAnimationsMap layer_to_element_animations_map_; + ElementToAnimationsMap element_to_animations_map_; + ElementToAnimationsMap active_element_to_animations_map_; // A list of all timelines which this host owns. using IdToTimelineMap = std::unordered_map<int, scoped_refptr<AnimationTimeline>>; IdToTimelineMap id_to_timeline_map_; - scoped_ptr<AnimationRegistrar> animation_registrar_; MutatorHostClient* mutator_host_client_; - class ScrollOffsetAnimations; - scoped_ptr<ScrollOffsetAnimations> scroll_offset_animations_; + std::unique_ptr<ScrollOffsetAnimationsImpl> scroll_offset_animations_impl_; const ThreadInstance thread_instance_; + bool supports_scroll_animations_; + bool animation_waiting_for_deletion_; + DISALLOW_COPY_AND_ASSIGN(AnimationHost); }; diff --git a/chromium/cc/animation/animation_host_perftest.cc b/chromium/cc/animation/animation_host_perftest.cc index bd183ed243d..32b999b69f5 100644 --- a/chromium/cc/animation/animation_host_perftest.cc +++ b/chromium/cc/animation/animation_host_perftest.cc @@ -4,7 +4,7 @@ #include "cc/animation/animation_host.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/animation/animation_id_provider.h" #include "cc/animation/animation_player.h" #include "cc/animation/animation_timeline.h" @@ -68,7 +68,7 @@ class AnimationHostPerfTest : public testing::Test { last_player_id = AnimationIdProvider::NextPlayerId(); timeline->AttachPlayer(player); - player->AttachLayer(layer->id()); + player->AttachElement(layer->id()); EXPECT_TRUE(player->element_animations()); } @@ -114,7 +114,7 @@ class AnimationHostPerfTest : public testing::Test { } protected: - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; scoped_refptr<Layer> root_layer_; LayerImpl* root_layer_impl_; diff --git a/chromium/cc/animation/animation_host_unittest.cc b/chromium/cc/animation/animation_host_unittest.cc index cf828f63f41..aa477bfeb70 100644 --- a/chromium/cc/animation/animation_host_unittest.cc +++ b/chromium/cc/animation/animation_host_unittest.cc @@ -24,8 +24,9 @@ class AnimationHostTest : public AnimationTimelinesTest { // animation_player_unittest.cc. TEST_F(AnimationHostTest, SyncTimelinesAddRemove) { - scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN)); - scoped_ptr<AnimationHost> host_impl( + std::unique_ptr<AnimationHost> host( + AnimationHost::Create(ThreadInstance::MAIN)); + std::unique_ptr<AnimationHost> host_impl( AnimationHost::Create(ThreadInstance::IMPL)); const int timeline_id = AnimationIdProvider::NextTimelineId(); @@ -56,8 +57,9 @@ TEST_F(AnimationHostTest, SyncTimelinesAddRemove) { } TEST_F(AnimationHostTest, ImplOnlyTimeline) { - scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN)); - scoped_ptr<AnimationHost> host_impl( + std::unique_ptr<AnimationHost> host( + AnimationHost::Create(ThreadInstance::MAIN)); + std::unique_ptr<AnimationHost> host_impl( AnimationHost::Create(ThreadInstance::IMPL)); const int timeline_id1 = AnimationIdProvider::NextTimelineId(); @@ -79,12 +81,12 @@ TEST_F(AnimationHostTest, ImplOnlyTimeline) { } TEST_F(AnimationHostTest, ImplOnlyScrollAnimationUpdateTargetIfDetached) { - client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE); - client_impl_.RegisterLayer(layer_id_, LayerTreeType::PENDING); + client_.RegisterElement(element_id_, ElementListType::ACTIVE); + client_impl_.RegisterElement(element_id_, ElementListType::PENDING); gfx::ScrollOffset target_offset(0., 2.); gfx::ScrollOffset current_offset(0., 1.); - host_impl_->ImplOnlyScrollAnimationCreate(layer_id_, target_offset, + host_impl_->ImplOnlyScrollAnimationCreate(element_id_, target_offset, current_offset); gfx::Vector2dF scroll_delta(0, 0.5); @@ -94,14 +96,14 @@ TEST_F(AnimationHostTest, ImplOnlyScrollAnimationUpdateTargetIfDetached) { time += base::TimeDelta::FromSecondsD(0.1); EXPECT_TRUE(host_impl_->ImplOnlyScrollAnimationUpdateTarget( - layer_id_, scroll_delta, max_scroll_offset, time)); + element_id_, scroll_delta, max_scroll_offset, time)); // Detach all players from layers and timelines. host_impl_->ClearTimelines(); time += base::TimeDelta::FromSecondsD(0.1); EXPECT_FALSE(host_impl_->ImplOnlyScrollAnimationUpdateTarget( - layer_id_, scroll_delta, max_scroll_offset, time)); + element_id_, scroll_delta, max_scroll_offset, time)); } } // namespace diff --git a/chromium/cc/animation/animation_player.cc b/chromium/cc/animation/animation_player.cc index 77a7c21ec04..f77bdd796bf 100644 --- a/chromium/cc/animation/animation_player.cc +++ b/chromium/cc/animation/animation_player.cc @@ -4,11 +4,12 @@ #include "cc/animation/animation_player.h" +#include <algorithm> + #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 { @@ -20,9 +21,9 @@ AnimationPlayer::AnimationPlayer(int id) : animation_host_(), animation_timeline_(), element_animations_(), - layer_animation_delegate_(), + animation_delegate_(), id_(id), - layer_id_(0) { + element_id_(0) { DCHECK(id_); } @@ -46,67 +47,66 @@ void AnimationPlayer::SetAnimationTimeline(AnimationTimeline* timeline) { // We need to unregister player to manage ElementAnimations and observers // properly. - if (layer_id_ && element_animations_) + if (element_id_ && element_animations_) UnregisterPlayer(); animation_timeline_ = timeline; // Register player only if layer AND host attached. - if (layer_id_ && animation_host_) + if (element_id_ && animation_host_) RegisterPlayer(); } -void AnimationPlayer::AttachLayer(int layer_id) { - DCHECK_EQ(layer_id_, 0); - DCHECK(layer_id); +void AnimationPlayer::AttachElement(ElementId element_id) { + DCHECK_EQ(element_id_, 0); + DCHECK(element_id); - layer_id_ = layer_id; + element_id_ = element_id; // Register player only if layer AND host attached. if (animation_host_) RegisterPlayer(); } -void AnimationPlayer::DetachLayer() { - DCHECK(layer_id_); +void AnimationPlayer::DetachElement() { + DCHECK(element_id_); if (animation_host_) UnregisterPlayer(); - layer_id_ = 0; + element_id_ = 0; } void AnimationPlayer::RegisterPlayer() { - DCHECK(layer_id_); + DCHECK(element_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. + // Create ElementAnimations or re-use existing. + animation_host_->RegisterPlayerForElement(element_id_, this); + // Get local reference to shared ElementAnimations. BindElementAnimations(); } void AnimationPlayer::UnregisterPlayer() { - DCHECK(layer_id_); + DCHECK(element_id_); DCHECK(animation_host_); DCHECK(element_animations_); UnbindElementAnimations(); - // Destroy LAC or release it if it's still needed. - animation_host_->UnregisterPlayerForLayer(layer_id_, this); + // Destroy ElementAnimations or release it if it's still needed. + animation_host_->UnregisterPlayerForElement(element_id_, this); } void AnimationPlayer::BindElementAnimations() { DCHECK(!element_animations_); element_animations_ = - animation_host_->GetElementAnimationsForLayerId(layer_id_); + animation_host_->GetElementAnimationsForElementId(element_id_); DCHECK(element_animations_); - // Pass all accumulated animations to LAC. + // Pass all accumulated animations to ElementAnimations. for (auto& animation : animations_) { - element_animations_->layer_animation_controller()->AddAnimation( - std::move(animation)); + element_animations_->AddAnimation(std::move(animation)); } if (!animations_.empty()) SetNeedsCommit(); @@ -118,13 +118,12 @@ void AnimationPlayer::UnbindElementAnimations() { DCHECK(animations_.empty()); } -void AnimationPlayer::AddAnimation(scoped_ptr<Animation> animation) { +void AnimationPlayer::AddAnimation(std::unique_ptr<Animation> animation) { DCHECK(animation->target_property() != TargetProperty::SCROLL_OFFSET || (animation_host_ && animation_host_->SupportsScrollAnimations())); if (element_animations_) { - element_animations_->layer_animation_controller()->AddAnimation( - std::move(animation)); + element_animations_->AddAnimation(std::move(animation)); SetNeedsCommit(); } else { animations_.push_back(std::move(animation)); @@ -133,43 +132,40 @@ void AnimationPlayer::AddAnimation(scoped_ptr<Animation> animation) { void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) { DCHECK(element_animations_); - element_animations_->layer_animation_controller()->PauseAnimation( + element_animations_->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); + element_animations_->RemoveAnimation(animation_id); SetNeedsCommit(); } else { - auto animations_to_remove = - std::remove_if(animations_.begin(), animations_.end(), - [animation_id](const scoped_ptr<Animation>& animation) { - return animation->id() == animation_id; - }); + auto animations_to_remove = std::remove_if( + animations_.begin(), animations_.end(), + [animation_id](const std::unique_ptr<Animation>& animation) { + return animation->id() == animation_id; + }); animations_.erase(animations_to_remove, animations_.end()); } } void AnimationPlayer::AbortAnimation(int animation_id) { DCHECK(element_animations_); - element_animations_->layer_animation_controller()->AbortAnimation( - animation_id); + element_animations_->AbortAnimation(animation_id); SetNeedsCommit(); } void AnimationPlayer::AbortAnimations(TargetProperty::Type target_property, bool needs_completion) { if (element_animations_) { - element_animations_->layer_animation_controller()->AbortAnimations( - target_property, needs_completion); + element_animations_->AbortAnimations(target_property, needs_completion); SetNeedsCommit(); } else { auto animations_to_remove = std::remove_if( animations_.begin(), animations_.end(), - [target_property](const scoped_ptr<Animation>& animation) { + [target_property](const std::unique_ptr<Animation>& animation) { return animation->target_property() == target_property; }); animations_.erase(animations_to_remove, animations_.end()); @@ -177,11 +173,11 @@ void AnimationPlayer::AbortAnimations(TargetProperty::Type target_property, } void AnimationPlayer::PushPropertiesTo(AnimationPlayer* player_impl) { - if (layer_id_ != player_impl->layer_id()) { - if (player_impl->layer_id()) - player_impl->DetachLayer(); - if (layer_id_) - player_impl->AttachLayer(layer_id_); + if (element_id_ != player_impl->element_id()) { + if (player_impl->element_id()) + player_impl->DetachElement(); + if (element_id_) + player_impl->AttachElement(element_id_); } } @@ -189,37 +185,37 @@ void AnimationPlayer::NotifyAnimationStarted( base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) { - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationStarted(monotonic_time, - target_property, group); + if (animation_delegate_) + animation_delegate_->NotifyAnimationStarted(monotonic_time, target_property, + group); } void AnimationPlayer::NotifyAnimationFinished( base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) { - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationFinished(monotonic_time, - target_property, group); + if (animation_delegate_) + animation_delegate_->NotifyAnimationFinished(monotonic_time, + target_property, group); } void AnimationPlayer::NotifyAnimationAborted( base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) { - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationAborted(monotonic_time, - target_property, group); + if (animation_delegate_) + animation_delegate_->NotifyAnimationAborted(monotonic_time, target_property, + group); } void AnimationPlayer::NotifyAnimationTakeover( base::TimeTicks monotonic_time, TargetProperty::Type target_property, double animation_start_time, - scoped_ptr<AnimationCurve> curve) { - if (layer_animation_delegate_) { + std::unique_ptr<AnimationCurve> curve) { + if (animation_delegate_) { DCHECK(curve); - layer_animation_delegate_->NotifyAnimationTakeover( + animation_delegate_->NotifyAnimationTakeover( monotonic_time, target_property, animation_start_time, std::move(curve)); } diff --git a/chromium/cc/animation/animation_player.h b/chromium/cc/animation/animation_player.h index ddd303b8c9e..247b24c3d23 100644 --- a/chromium/cc/animation/animation_player.h +++ b/chromium/cc/animation/animation_player.h @@ -13,6 +13,7 @@ #include "base/time/time.h" #include "cc/animation/animation.h" #include "cc/animation/animation_curve.h" +#include "cc/animation/element_animations.h" #include "cc/base/cc_export.h" namespace cc { @@ -21,14 +22,11 @@ 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). +// they share common ElementAnimations so the +// ElementAnimations-to-Layer relationship is 1:1. // For now, the blink logic is responsible for handling of conflicting // same-property animations. // Each AnimationPlayer has its copy on the impl thread. @@ -40,7 +38,7 @@ class CC_EXPORT AnimationPlayer : public base::RefCounted<AnimationPlayer>, scoped_refptr<AnimationPlayer> CreateImplInstance() const; int id() const { return id_; } - int layer_id() const { return layer_id_; } + ElementId element_id() const { return element_id_; } // Parent AnimationHost. AnimationPlayer can be detached from // AnimationTimeline. @@ -56,17 +54,18 @@ class CC_EXPORT AnimationPlayer : public base::RefCounted<AnimationPlayer>, 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_; } + scoped_refptr<ElementAnimations> element_animations() const { + return element_animations_; + } - void set_layer_animation_delegate(AnimationDelegate* delegate) { - layer_animation_delegate_ = delegate; + void set_animation_delegate(AnimationDelegate* delegate) { + animation_delegate_ = delegate; } - void AttachLayer(int layer_id); - void DetachLayer(); + void AttachElement(ElementId element_id); + void DetachElement(); - void AddAnimation(scoped_ptr<Animation> animation); + void AddAnimation(std::unique_ptr<Animation> animation); void PauseAnimation(int animation_id, double time_offset); void RemoveAnimation(int animation_id); void AbortAnimation(int animation_id); @@ -88,9 +87,9 @@ class CC_EXPORT AnimationPlayer : public base::RefCounted<AnimationPlayer>, void NotifyAnimationTakeover(base::TimeTicks monotonic_time, TargetProperty::Type target_property, double animation_start_time, - scoped_ptr<AnimationCurve> curve); + std::unique_ptr<AnimationCurve> curve); - // Whether this player has animations waiting to get sent to LAC. + // Whether this player has animations waiting to get sent to ElementAnimations bool has_pending_animations_for_testing() const { return !animations_.empty(); } @@ -112,16 +111,16 @@ class CC_EXPORT AnimationPlayer : public base::RefCounted<AnimationPlayer>, // We accumulate added animations in animations_ container // if element_animations_ is a nullptr. It allows us to add/remove animations // to non-attached AnimationPlayers. - std::vector<scoped_ptr<Animation>> animations_; + std::vector<std::unique_ptr<Animation>> 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_; + scoped_refptr<ElementAnimations> element_animations_; + AnimationDelegate* animation_delegate_; int id_; - int layer_id_; + ElementId element_id_; DISALLOW_COPY_AND_ASSIGN(AnimationPlayer); }; diff --git a/chromium/cc/animation/animation_player_unittest.cc b/chromium/cc/animation/animation_player_unittest.cc index 6e165fd7466..14de5aadfea 100644 --- a/chromium/cc/animation/animation_player_unittest.cc +++ b/chromium/cc/animation/animation_player_unittest.cc @@ -7,7 +7,6 @@ #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" @@ -28,79 +27,79 @@ TEST_F(AnimationPlayerTest, AttachDetachLayerIfTimelineAttached) { host_->AddAnimationTimeline(timeline_); timeline_->AttachPlayer(player_); EXPECT_FALSE(player_->element_animations()); - EXPECT_FALSE(player_->layer_id()); + EXPECT_FALSE(player_->element_id()); host_->PushPropertiesTo(host_impl_); - EXPECT_FALSE(GetImplPlayerForLayerId(layer_id_)); + EXPECT_FALSE(GetImplPlayerForLayerId(element_id_)); GetImplTimelineAndPlayerByID(); EXPECT_FALSE(player_impl_->element_animations()); - EXPECT_FALSE(player_impl_->layer_id()); + EXPECT_FALSE(player_impl_->element_id()); - player_->AttachLayer(layer_id_); - EXPECT_EQ(player_, GetPlayerForLayerId(layer_id_)); + player_->AttachElement(element_id_); + EXPECT_EQ(player_, GetPlayerForLayerId(element_id_)); EXPECT_TRUE(player_->element_animations()); - EXPECT_EQ(player_->layer_id(), layer_id_); + EXPECT_EQ(player_->element_id(), element_id_); host_->PushPropertiesTo(host_impl_); - EXPECT_EQ(player_impl_, GetImplPlayerForLayerId(layer_id_)); + EXPECT_EQ(player_impl_, GetImplPlayerForLayerId(element_id_)); EXPECT_TRUE(player_impl_->element_animations()); - EXPECT_EQ(player_impl_->layer_id(), layer_id_); + EXPECT_EQ(player_impl_->element_id(), element_id_); - player_->DetachLayer(); - EXPECT_FALSE(GetPlayerForLayerId(layer_id_)); + player_->DetachElement(); + EXPECT_FALSE(GetPlayerForLayerId(element_id_)); EXPECT_FALSE(player_->element_animations()); - EXPECT_FALSE(player_->layer_id()); + EXPECT_FALSE(player_->element_id()); host_->PushPropertiesTo(host_impl_); - EXPECT_FALSE(GetImplPlayerForLayerId(layer_id_)); + EXPECT_FALSE(GetImplPlayerForLayerId(element_id_)); EXPECT_FALSE(player_impl_->element_animations()); - EXPECT_FALSE(player_impl_->layer_id()); + EXPECT_FALSE(player_impl_->element_id()); timeline_->DetachPlayer(player_); EXPECT_FALSE(player_->animation_timeline()); EXPECT_FALSE(player_->element_animations()); - EXPECT_FALSE(player_->layer_id()); + EXPECT_FALSE(player_->element_id()); } TEST_F(AnimationPlayerTest, AttachDetachTimelineIfLayerAttached) { host_->AddAnimationTimeline(timeline_); EXPECT_FALSE(player_->element_animations()); - EXPECT_FALSE(player_->layer_id()); + EXPECT_FALSE(player_->element_id()); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_id_); EXPECT_FALSE(player_->animation_timeline()); - EXPECT_FALSE(GetPlayerForLayerId(layer_id_)); + EXPECT_FALSE(GetPlayerForLayerId(element_id_)); EXPECT_FALSE(player_->element_animations()); - EXPECT_EQ(player_->layer_id(), layer_id_); + EXPECT_EQ(player_->element_id(), element_id_); timeline_->AttachPlayer(player_); EXPECT_EQ(timeline_, player_->animation_timeline()); - EXPECT_EQ(player_, GetPlayerForLayerId(layer_id_)); + EXPECT_EQ(player_, GetPlayerForLayerId(element_id_)); EXPECT_TRUE(player_->element_animations()); - EXPECT_EQ(player_->layer_id(), layer_id_); + EXPECT_EQ(player_->element_id(), element_id_); // Removing player from timeline detaches layer. timeline_->DetachPlayer(player_); EXPECT_FALSE(player_->animation_timeline()); - EXPECT_FALSE(GetPlayerForLayerId(layer_id_)); + EXPECT_FALSE(GetPlayerForLayerId(element_id_)); EXPECT_FALSE(player_->element_animations()); - EXPECT_FALSE(player_->layer_id()); + EXPECT_FALSE(player_->element_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); + client_.RegisterElement(element_id_, ElementListType::ACTIVE); + client_impl_.RegisterElement(element_id_, ElementListType::PENDING); + client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE); host_->AddAnimationTimeline(timeline_); timeline_->AttachPlayer(player_); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_id_); const float start_opacity = .7f; const float end_opacity = .3f; @@ -122,21 +121,21 @@ TEST_F(AnimationPlayerTest, PropertiesMutate) { host_->PushPropertiesTo(host_impl_); - EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE, TargetProperty::OPACITY)); - EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE, TargetProperty::TRANSFORM)); - EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE, TargetProperty::FILTER)); - EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, - TargetProperty::OPACITY)); - EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, - TargetProperty::TRANSFORM)); - EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, - TargetProperty::FILTER)); + EXPECT_FALSE(client_impl_.IsPropertyMutated( + element_id_, ElementListType::ACTIVE, TargetProperty::OPACITY)); + EXPECT_FALSE(client_impl_.IsPropertyMutated( + element_id_, ElementListType::ACTIVE, TargetProperty::TRANSFORM)); + EXPECT_FALSE(client_impl_.IsPropertyMutated( + element_id_, ElementListType::ACTIVE, TargetProperty::FILTER)); - host_impl_->animation_registrar()->ActivateAnimations(); + host_impl_->ActivateAnimations(); base::TimeTicks time; time += base::TimeDelta::FromSecondsD(0.1); @@ -145,35 +144,35 @@ TEST_F(AnimationPlayerTest, PropertiesMutate) { time += base::TimeDelta::FromSecondsD(duration); AnimateLayersTransferEvents(time, 3u); - client_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE, end_opacity); - client_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + client_.ExpectTransformPropertyMutated(element_id_, ElementListType::ACTIVE, transform_x, transform_y); - client_.ExpectFilterPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + client_.ExpectFilterPropertyMutated(element_id_, ElementListType::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, + client_impl_.ExpectOpacityPropertyMutated( + element_id_, ElementListType::ACTIVE, end_opacity); + client_impl_.ExpectTransformPropertyMutated( + element_id_, ElementListType::ACTIVE, transform_x, transform_y); + client_impl_.ExpectFilterPropertyMutated(element_id_, ElementListType::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); + client_impl_.ExpectOpacityPropertyMutated( + element_id_, ElementListType::PENDING, end_opacity); + client_impl_.ExpectTransformPropertyMutated( + element_id_, ElementListType::PENDING, transform_x, transform_y); + client_impl_.ExpectFilterPropertyMutated( + element_id_, ElementListType::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); + client_.RegisterElement(element_id_, ElementListType::ACTIVE); + client_impl_.RegisterElement(element_id_, ElementListType::PENDING); + client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE); scoped_refptr<AnimationPlayer> player1 = AnimationPlayer::Create(AnimationIdProvider::NextPlayerId()); @@ -184,12 +183,12 @@ TEST_F(AnimationPlayerTest, AttachTwoPlayersToOneLayer) { timeline_->AttachPlayer(player1); timeline_->AttachPlayer(player2); - player1->set_layer_animation_delegate(&delegate1); - player2->set_layer_animation_delegate(&delegate2); + player1->set_animation_delegate(&delegate1); + player2->set_animation_delegate(&delegate2); // Attach players to the same layer. - player1->AttachLayer(layer_id_); - player2->AttachLayer(layer_id_); + player1->AttachElement(element_id_); + player2->AttachElement(element_id_); const float start_opacity = .7f; const float end_opacity = .3f; @@ -205,50 +204,50 @@ TEST_F(AnimationPlayerTest, AttachTwoPlayersToOneLayer) { transform_y); host_->PushPropertiesTo(host_impl_); - host_impl_->animation_registrar()->ActivateAnimations(); + host_impl_->ActivateAnimations(); - EXPECT_FALSE(delegate1.started_); - EXPECT_FALSE(delegate1.finished_); + EXPECT_FALSE(delegate1.started()); + EXPECT_FALSE(delegate1.finished()); - EXPECT_FALSE(delegate2.started_); - EXPECT_FALSE(delegate2.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(delegate1.started()); + EXPECT_FALSE(delegate1.finished()); - EXPECT_TRUE(delegate2.started_); - EXPECT_FALSE(delegate2.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_); + EXPECT_TRUE(delegate1.finished()); + EXPECT_TRUE(delegate2.finished()); - client_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE, end_opacity); - client_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + client_.ExpectTransformPropertyMutated(element_id_, ElementListType::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( + element_id_, ElementListType::ACTIVE, end_opacity); + client_impl_.ExpectTransformPropertyMutated( + element_id_, ElementListType::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); + client_impl_.ExpectOpacityPropertyMutated( + element_id_, ElementListType::PENDING, end_opacity); + client_impl_.ExpectTransformPropertyMutated( + element_id_, ElementListType::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); + client_.RegisterElement(element_id_, ElementListType::ACTIVE); + client_impl_.RegisterElement(element_id_, ElementListType::PENDING); + client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE); const double duration = 1.; const float start_opacity = .7f; @@ -265,29 +264,27 @@ TEST_F(AnimationPlayerTest, AddRemoveAnimationToNonAttachedPlayer) { EXPECT_FALSE(player_->element_animations()); player_->RemoveAnimation(filter_id); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_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, + EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE, TargetProperty::OPACITY)); - EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, - TargetProperty::OPACITY)); + EXPECT_FALSE(client_impl_.IsPropertyMutated( + element_id_, ElementListType::ACTIVE, TargetProperty::OPACITY)); - EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE, TargetProperty::FILTER)); - EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, - TargetProperty::FILTER)); + EXPECT_FALSE(client_impl_.IsPropertyMutated( + element_id_, ElementListType::ACTIVE, TargetProperty::FILTER)); - host_impl_->animation_registrar()->ActivateAnimations(); + host_impl_->ActivateAnimations(); base::TimeTicks time; time += base::TimeDelta::FromSecondsD(0.1); @@ -296,24 +293,24 @@ TEST_F(AnimationPlayerTest, AddRemoveAnimationToNonAttachedPlayer) { time += base::TimeDelta::FromSecondsD(duration); AnimateLayersTransferEvents(time, 1u); - client_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE, end_opacity); - client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE, - end_opacity); - client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::PENDING, - end_opacity); + client_impl_.ExpectOpacityPropertyMutated( + element_id_, ElementListType::ACTIVE, end_opacity); + client_impl_.ExpectOpacityPropertyMutated( + element_id_, ElementListType::PENDING, end_opacity); - EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, + EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE, TargetProperty::FILTER)); - EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE, - TargetProperty::FILTER)); + EXPECT_FALSE(client_impl_.IsPropertyMutated( + element_id_, ElementListType::ACTIVE, TargetProperty::FILTER)); } TEST_F(AnimationPlayerTest, AddRemoveAnimationCausesSetNeedsCommit) { - client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE); + client_.RegisterElement(element_id_, ElementListType::ACTIVE); host_->AddAnimationTimeline(timeline_); timeline_->AttachPlayer(player_); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_id_); EXPECT_FALSE(client_.mutators_need_commit()); @@ -337,33 +334,33 @@ TEST_F(AnimationPlayerTest, AddRemoveAnimationCausesSetNeedsCommit) { TEST_F(AnimationPlayerTest, SwitchToLayer) { host_->AddAnimationTimeline(timeline_); timeline_->AttachPlayer(player_); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_id_); host_->PushPropertiesTo(host_impl_); GetImplTimelineAndPlayerByID(); - EXPECT_EQ(player_, GetPlayerForLayerId(layer_id_)); + EXPECT_EQ(player_, GetPlayerForLayerId(element_id_)); EXPECT_TRUE(player_->element_animations()); - EXPECT_EQ(player_->layer_id(), layer_id_); + EXPECT_EQ(player_->element_id(), element_id_); - EXPECT_EQ(player_impl_, GetImplPlayerForLayerId(layer_id_)); + EXPECT_EQ(player_impl_, GetImplPlayerForLayerId(element_id_)); EXPECT_TRUE(player_impl_->element_animations()); - EXPECT_EQ(player_impl_->layer_id(), layer_id_); + EXPECT_EQ(player_impl_->element_id(), element_id_); const int new_layer_id = NextTestLayerId(); - player_->DetachLayer(); - player_->AttachLayer(new_layer_id); + player_->DetachElement(); + player_->AttachElement(new_layer_id); EXPECT_EQ(player_, GetPlayerForLayerId(new_layer_id)); EXPECT_TRUE(player_->element_animations()); - EXPECT_EQ(player_->layer_id(), new_layer_id); + EXPECT_EQ(player_->element_id(), new_layer_id); host_->PushPropertiesTo(host_impl_); EXPECT_EQ(player_impl_, GetImplPlayerForLayerId(new_layer_id)); EXPECT_TRUE(player_impl_->element_animations()); - EXPECT_EQ(player_impl_->layer_id(), new_layer_id); + EXPECT_EQ(player_impl_->element_id(), new_layer_id); } } // namespace diff --git a/chromium/cc/animation/animation_registrar.cc b/chromium/cc/animation/animation_registrar.cc deleted file mode 100644 index e498045b56d..00000000000 --- a/chromium/cc/animation/animation_registrar.cc +++ /dev/null @@ -1,144 +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/animation/animation_registrar.h" - -#include <stddef.h> - -#include "base/trace_event/trace_event.h" -#include "base/trace_event/trace_event_argument.h" -#include "cc/animation/animation_events.h" -#include "cc/animation/layer_animation_controller.h" - -namespace cc { - -AnimationRegistrar::AnimationRegistrar() : supports_scroll_animations_(false) { -} - -AnimationRegistrar::~AnimationRegistrar() { - AnimationControllerMap copy = all_animation_controllers_; - for (AnimationControllerMap::iterator iter = copy.begin(); - iter != copy.end(); - ++iter) - (*iter).second->SetAnimationRegistrar(nullptr); -} - -scoped_refptr<LayerAnimationController> -AnimationRegistrar::GetAnimationControllerForId(int id) { - scoped_refptr<LayerAnimationController> to_return; - if (!ContainsKey(all_animation_controllers_, id)) { - to_return = LayerAnimationController::Create(id); - to_return->SetAnimationRegistrar(this); - all_animation_controllers_[id] = to_return.get(); - } else { - to_return = all_animation_controllers_[id]; - } - return to_return; -} - -void AnimationRegistrar::DidActivateAnimationController( - LayerAnimationController* controller) { - active_animation_controllers_[controller->id()] = controller; -} - -void AnimationRegistrar::DidDeactivateAnimationController( - LayerAnimationController* controller) { - if (ContainsKey(active_animation_controllers_, controller->id())) - active_animation_controllers_.erase(controller->id()); -} - -void AnimationRegistrar::RegisterAnimationController( - LayerAnimationController* controller) { - all_animation_controllers_[controller->id()] = controller; -} - -void AnimationRegistrar::UnregisterAnimationController( - LayerAnimationController* controller) { - if (ContainsKey(all_animation_controllers_, controller->id())) - all_animation_controllers_.erase(controller->id()); - DidDeactivateAnimationController(controller); -} - -bool AnimationRegistrar::ActivateAnimations() { - if (!needs_animate_layers()) - return false; - - TRACE_EVENT0("cc", "AnimationRegistrar::ActivateAnimations"); - AnimationControllerMap active_controllers_copy = - active_animation_controllers_; - for (auto& it : active_controllers_copy) - it.second->ActivateAnimations(); - - return true; -} - -bool AnimationRegistrar::AnimateLayers(base::TimeTicks monotonic_time) { - if (!needs_animate_layers()) - return false; - - TRACE_EVENT0("cc", "AnimationRegistrar::AnimateLayers"); - AnimationControllerMap controllers_copy = active_animation_controllers_; - for (auto& it : controllers_copy) - it.second->Animate(monotonic_time); - - return true; -} - -bool AnimationRegistrar::UpdateAnimationState(bool start_ready_animations, - AnimationEvents* events) { - if (!needs_animate_layers()) - return false; - - TRACE_EVENT0("cc", "AnimationRegistrar::UpdateAnimationState"); - AnimationControllerMap active_controllers_copy = - active_animation_controllers_; - for (auto& it : active_controllers_copy) - it.second->UpdateState(start_ready_animations, events); - - return true; -} - -scoped_ptr<AnimationEvents> AnimationRegistrar::CreateEvents() { - return make_scoped_ptr(new AnimationEvents()); -} - -void AnimationRegistrar::SetAnimationEvents( - scoped_ptr<AnimationEvents> events) { - for (size_t event_index = 0; event_index < events->events_.size(); - ++event_index) { - int event_layer_id = events->events_[event_index].layer_id; - - // Use the map of all controllers, not just active ones, since non-active - // controllers may still receive events for impl-only animations. - const AnimationRegistrar::AnimationControllerMap& animation_controllers = - all_animation_controllers_; - auto iter = animation_controllers.find(event_layer_id); - if (iter != animation_controllers.end()) { - switch (events->events_[event_index].type) { - case AnimationEvent::STARTED: - (*iter).second->NotifyAnimationStarted(events->events_[event_index]); - break; - - case AnimationEvent::FINISHED: - (*iter).second->NotifyAnimationFinished(events->events_[event_index]); - break; - - case AnimationEvent::ABORTED: - (*iter).second->NotifyAnimationAborted(events->events_[event_index]); - break; - - case AnimationEvent::PROPERTY_UPDATE: - (*iter).second->NotifyAnimationPropertyUpdate( - events->events_[event_index]); - break; - - case AnimationEvent::TAKEOVER: - (*iter).second->NotifyAnimationTakeover(events->events_[event_index]); - break; - } - } - } -} - -} // namespace cc diff --git a/chromium/cc/animation/animation_registrar.h b/chromium/cc/animation/animation_registrar.h deleted file mode 100644 index bc143307c34..00000000000 --- a/chromium/cc/animation/animation_registrar.h +++ /dev/null @@ -1,91 +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_ANIMATION_ANIMATION_REGISTRAR_H_ -#define CC_ANIMATION_ANIMATION_REGISTRAR_H_ - -#include <unordered_map> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/time/time.h" -#include "cc/base/cc_export.h" - -namespace cc { - -class AnimationEvents; -class LayerAnimationController; - -class CC_EXPORT AnimationRegistrar { - public: - using AnimationControllerMap = - std::unordered_map<int, LayerAnimationController*>; - - static scoped_ptr<AnimationRegistrar> Create() { - return make_scoped_ptr(new AnimationRegistrar()); - } - - virtual ~AnimationRegistrar(); - - // If an animation has been registered for the given id, return it. Otherwise - // creates a new one and returns a scoped_refptr to it. - scoped_refptr<LayerAnimationController> GetAnimationControllerForId(int id); - - // Registers the given animation controller as active. An active animation - // controller is one that has a running animation that needs to be ticked. - void DidActivateAnimationController(LayerAnimationController* controller); - - // Unregisters the given animation controller. When this happens, the - // animation controller will no longer be ticked (since it's not active). It - // is not an error to call this function with a deactivated controller. - void DidDeactivateAnimationController(LayerAnimationController* controller); - - // Registers the given controller as alive. - void RegisterAnimationController(LayerAnimationController* controller); - - // Unregisters the given controller as alive. - void UnregisterAnimationController(LayerAnimationController* controller); - - const AnimationControllerMap& active_animation_controllers_for_testing() - const { - return active_animation_controllers_; - } - - const AnimationControllerMap& all_animation_controllers_for_testing() const { - return all_animation_controllers_; - } - - void set_supports_scroll_animations(bool supports_scroll_animations) { - supports_scroll_animations_ = supports_scroll_animations; - } - - bool supports_scroll_animations() { return supports_scroll_animations_; } - - bool needs_animate_layers() const { - return !active_animation_controllers_.empty(); - } - - bool ActivateAnimations(); - bool AnimateLayers(base::TimeTicks monotonic_time); - bool UpdateAnimationState(bool start_ready_animations, - AnimationEvents* events); - - scoped_ptr<AnimationEvents> CreateEvents(); - void SetAnimationEvents(scoped_ptr<AnimationEvents> events); - - private: - AnimationRegistrar(); - - AnimationControllerMap active_animation_controllers_; - AnimationControllerMap all_animation_controllers_; - - bool supports_scroll_animations_; - - DISALLOW_COPY_AND_ASSIGN(AnimationRegistrar); -}; - -} // namespace cc - -#endif // CC_ANIMATION_ANIMATION_REGISTRAR_H_ diff --git a/chromium/cc/animation/animation_timeline.cc b/chromium/cc/animation/animation_timeline.cc index 42591d01dcc..5b2b10653f0 100644 --- a/chromium/cc/animation/animation_timeline.cc +++ b/chromium/cc/animation/animation_timeline.cc @@ -94,7 +94,7 @@ void AnimationTimeline::RemoveDetachedPlayersFromImplThread( void AnimationTimeline::ErasePlayer(scoped_refptr<AnimationPlayer> player) { if (player->element_animations()) - player->DetachLayer(); + player->DetachElement(); player->SetAnimationTimeline(nullptr); player->SetAnimationHost(nullptr); } diff --git a/chromium/cc/animation/animation_timeline.h b/chromium/cc/animation/animation_timeline.h index ca618ca36d7..48dd05942d6 100644 --- a/chromium/cc/animation/animation_timeline.h +++ b/chromium/cc/animation/animation_timeline.h @@ -5,11 +5,11 @@ #ifndef CC_ANIMATION_ANIMATION_TIMELINE_H_ #define CC_ANIMATION_ANIMATION_TIMELINE_H_ +#include <memory> #include <unordered_map> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" namespace cc { diff --git a/chromium/cc/animation/animation_timeline_unittest.cc b/chromium/cc/animation/animation_timeline_unittest.cc index 3b0bc5ab730..c3800240e7b 100644 --- a/chromium/cc/animation/animation_timeline_unittest.cc +++ b/chromium/cc/animation/animation_timeline_unittest.cc @@ -15,8 +15,9 @@ namespace cc { namespace { TEST(AnimationTimelineTest, SyncPlayersAttachDetach) { - scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN)); - scoped_ptr<AnimationHost> host_impl( + std::unique_ptr<AnimationHost> host( + AnimationHost::Create(ThreadInstance::MAIN)); + std::unique_ptr<AnimationHost> host_impl( AnimationHost::Create(ThreadInstance::IMPL)); const int timeline_id = AnimationIdProvider::NextTimelineId(); @@ -60,8 +61,9 @@ TEST(AnimationTimelineTest, SyncPlayersAttachDetach) { } TEST(AnimationTimelineTest, ClearPlayers) { - scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN)); - scoped_ptr<AnimationHost> host_impl( + std::unique_ptr<AnimationHost> host( + AnimationHost::Create(ThreadInstance::MAIN)); + std::unique_ptr<AnimationHost> host_impl( AnimationHost::Create(ThreadInstance::IMPL)); const int timeline_id = AnimationIdProvider::NextTimelineId(); diff --git a/chromium/cc/animation/animation_unittest.cc b/chromium/cc/animation/animation_unittest.cc index 3bb984a0aec..edf0f7939ee 100644 --- a/chromium/cc/animation/animation_unittest.cc +++ b/chromium/cc/animation/animation_unittest.cc @@ -4,6 +4,7 @@ #include "cc/animation/animation.h" +#include "base/memory/ptr_util.h" #include "cc/test/animation_test_common.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,27 +19,27 @@ static base::TimeTicks TicksFromSecondsF(double seconds) { base::Time::kMicrosecondsPerSecond); } -scoped_ptr<Animation> CreateAnimation(double iterations, - double duration, - double playback_rate) { - scoped_ptr<Animation> to_return( - Animation::Create(make_scoped_ptr(new FakeFloatAnimationCurve(duration)), +std::unique_ptr<Animation> CreateAnimation(double iterations, + double duration, + double playback_rate) { + std::unique_ptr<Animation> to_return( + Animation::Create(base::WrapUnique(new FakeFloatAnimationCurve(duration)), 0, 1, TargetProperty::OPACITY)); to_return->set_iterations(iterations); to_return->set_playback_rate(playback_rate); return to_return; } -scoped_ptr<Animation> CreateAnimation(double iterations, double duration) { +std::unique_ptr<Animation> CreateAnimation(double iterations, double duration) { return CreateAnimation(iterations, duration, 1); } -scoped_ptr<Animation> CreateAnimation(double iterations) { +std::unique_ptr<Animation> CreateAnimation(double iterations) { return CreateAnimation(iterations, 1, 1); } TEST(AnimationTest, TrimTimeZeroIterations) { - scoped_ptr<Animation> anim(CreateAnimation(0)); + std::unique_ptr<Animation> anim(CreateAnimation(0)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -48,7 +49,7 @@ TEST(AnimationTest, TrimTimeZeroIterations) { } TEST(AnimationTest, TrimTimeOneIteration) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -60,7 +61,7 @@ TEST(AnimationTest, TrimTimeOneIteration) { } TEST(AnimationTest, TrimTimeOneHalfIteration) { - scoped_ptr<Animation> anim(CreateAnimation(1.5)); + std::unique_ptr<Animation> anim(CreateAnimation(1.5)); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) @@ -78,7 +79,7 @@ TEST(AnimationTest, TrimTimeOneHalfIteration) { } TEST(AnimationTest, TrimTimeInfiniteIterations) { - scoped_ptr<Animation> anim(CreateAnimation(-1)); + std::unique_ptr<Animation> anim(CreateAnimation(-1)); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5)) @@ -90,8 +91,8 @@ TEST(AnimationTest, TrimTimeInfiniteIterations) { } TEST(AnimationTest, TrimTimeReverse) { - scoped_ptr<Animation> anim(CreateAnimation(-1)); - anim->set_direction(Animation::DIRECTION_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(-1)); + anim->set_direction(Animation::Direction::REVERSE); EXPECT_EQ( 1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0)).InSecondsF()); EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -107,8 +108,8 @@ TEST(AnimationTest, TrimTimeReverse) { } TEST(AnimationTest, TrimTimeAlternateInfiniteIterations) { - scoped_ptr<Animation> anim(CreateAnimation(-1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(-1)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -124,8 +125,8 @@ TEST(AnimationTest, TrimTimeAlternateInfiniteIterations) { } TEST(AnimationTest, TrimTimeAlternateOneIteration) { - scoped_ptr<Animation> anim(CreateAnimation(1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(1)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -141,8 +142,8 @@ TEST(AnimationTest, TrimTimeAlternateOneIteration) { } TEST(AnimationTest, TrimTimeAlternateTwoIterations) { - scoped_ptr<Animation> anim(CreateAnimation(2)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(2)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -164,8 +165,8 @@ TEST(AnimationTest, TrimTimeAlternateTwoIterations) { } TEST(AnimationTest, TrimTimeAlternateTwoHalfIterations) { - scoped_ptr<Animation> anim(CreateAnimation(2.5)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(2.5)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -191,8 +192,8 @@ TEST(AnimationTest, TrimTimeAlternateTwoHalfIterations) { } TEST(AnimationTest, TrimTimeAlternateReverseInfiniteIterations) { - scoped_ptr<Animation> anim(CreateAnimation(-1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(-1)); + anim->set_direction(Animation::Direction::ALTERNATE_REVERSE); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -208,8 +209,8 @@ TEST(AnimationTest, TrimTimeAlternateReverseInfiniteIterations) { } TEST(AnimationTest, TrimTimeAlternateReverseOneIteration) { - scoped_ptr<Animation> anim(CreateAnimation(1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(1)); + anim->set_direction(Animation::Direction::ALTERNATE_REVERSE); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -225,8 +226,8 @@ TEST(AnimationTest, TrimTimeAlternateReverseOneIteration) { } TEST(AnimationTest, TrimTimeAlternateReverseTwoIterations) { - scoped_ptr<Animation> anim(CreateAnimation(2)); - anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(2)); + anim->set_direction(Animation::Direction::ALTERNATE_REVERSE); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -248,7 +249,7 @@ TEST(AnimationTest, TrimTimeAlternateReverseTwoIterations) { } TEST(AnimationTest, TrimTimeStartTime) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_start_time(TicksFromSecondsF(4)); EXPECT_EQ( 0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF()); @@ -263,9 +264,9 @@ TEST(AnimationTest, TrimTimeStartTime) { } TEST(AnimationTest, TrimTimeStartTimeReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_start_time(TicksFromSecondsF(4)); - anim->set_direction(Animation::DIRECTION_REVERSE); + anim->set_direction(Animation::Direction::REVERSE); EXPECT_EQ( 0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF()); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(4.0)) @@ -279,7 +280,7 @@ TEST(AnimationTest, TrimTimeStartTimeReverse) { } TEST(AnimationTest, TrimTimeTimeOffset) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(TimeDelta::FromMilliseconds(4000)); anim->set_start_time(TicksFromSecondsF(4)); EXPECT_EQ( @@ -293,10 +294,10 @@ TEST(AnimationTest, TrimTimeTimeOffset) { } TEST(AnimationTest, TrimTimeTimeOffsetReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(TimeDelta::FromMilliseconds(4000)); anim->set_start_time(TicksFromSecondsF(4)); - anim->set_direction(Animation::DIRECTION_REVERSE); + anim->set_direction(Animation::Direction::REVERSE); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5)) @@ -308,7 +309,7 @@ TEST(AnimationTest, TrimTimeTimeOffsetReverse) { } TEST(AnimationTest, TrimTimeNegativeTimeOffset) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(TimeDelta::FromMilliseconds(-4000)); EXPECT_EQ( @@ -322,9 +323,9 @@ TEST(AnimationTest, TrimTimeNegativeTimeOffset) { } TEST(AnimationTest, TrimTimeNegativeTimeOffsetReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(TimeDelta::FromMilliseconds(-4000)); - anim->set_direction(Animation::DIRECTION_REVERSE); + anim->set_direction(Animation::Direction::REVERSE); EXPECT_EQ( 0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF()); @@ -337,7 +338,7 @@ TEST(AnimationTest, TrimTimeNegativeTimeOffsetReverse) { } TEST(AnimationTest, TrimTimePauseResume) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_EQ( 0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF()); @@ -354,8 +355,8 @@ TEST(AnimationTest, TrimTimePauseResume) { } TEST(AnimationTest, TrimTimePauseResumeReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1)); - anim->set_direction(Animation::DIRECTION_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(1)); + anim->set_direction(Animation::Direction::REVERSE); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); @@ -372,7 +373,7 @@ TEST(AnimationTest, TrimTimePauseResumeReverse) { } TEST(AnimationTest, TrimTimeSuspendResume) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_EQ( 0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF()); @@ -389,8 +390,8 @@ TEST(AnimationTest, TrimTimeSuspendResume) { } TEST(AnimationTest, TrimTimeSuspendResumeReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1)); - anim->set_direction(Animation::DIRECTION_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(1)); + anim->set_direction(Animation::Direction::REVERSE); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); @@ -407,7 +408,7 @@ TEST(AnimationTest, TrimTimeSuspendResumeReverse) { } TEST(AnimationTest, TrimTimeZeroDuration) { - scoped_ptr<Animation> anim(CreateAnimation(0, 0)); + std::unique_ptr<Animation> anim(CreateAnimation(0, 0)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); @@ -418,7 +419,7 @@ TEST(AnimationTest, TrimTimeZeroDuration) { } TEST(AnimationTest, TrimTimeStarting) { - scoped_ptr<Animation> anim(CreateAnimation(1, 5.0)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 5.0)); anim->SetRunState(Animation::STARTING, TicksFromSecondsF(0.0)); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); @@ -445,7 +446,7 @@ TEST(AnimationTest, TrimTimeStarting) { } TEST(AnimationTest, TrimTimeNeedsSynchronizedStartTime) { - scoped_ptr<Animation> anim(CreateAnimation(1, 5.0)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 5.0)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); anim->set_needs_synchronized_start_time(true); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) @@ -472,7 +473,7 @@ TEST(AnimationTest, TrimTimeNeedsSynchronizedStartTime) { } TEST(AnimationTest, IsFinishedAtZeroIterations) { - scoped_ptr<Animation> anim(CreateAnimation(0)); + std::unique_ptr<Animation> anim(CreateAnimation(0)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_FALSE(anim->IsFinishedAt(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->IsFinishedAt(TicksFromSecondsF(0.0))); @@ -480,7 +481,7 @@ TEST(AnimationTest, IsFinishedAtZeroIterations) { } TEST(AnimationTest, IsFinishedAtOneIteration) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_FALSE(anim->IsFinishedAt(TicksFromSecondsF(-1.0))); EXPECT_FALSE(anim->IsFinishedAt(TicksFromSecondsF(0.0))); @@ -489,7 +490,7 @@ TEST(AnimationTest, IsFinishedAtOneIteration) { } TEST(AnimationTest, IsFinishedAtInfiniteIterations) { - scoped_ptr<Animation> anim(CreateAnimation(-1)); + std::unique_ptr<Animation> anim(CreateAnimation(-1)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_FALSE(anim->IsFinishedAt(TicksFromSecondsF(0.0))); EXPECT_FALSE(anim->IsFinishedAt(TicksFromSecondsF(0.5))); @@ -498,7 +499,7 @@ TEST(AnimationTest, IsFinishedAtInfiniteIterations) { } TEST(AnimationTest, IsFinishedNegativeTimeOffset) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(TimeDelta::FromMilliseconds(-500)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); @@ -512,7 +513,7 @@ TEST(AnimationTest, IsFinishedNegativeTimeOffset) { } TEST(AnimationTest, IsFinishedPositiveTimeOffset) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(TimeDelta::FromMilliseconds(500)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); @@ -523,7 +524,7 @@ TEST(AnimationTest, IsFinishedPositiveTimeOffset) { } TEST(AnimationTest, IsFinishedAtNotRunning) { - scoped_ptr<Animation> anim(CreateAnimation(0)); + std::unique_ptr<Animation> anim(CreateAnimation(0)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_TRUE(anim->IsFinishedAt(TicksFromSecondsF(0.0))); anim->SetRunState(Animation::PAUSED, TicksFromSecondsF(0.0)); @@ -538,7 +539,7 @@ TEST(AnimationTest, IsFinishedAtNotRunning) { } TEST(AnimationTest, IsFinished) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); EXPECT_FALSE(anim->is_finished()); anim->SetRunState(Animation::PAUSED, TicksFromSecondsF(0.0)); @@ -553,7 +554,7 @@ TEST(AnimationTest, IsFinished) { } TEST(AnimationTest, IsFinishedNeedsSynchronizedStartTime) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(2.0)); EXPECT_FALSE(anim->is_finished()); anim->SetRunState(Animation::PAUSED, TicksFromSecondsF(2.0)); @@ -568,7 +569,7 @@ TEST(AnimationTest, IsFinishedNeedsSynchronizedStartTime) { } TEST(AnimationTest, RunStateChangesIgnoredWhileSuspended) { - scoped_ptr<Animation> anim(CreateAnimation(1)); + std::unique_ptr<Animation> anim(CreateAnimation(1)); anim->Suspend(TicksFromSecondsF(0)); EXPECT_EQ(Animation::PAUSED, anim->run_state()); anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0)); @@ -579,7 +580,7 @@ TEST(AnimationTest, RunStateChangesIgnoredWhileSuspended) { } TEST(AnimationTest, TrimTimePlaybackNormal) { - scoped_ptr<Animation> anim(CreateAnimation(1, 1, 1)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 1, 1)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -593,7 +594,7 @@ TEST(AnimationTest, TrimTimePlaybackNormal) { } TEST(AnimationTest, TrimTimePlaybackSlow) { - scoped_ptr<Animation> anim(CreateAnimation(1, 1, 0.5)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 1, 0.5)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -609,7 +610,7 @@ TEST(AnimationTest, TrimTimePlaybackSlow) { } TEST(AnimationTest, TrimTimePlaybackFast) { - scoped_ptr<Animation> anim(CreateAnimation(1, 4, 2)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 4, 2)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -627,7 +628,7 @@ TEST(AnimationTest, TrimTimePlaybackFast) { } TEST(AnimationTest, TrimTimePlaybackNormalReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1, 2, -1)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 2, -1)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -645,7 +646,7 @@ TEST(AnimationTest, TrimTimePlaybackNormalReverse) { } TEST(AnimationTest, TrimTimePlaybackSlowReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1, 2, -0.5)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 2, -0.5)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -671,7 +672,7 @@ TEST(AnimationTest, TrimTimePlaybackSlowReverse) { } TEST(AnimationTest, TrimTimePlaybackFastReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1, 2, -2)); + std::unique_ptr<Animation> anim(CreateAnimation(1, 2, -2)); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -689,7 +690,7 @@ TEST(AnimationTest, TrimTimePlaybackFastReverse) { } TEST(AnimationTest, TrimTimePlaybackFastInfiniteIterations) { - scoped_ptr<Animation> anim(CreateAnimation(-1, 4, 4)); + std::unique_ptr<Animation> anim(CreateAnimation(-1, 4, 4)); EXPECT_EQ( 0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF()); EXPECT_EQ( @@ -705,8 +706,8 @@ TEST(AnimationTest, TrimTimePlaybackFastInfiniteIterations) { } TEST(AnimationTest, TrimTimePlaybackNormalDoubleReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1, 1, -1)); - anim->set_direction(Animation::DIRECTION_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(1, 1, -1)); + anim->set_direction(Animation::Direction::REVERSE); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -720,8 +721,8 @@ TEST(AnimationTest, TrimTimePlaybackNormalDoubleReverse) { } TEST(AnimationTest, TrimTimePlaybackFastDoubleReverse) { - scoped_ptr<Animation> anim(CreateAnimation(1, 4, -2)); - anim->set_direction(Animation::DIRECTION_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(1, 4, -2)); + anim->set_direction(Animation::Direction::REVERSE); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ( @@ -739,8 +740,8 @@ TEST(AnimationTest, TrimTimePlaybackFastDoubleReverse) { } TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFast) { - scoped_ptr<Animation> anim(CreateAnimation(2, 2, 2)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(2, 2, 2)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -764,8 +765,8 @@ TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFast) { } TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFastReverse) { - scoped_ptr<Animation> anim(CreateAnimation(2, 2, 2)); - anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(2, 2, 2)); + anim->set_direction(Animation::Direction::ALTERNATE_REVERSE); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); EXPECT_EQ(2.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) @@ -791,8 +792,8 @@ TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFastReverse) { } TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFastDoubleReverse) { - scoped_ptr<Animation> anim(CreateAnimation(2, 2, -2)); - anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(2, 2, -2)); + anim->set_direction(Animation::Direction::ALTERNATE_REVERSE); EXPECT_EQ(2.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(1.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -817,8 +818,8 @@ TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFastDoubleReverse) { TEST(AnimationTest, TrimTimeAlternateReverseThreeIterationsPlaybackFastAlternateReverse) { - scoped_ptr<Animation> anim(CreateAnimation(3, 2, -2)); - anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE); + std::unique_ptr<Animation> anim(CreateAnimation(3, 2, -2)); + anim->set_direction(Animation::Direction::ALTERNATE_REVERSE); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25)) @@ -851,8 +852,8 @@ TEST(AnimationTest, TEST(AnimationTest, TrimTimeAlternateReverseTwoIterationsPlaybackNormalAlternate) { - scoped_ptr<Animation> anim(CreateAnimation(2, 2, -1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(2, 2, -1)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5)) @@ -876,7 +877,7 @@ TEST(AnimationTest, } TEST(AnimationTest, TrimTimeIterationStart) { - scoped_ptr<Animation> anim(CreateAnimation(2, 1, 1)); + std::unique_ptr<Animation> anim(CreateAnimation(2, 1, 1)); anim->set_iteration_start(0.5); EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); @@ -895,8 +896,8 @@ TEST(AnimationTest, TrimTimeIterationStart) { } TEST(AnimationTest, TrimTimeIterationStartAlternate) { - scoped_ptr<Animation> anim(CreateAnimation(2, 1, 1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(2, 1, 1)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); anim->set_iteration_start(0.3); EXPECT_EQ(0.3, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); @@ -915,8 +916,8 @@ TEST(AnimationTest, TrimTimeIterationStartAlternate) { } TEST(AnimationTest, TrimTimeIterationStartAlternateThreeIterations) { - scoped_ptr<Animation> anim(CreateAnimation(3, 1, 1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(3, 1, 1)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); anim->set_iteration_start(1); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0)) .InSecondsF()); @@ -940,8 +941,8 @@ TEST(AnimationTest, TrimTimeIterationStartAlternateThreeIterations) { TEST(AnimationTest, TrimTimeIterationStartAlternateThreeIterationsPlaybackReverse) { - scoped_ptr<Animation> anim(CreateAnimation(3, 1, -1)); - anim->set_direction(Animation::DIRECTION_ALTERNATE); + std::unique_ptr<Animation> anim(CreateAnimation(3, 1, -1)); + anim->set_direction(Animation::Direction::ALTERNATE_NORMAL); anim->set_iteration_start(1); EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)) .InSecondsF()); @@ -956,46 +957,46 @@ TEST(AnimationTest, } TEST(AnimationTest, InEffectFillMode) { - scoped_ptr<Animation> anim(CreateAnimation(1)); - anim->set_fill_mode(Animation::FILL_MODE_NONE); + std::unique_ptr<Animation> anim(CreateAnimation(1)); + anim->set_fill_mode(Animation::FillMode::NONE); EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); - anim->set_fill_mode(Animation::FILL_MODE_FORWARDS); + anim->set_fill_mode(Animation::FillMode::FORWARDS); EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); - anim->set_fill_mode(Animation::FILL_MODE_BACKWARDS); + anim->set_fill_mode(Animation::FillMode::BACKWARDS); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); - anim->set_fill_mode(Animation::FILL_MODE_BOTH); + anim->set_fill_mode(Animation::FillMode::BOTH); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); } TEST(AnimationTest, InEffectFillModePlayback) { - scoped_ptr<Animation> anim(CreateAnimation(1, 1, -1)); - anim->set_fill_mode(Animation::FILL_MODE_NONE); + std::unique_ptr<Animation> anim(CreateAnimation(1, 1, -1)); + anim->set_fill_mode(Animation::FillMode::NONE); EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); - anim->set_fill_mode(Animation::FILL_MODE_FORWARDS); + anim->set_fill_mode(Animation::FillMode::FORWARDS); EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); - anim->set_fill_mode(Animation::FILL_MODE_BACKWARDS); + anim->set_fill_mode(Animation::FillMode::BACKWARDS); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); - anim->set_fill_mode(Animation::FILL_MODE_BOTH); + anim->set_fill_mode(Animation::FillMode::BOTH); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0))); EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0))); diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc index 6a9dc33dc5d..404e9a0aebb 100644 --- a/chromium/cc/animation/element_animations.cc +++ b/chromium/cc/animation/element_animations.cc @@ -4,240 +4,1380 @@ #include "cc/animation/element_animations.h" +#include <stddef.h> + +#include <algorithm> + #include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "cc/animation/animation_delegate.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/animation/keyframed_animation_curve.h" +#include "cc/animation/scroll_offset_animation_curve.h" +#include "cc/output/filter_operations.h" #include "cc/trees/mutator_host_client.h" +#include "ui/gfx/geometry/box_f.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_); +scoped_refptr<ElementAnimations> ElementAnimations::Create() { + return make_scoped_refptr(new ElementAnimations()); +} + +ElementAnimations::ElementAnimations() + : players_list_(new PlayersList()), + animation_host_(), + element_id_(), + is_active_(false), + has_element_in_active_list_(false), + has_element_in_pending_list_(false), + needs_to_start_animations_(false), + scroll_offset_animation_was_interrupted_(false) {} + +ElementAnimations::~ElementAnimations() {} + +void ElementAnimations::SetAnimationHost(AnimationHost* host) { + animation_host_ = host; +} + +void ElementAnimations::SetElementId(ElementId element_id) { + element_id_ = element_id; +} + +void ElementAnimations::InitAffectedElementTypes() { + DCHECK(element_id_); + DCHECK(animation_host_); + + UpdateActivation(FORCE_ACTIVATION); + + DCHECK(animation_host_->mutator_host_client()); + if (animation_host_->mutator_host_client()->IsElementInList( + element_id_, ElementListType::ACTIVE)) { + set_has_element_in_active_list(true); + } + if (animation_host_->mutator_host_client()->IsElementInList( + element_id_, ElementListType::PENDING)) { + set_has_element_in_pending_list(true); + } +} + +void ElementAnimations::ClearAffectedElementTypes() { + DCHECK(animation_host_); + + if (has_element_in_active_list()) { + IsAnimatingChanged(ElementListType::ACTIVE, TargetProperty::TRANSFORM, + AnimationChangeType::BOTH, false); + IsAnimatingChanged(ElementListType::ACTIVE, TargetProperty::OPACITY, + AnimationChangeType::BOTH, false); + } + set_has_element_in_active_list(false); + + if (has_element_in_pending_list()) { + IsAnimatingChanged(ElementListType::PENDING, TargetProperty::TRANSFORM, + AnimationChangeType::BOTH, false); + IsAnimatingChanged(ElementListType::PENDING, TargetProperty::OPACITY, + AnimationChangeType::BOTH, false); + } + set_has_element_in_pending_list(false); + + animation_host_->DidDeactivateElementAnimations(this); + UpdateActivation(FORCE_ACTIVATION); +} + +void ElementAnimations::ElementRegistered(ElementId element_id, + ElementListType list_type) { + DCHECK_EQ(element_id_, element_id); + + if (list_type == ElementListType::ACTIVE) + set_has_element_in_active_list(true); + else + set_has_element_in_pending_list(true); +} + +void ElementAnimations::ElementUnregistered(ElementId element_id, + ElementListType list_type) { + DCHECK_EQ(this->element_id(), element_id); + if (list_type == ElementListType::ACTIVE) + set_has_element_in_active_list(false); + else + set_has_element_in_pending_list(false); +} + +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( + scoped_refptr<ElementAnimations> element_animations_impl) { + DCHECK_NE(this, element_animations_impl); + if (!has_any_animation() && !element_animations_impl->has_any_animation()) + return; + MarkAbortedAnimationsForDeletion(element_animations_impl.get()); + PurgeAnimationsMarkedForDeletion(); + PushNewAnimationsToImplThread(element_animations_impl.get()); + + // Remove finished impl side animations only after pushing, + // and only after the animations are deleted on the main thread + // this insures we will never push an animation twice. + RemoveAnimationsCompletedOnMainThread(element_animations_impl.get()); + + PushPropertiesToImplThread(element_animations_impl.get()); + element_animations_impl->UpdateActivation(NORMAL_ACTIVATION); + UpdateActivation(NORMAL_ACTIVATION); +} + +void ElementAnimations::AddAnimation(std::unique_ptr<Animation> animation) { + DCHECK(!animation->is_impl_only() || + animation->target_property() == TargetProperty::SCROLL_OFFSET); + bool added_transform_animation = + animation->target_property() == TargetProperty::TRANSFORM; + bool added_opacity_animation = + animation->target_property() == TargetProperty::OPACITY; + animations_.push_back(std::move(animation)); + needs_to_start_animations_ = true; + UpdateActivation(NORMAL_ACTIVATION); + if (added_transform_animation) + UpdateClientAnimationState(TargetProperty::TRANSFORM); + if (added_opacity_animation) + UpdateClientAnimationState(TargetProperty::OPACITY); +} + +void ElementAnimations::Animate(base::TimeTicks monotonic_time) { + DCHECK(!monotonic_time.is_null()); + if (!has_element_in_active_list() && !has_element_in_pending_list()) + return; + + if (needs_to_start_animations_) + StartAnimations(monotonic_time); + TickAnimations(monotonic_time); + last_tick_time_ = monotonic_time; + UpdateClientAnimationState(TargetProperty::OPACITY); + UpdateClientAnimationState(TargetProperty::TRANSFORM); +} + +void ElementAnimations::UpdateState(bool start_ready_animations, + AnimationEvents* events) { + if (!has_element_in_active_list()) + return; + + // Animate hasn't been called, this happens if an element has been added + // between the Commit and Draw phases. + if (last_tick_time_ == base::TimeTicks()) + return; + + if (start_ready_animations) + PromoteStartedAnimations(last_tick_time_, events); + + MarkFinishedAnimations(last_tick_time_); + MarkAnimationsForDeletion(last_tick_time_, events); + + if (needs_to_start_animations_ && start_ready_animations) { + StartAnimations(last_tick_time_); + PromoteStartedAnimations(last_tick_time_, events); } - // LayerAnimationValueObserver implementation. - void OnFilterAnimated(const FilterOperations& filters) override { - element_animations_->SetFilterMutated(tree_type_, filters); + UpdateActivation(NORMAL_ACTIVATION); +} + +void ElementAnimations::ActivateAnimations() { + bool changed_transform_animation = false; + bool changed_opacity_animation = false; + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->affects_active_elements() != + animations_[i]->affects_pending_elements()) { + if (animations_[i]->target_property() == TargetProperty::TRANSFORM) + changed_transform_animation = true; + else if (animations_[i]->target_property() == TargetProperty::OPACITY) + changed_opacity_animation = true; + } + animations_[i]->set_affects_active_elements( + animations_[i]->affects_pending_elements()); } + auto affects_no_elements = [](const std::unique_ptr<Animation>& animation) { + return !animation->affects_active_elements() && + !animation->affects_pending_elements(); + }; + animations_.erase(std::remove_if(animations_.begin(), animations_.end(), + affects_no_elements), + animations_.end()); + scroll_offset_animation_was_interrupted_ = false; + UpdateActivation(NORMAL_ACTIVATION); + if (changed_transform_animation) + UpdateClientAnimationState(TargetProperty::TRANSFORM); + if (changed_opacity_animation) + UpdateClientAnimationState(TargetProperty::OPACITY); +} - void OnOpacityAnimated(float opacity) override { - element_animations_->SetOpacityMutated(tree_type_, opacity); +void ElementAnimations::NotifyAnimationStarted(const AnimationEvent& event) { + if (event.is_impl_only) { + NotifyPlayersAnimationStarted(event.monotonic_time, event.target_property, + event.group_id); + return; } - void OnTransformAnimated(const gfx::Transform& transform) override { - element_animations_->SetTransformMutated(tree_type_, transform); + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->group() == event.group_id && + animations_[i]->target_property() == event.target_property && + animations_[i]->needs_synchronized_start_time()) { + animations_[i]->set_needs_synchronized_start_time(false); + if (!animations_[i]->has_set_start_time()) + animations_[i]->set_start_time(event.monotonic_time); + + NotifyPlayersAnimationStarted(event.monotonic_time, event.target_property, + event.group_id); + + return; + } } +} - void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) override { - element_animations_->SetScrollOffsetMutated(tree_type_, scroll_offset); +void ElementAnimations::NotifyAnimationFinished(const AnimationEvent& event) { + if (event.is_impl_only) { + NotifyPlayersAnimationFinished(event.monotonic_time, event.target_property, + event.group_id); + return; } - void OnAnimationWaitingForDeletion() override { - // TODO(loyso): See Layer::OnAnimationWaitingForDeletion. But we always do - // PushProperties for AnimationTimelines for now. + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->group() == event.group_id && + animations_[i]->target_property() == event.target_property) { + animations_[i]->set_received_finished_event(true); + NotifyPlayersAnimationFinished(event.monotonic_time, + event.target_property, event.group_id); + + return; + } } +} - void OnTransformIsPotentiallyAnimatingChanged(bool is_animating) override { - element_animations_->SetTransformIsPotentiallyAnimatingChanged( - tree_type_, is_animating); +void ElementAnimations::NotifyAnimationTakeover(const AnimationEvent& event) { + DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET); + if (!players_list_->empty()) { + std::unique_ptr<AnimationCurve> animation_curve = event.curve->Clone(); + NotifyPlayersAnimationTakeover(event.monotonic_time, event.target_property, + event.animation_start_time, + std::move(animation_curve)); } +} - bool IsActive() const override { return tree_type_ == LayerTreeType::ACTIVE; } +void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) { + bool aborted_transform_animation = false; + bool aborted_opacity_animation = false; + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->group() == event.group_id && + animations_[i]->target_property() == event.target_property) { + animations_[i]->SetRunState(Animation::ABORTED, event.monotonic_time); + animations_[i]->set_received_finished_event(true); + NotifyPlayersAnimationAborted(event.monotonic_time, event.target_property, + event.group_id); + if (event.target_property == TargetProperty::TRANSFORM) + aborted_transform_animation = true; + else if (event.target_property == TargetProperty::OPACITY) + aborted_opacity_animation = true; + break; + } + } + if (aborted_transform_animation) + UpdateClientAnimationState(TargetProperty::TRANSFORM); + if (aborted_opacity_animation) + UpdateClientAnimationState(TargetProperty::OPACITY); +} - private: - ElementAnimations* element_animations_; - const LayerTreeType tree_type_; +void ElementAnimations::NotifyAnimationPropertyUpdate( + const AnimationEvent& event) { + bool notify_active_elements = true; + bool notify_pending_elements = true; + switch (event.target_property) { + case TargetProperty::OPACITY: + NotifyClientOpacityAnimated(event.opacity, notify_active_elements, + notify_pending_elements); + break; + case TargetProperty::TRANSFORM: + NotifyClientTransformAnimated(event.transform, notify_active_elements, + notify_pending_elements); + break; + default: + NOTREACHED(); + } +} - DISALLOW_COPY_AND_ASSIGN(ValueObserver); -}; +bool ElementAnimations::HasFilterAnimationThatInflatesBounds() const { + for (size_t i = 0; i < animations_.size(); ++i) { + if (!animations_[i]->is_finished() && + animations_[i]->target_property() == TargetProperty::FILTER && + animations_[i] + ->curve() + ->ToFilterAnimationCurve() + ->HasFilterThatMovesPixels()) + return true; + } -scoped_ptr<ElementAnimations> ElementAnimations::Create(AnimationHost* host) { - return make_scoped_ptr(new ElementAnimations(host)); + return false; } -ElementAnimations::ElementAnimations(AnimationHost* host) - : players_list_(make_scoped_ptr(new PlayersList())), animation_host_(host) { - DCHECK(animation_host_); +bool ElementAnimations::HasTransformAnimationThatInflatesBounds() const { + return IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM, + ElementListType::ACTIVE) || + IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM, + ElementListType::PENDING); } -ElementAnimations::~ElementAnimations() { - DCHECK(!layer_animation_controller_); +bool ElementAnimations::FilterAnimationBoundsForBox(const gfx::BoxF& box, + gfx::BoxF* bounds) const { + // TODO(avallee): Implement. + return false; } -void ElementAnimations::CreateLayerAnimationController(int layer_id) { - DCHECK(layer_id); - DCHECK(!layer_animation_controller_); - DCHECK(animation_host_); +bool ElementAnimations::TransformAnimationBoundsForBox( + const gfx::BoxF& box, + gfx::BoxF* bounds) const { + DCHECK(HasTransformAnimationThatInflatesBounds()) + << "TransformAnimationBoundsForBox will give incorrect results if there " + << "are no transform animations affecting bounds, non-animated transform " + << "is not known"; - AnimationRegistrar* registrar = animation_host_->animation_registrar(); - DCHECK(registrar); + // Compute bounds based on animations for which is_finished() is false. + // Do nothing if there are no such animations; in this case, it is assumed + // that callers will take care of computing bounds based on the owning layer's + // actual transform. + *bounds = gfx::BoxF(); + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->is_finished() || + animations_[i]->target_property() != TargetProperty::TRANSFORM) + continue; - 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); + const TransformAnimationCurve* transform_animation_curve = + animations_[i]->curve()->ToTransformAnimationCurve(); + gfx::BoxF animation_bounds; + bool success = + transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds); + if (!success) + return false; + bounds->Union(animation_bounds); + } - 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(); + return true; } -void ElementAnimations::DestroyLayerAnimationController() { - DCHECK(animation_host_); +bool ElementAnimations::HasAnimationThatAffectsScale() const { + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->is_finished() || + animations_[i]->target_property() != TargetProperty::TRANSFORM) + continue; - if (active_value_observer_) - SetTransformIsPotentiallyAnimatingChanged(LayerTreeType::ACTIVE, false); - if (pending_value_observer_) - SetTransformIsPotentiallyAnimatingChanged(LayerTreeType::PENDING, false); + const TransformAnimationCurve* transform_animation_curve = + animations_[i]->curve()->ToTransformAnimationCurve(); + if (transform_animation_curve->AffectsScale()) + return true; + } - DestroyPendingValueObserver(); - DestroyActiveValueObserver(); + return false; +} - 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; +bool ElementAnimations::HasOnlyTranslationTransforms( + ElementListType list_type) const { + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->is_finished() || + animations_[i]->target_property() != TargetProperty::TRANSFORM) + continue; + + if ((list_type == ElementListType::ACTIVE && + !animations_[i]->affects_active_elements()) || + (list_type == ElementListType::PENDING && + !animations_[i]->affects_pending_elements())) + continue; + + const TransformAnimationCurve* transform_animation_curve = + animations_[i]->curve()->ToTransformAnimationCurve(); + if (!transform_animation_curve->IsTranslation()) + return false; } + + return true; } -void ElementAnimations::LayerRegistered(int layer_id, LayerTreeType tree_type) { - DCHECK(layer_animation_controller_); - DCHECK_EQ(layer_animation_controller_->id(), layer_id); +bool ElementAnimations::AnimationsPreserveAxisAlignment() const { + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->is_finished() || + animations_[i]->target_property() != TargetProperty::TRANSFORM) + continue; - if (tree_type == LayerTreeType::ACTIVE) { - if (!active_value_observer_) - CreateActiveValueObserver(); - } else { - if (!pending_value_observer_) - CreatePendingValueObserver(); + const TransformAnimationCurve* transform_animation_curve = + animations_[i]->curve()->ToTransformAnimationCurve(); + if (!transform_animation_curve->PreservesAxisAlignment()) + return false; } + + return true; } -void ElementAnimations::LayerUnregistered(int layer_id, - LayerTreeType tree_type) { - DCHECK_EQ(this->layer_id(), layer_id); - tree_type == LayerTreeType::ACTIVE ? DestroyActiveValueObserver() - : DestroyPendingValueObserver(); +bool ElementAnimations::AnimationStartScale(ElementListType list_type, + float* start_scale) const { + *start_scale = 0.f; + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->is_finished() || + animations_[i]->target_property() != TargetProperty::TRANSFORM) + continue; + + if ((list_type == ElementListType::ACTIVE && + !animations_[i]->affects_active_elements()) || + (list_type == ElementListType::PENDING && + !animations_[i]->affects_pending_elements())) + continue; + + bool forward_direction = true; + switch (animations_[i]->direction()) { + case Animation::Direction::NORMAL: + case Animation::Direction::ALTERNATE_NORMAL: + forward_direction = animations_[i]->playback_rate() >= 0.0; + break; + case Animation::Direction::REVERSE: + case Animation::Direction::ALTERNATE_REVERSE: + forward_direction = animations_[i]->playback_rate() < 0.0; + break; + } + + const TransformAnimationCurve* transform_animation_curve = + animations_[i]->curve()->ToTransformAnimationCurve(); + float animation_start_scale = 0.f; + if (!transform_animation_curve->AnimationStartScale(forward_direction, + &animation_start_scale)) + return false; + *start_scale = std::max(*start_scale, animation_start_scale); + } + return true; } -void ElementAnimations::AddPlayer(AnimationPlayer* player) { - players_list_->Append(player); +bool ElementAnimations::MaximumTargetScale(ElementListType list_type, + float* max_scale) const { + *max_scale = 0.f; + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->is_finished() || + animations_[i]->target_property() != TargetProperty::TRANSFORM) + continue; + + if ((list_type == ElementListType::ACTIVE && + !animations_[i]->affects_active_elements()) || + (list_type == ElementListType::PENDING && + !animations_[i]->affects_pending_elements())) + continue; + + bool forward_direction = true; + switch (animations_[i]->direction()) { + case Animation::Direction::NORMAL: + case Animation::Direction::ALTERNATE_NORMAL: + forward_direction = animations_[i]->playback_rate() >= 0.0; + break; + case Animation::Direction::REVERSE: + case Animation::Direction::ALTERNATE_REVERSE: + forward_direction = animations_[i]->playback_rate() < 0.0; + break; + } + + const TransformAnimationCurve* transform_animation_curve = + animations_[i]->curve()->ToTransformAnimationCurve(); + float animation_scale = 0.f; + if (!transform_animation_curve->MaximumTargetScale(forward_direction, + &animation_scale)) + return false; + *max_scale = std::max(*max_scale, animation_scale); + } + + return true; } -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; +void ElementAnimations::PushNewAnimationsToImplThread( + ElementAnimations* element_animations_impl) const { + // Any new animations owned by the main thread's ElementAnimations are cloned + // and added to the impl thread's ElementAnimations. + for (size_t i = 0; i < animations_.size(); ++i) { + // If the animation is already running on the impl thread, there is no + // need to copy it over. + if (element_animations_impl->GetAnimationById(animations_[i]->id())) + continue; + + if (animations_[i]->target_property() == TargetProperty::SCROLL_OFFSET && + !animations_[i] + ->curve() + ->ToScrollOffsetAnimationCurve() + ->HasSetInitialValue()) { + gfx::ScrollOffset current_scroll_offset; + if (element_animations_impl->has_element_in_active_list()) { + current_scroll_offset = + element_animations_impl->ScrollOffsetForAnimation(); + } else { + // The owning layer isn't yet in the active tree, so the main thread + // scroll offset will be up-to-date. + current_scroll_offset = ScrollOffsetForAnimation(); + } + animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue( + current_scroll_offset); } + + // The new animation should be set to run as soon as possible. + Animation::RunState initial_run_state = + Animation::WAITING_FOR_TARGET_AVAILABILITY; + std::unique_ptr<Animation> to_add( + animations_[i]->CloneAndInitialize(initial_run_state)); + DCHECK(!to_add->needs_synchronized_start_time()); + to_add->set_affects_active_elements(false); + element_animations_impl->AddAnimation(std::move(to_add)); } } -bool ElementAnimations::IsEmpty() const { - return players_list_->empty(); +static bool IsCompleted( + Animation* animation, + const ElementAnimations* main_thread_element_animations) { + if (animation->is_impl_only()) { + return (animation->run_state() == Animation::WAITING_FOR_DELETION); + } else { + return !main_thread_element_animations->GetAnimationById(animation->id()); + } } -void ElementAnimations::PushPropertiesTo( +void ElementAnimations::RemoveAnimationsCompletedOnMainThread( + ElementAnimations* element_animations_impl) const { + bool removed_transform_animation = false; + bool removed_opacity_animation = false; + // Animations removed on the main thread should no longer affect pending + // elements, and should stop affecting active elements after the next call + // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed + // immediately. + auto& animations = element_animations_impl->animations_; + for (const auto& animation : animations) { + if (IsCompleted(animation.get(), this)) { + animation->set_affects_pending_elements(false); + if (animation->target_property() == TargetProperty::TRANSFORM) + removed_transform_animation = true; + else if (animation->target_property() == TargetProperty::OPACITY) + removed_opacity_animation = true; + } + } + auto affects_active_only_and_is_waiting_for_deletion = + [](const std::unique_ptr<Animation>& animation) { + return animation->run_state() == Animation::WAITING_FOR_DELETION && + !animation->affects_pending_elements(); + }; + animations.erase( + std::remove_if(animations.begin(), animations.end(), + affects_active_only_and_is_waiting_for_deletion), + animations.end()); + + if (removed_transform_animation) + element_animations_impl->UpdateClientAnimationState( + TargetProperty::TRANSFORM); + if (removed_opacity_animation) + element_animations_impl->UpdateClientAnimationState( + TargetProperty::OPACITY); +} + +void ElementAnimations::PushPropertiesToImplThread( ElementAnimations* element_animations_impl) { - DCHECK(layer_animation_controller_); - DCHECK(element_animations_impl->layer_animation_controller()); + for (size_t i = 0; i < animations_.size(); ++i) { + Animation* current_impl = + element_animations_impl->GetAnimationById(animations_[i]->id()); + if (current_impl) + animations_[i]->PushPropertiesTo(current_impl); + } + element_animations_impl->scroll_offset_animation_was_interrupted_ = + scroll_offset_animation_was_interrupted_; + scroll_offset_animation_was_interrupted_ = false; +} + +void ElementAnimations::StartAnimations(base::TimeTicks monotonic_time) { + DCHECK(needs_to_start_animations_); + needs_to_start_animations_ = false; + // First collect running properties affecting each type of element. + TargetProperties blocked_properties_for_active_elements; + TargetProperties blocked_properties_for_pending_elements; + std::vector<size_t> animations_waiting_for_target; + + animations_waiting_for_target.reserve(animations_.size()); + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->run_state() == Animation::STARTING || + animations_[i]->run_state() == Animation::RUNNING) { + if (animations_[i]->affects_active_elements()) { + blocked_properties_for_active_elements[animations_[i] + ->target_property()] = true; + } + if (animations_[i]->affects_pending_elements()) { + blocked_properties_for_pending_elements[animations_[i] + ->target_property()] = true; + } + } else if (animations_[i]->run_state() == + Animation::WAITING_FOR_TARGET_AVAILABILITY) { + animations_waiting_for_target.push_back(i); + } + } + + for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) { + // Collect all properties for animations with the same group id (they + // should all also be in the list of animations). + size_t animation_index = animations_waiting_for_target[i]; + Animation* animation_waiting_for_target = + animations_[animation_index].get(); + // Check for the run state again even though the animation was waiting + // for target because it might have changed the run state while handling + // previous animation in this loop (if they belong to same group). + if (animation_waiting_for_target->run_state() == + Animation::WAITING_FOR_TARGET_AVAILABILITY) { + TargetProperties enqueued_properties; + bool affects_active_elements = + animation_waiting_for_target->affects_active_elements(); + bool affects_pending_elements = + animation_waiting_for_target->affects_pending_elements(); + enqueued_properties[animation_waiting_for_target->target_property()] = + true; + for (size_t j = animation_index + 1; j < animations_.size(); ++j) { + if (animation_waiting_for_target->group() == animations_[j]->group()) { + enqueued_properties[animations_[j]->target_property()] = true; + affects_active_elements |= animations_[j]->affects_active_elements(); + affects_pending_elements |= + animations_[j]->affects_pending_elements(); + } + } + + // Check to see if intersection of the list of properties affected by + // the group and the list of currently blocked properties is null, taking + // into account the type(s) of elements affected by the group. In any + // case, the group's target properties need to be added to the lists of + // blocked properties. + bool null_intersection = true; + static_assert(TargetProperty::FIRST_TARGET_PROPERTY == 0, + "TargetProperty must be 0-based enum"); + for (int property = TargetProperty::FIRST_TARGET_PROPERTY; + property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { + if (enqueued_properties[property]) { + if (affects_active_elements) { + if (blocked_properties_for_active_elements[property]) + null_intersection = false; + else + blocked_properties_for_active_elements[property] = true; + } + if (affects_pending_elements) { + if (blocked_properties_for_pending_elements[property]) + null_intersection = false; + else + blocked_properties_for_pending_elements[property] = true; + } + } + } + + // If the intersection is null, then we are free to start the animations + // in the group. + if (null_intersection) { + animation_waiting_for_target->SetRunState(Animation::STARTING, + monotonic_time); + for (size_t j = animation_index + 1; j < animations_.size(); ++j) { + if (animation_waiting_for_target->group() == + animations_[j]->group()) { + animations_[j]->SetRunState(Animation::STARTING, monotonic_time); + } + } + } else { + needs_to_start_animations_ = true; + } + } + } +} + +void ElementAnimations::PromoteStartedAnimations(base::TimeTicks monotonic_time, + AnimationEvents* events) { + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->run_state() == Animation::STARTING && + animations_[i]->affects_active_elements()) { + animations_[i]->SetRunState(Animation::RUNNING, monotonic_time); + if (!animations_[i]->has_set_start_time() && + !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, element_id_, animations_[i]->group(), + 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); + else + events->events_.push_back(started_event); + } + } + } +} + +void ElementAnimations::MarkFinishedAnimations(base::TimeTicks monotonic_time) { + bool finished_transform_animation = false; + bool finished_opacity_animation = false; + for (size_t i = 0; i < animations_.size(); ++i) { + if (!animations_[i]->is_finished() && + animations_[i]->IsFinishedAt(monotonic_time)) { + animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); + if (animations_[i]->target_property() == TargetProperty::TRANSFORM) + finished_transform_animation = true; + else if (animations_[i]->target_property() == TargetProperty::OPACITY) + finished_opacity_animation = true; + } + } + if (finished_transform_animation) + UpdateClientAnimationState(TargetProperty::TRANSFORM); + if (finished_opacity_animation) + UpdateClientAnimationState(TargetProperty::OPACITY); +} + +void ElementAnimations::MarkAnimationsForDeletion( + base::TimeTicks monotonic_time, + AnimationEvents* events) { + bool marked_animations_for_deletions = false; + std::vector<size_t> animations_with_same_group_id; + + animations_with_same_group_id.reserve(animations_.size()); + // Non-aborted animations are marked for deletion after a corresponding + // AnimationEvent::FINISHED event is sent or received. This means that if + // we don't have an events vector, we must ensure that non-aborted animations + // have received a finished event before marking them for deletion. + for (size_t i = 0; i < animations_.size(); i++) { + int group_id = animations_[i]->group(); + if (animations_[i]->run_state() == Animation::ABORTED) { + if (events && !animations_[i]->is_impl_only()) { + AnimationEvent aborted_event( + AnimationEvent::ABORTED, element_id_, group_id, + animations_[i]->target_property(), monotonic_time); + events->events_.push_back(aborted_event); + } + // If on the compositor or on the main thread and received finish event, + // animation can be marked for deletion. + if (events || animations_[i]->received_finished_event()) { + animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION, + monotonic_time); + marked_animations_for_deletions = true; + } + continue; + } + + // If running on the compositor and need to complete an aborted animation + // on the main thread. + if (events && + animations_[i]->run_state() == + Animation::ABORTED_BUT_NEEDS_COMPLETION) { + AnimationEvent aborted_event(AnimationEvent::TAKEOVER, element_id_, + group_id, animations_[i]->target_property(), + monotonic_time); + aborted_event.animation_start_time = + (animations_[i]->start_time() - base::TimeTicks()).InSecondsF(); + const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = + animations_[i]->curve()->ToScrollOffsetAnimationCurve(); + aborted_event.curve = scroll_offset_animation_curve->Clone(); + // Notify the compositor that the animation is finished. + NotifyPlayersAnimationFinished(aborted_event.monotonic_time, + aborted_event.target_property, + aborted_event.group_id); + // Notify main thread. + events->events_.push_back(aborted_event); + + // Remove the animation from the compositor. + animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION, + monotonic_time); + marked_animations_for_deletions = true; + continue; + } + + bool all_anims_with_same_id_are_finished = false; + + // Since deleting an animation on the main thread leads to its deletion + // 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 = + 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 && + animation_i_will_send_or_has_received_finish_event) { + // Clear the animations_with_same_group_id if it was added for + // the previous animation's iteration. + if (animations_with_same_group_id.size() > 0) + animations_with_same_group_id.clear(); + 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 = + 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 && + !animation_j_will_send_or_has_received_finish_event)) { + all_anims_with_same_id_are_finished = false; + break; + } else if (j >= i && + animations_[j]->run_state() != Animation::ABORTED) { + // Mark down the animations which belong to the same group + // and is not yet aborted. If this current iteration finds that all + // animations with same ID are finished, then the marked + // animations below will be set to WAITING_FOR_DELETION in next + // iteration. + animations_with_same_group_id.push_back(j); + } + } + } + } + if (all_anims_with_same_id_are_finished) { + // We now need to remove all animations with the same group id as + // group_id (and send along animation finished notifications, if + // necessary). + for (size_t j = 0; j < animations_with_same_group_id.size(); j++) { + size_t animation_index = animations_with_same_group_id[j]; + if (events) { + AnimationEvent finished_event( + AnimationEvent::FINISHED, element_id_, + animations_[animation_index]->group(), + animations_[animation_index]->target_property(), monotonic_time); + finished_event.is_impl_only = + animations_[animation_index]->is_impl_only(); + if (finished_event.is_impl_only) + NotifyAnimationFinished(finished_event); + else + events->events_.push_back(finished_event); + } + animations_[animation_index]->SetRunState( + Animation::WAITING_FOR_DELETION, monotonic_time); + } + marked_animations_for_deletions = true; + } + } + if (marked_animations_for_deletions) + NotifyClientAnimationWaitingForDeletion(); +} + +void ElementAnimations::MarkAbortedAnimationsForDeletion( + ElementAnimations* element_animations_impl) const { + bool aborted_transform_animation = false; + bool aborted_opacity_animation = false; + auto& animations_impl = element_animations_impl->animations_; + for (const auto& animation_impl : animations_impl) { + // If the animation has been aborted on the main thread, mark it for + // deletion. + if (Animation* animation = GetAnimationById(animation_impl->id())) { + if (animation->run_state() == Animation::ABORTED) { + animation_impl->SetRunState(Animation::WAITING_FOR_DELETION, + element_animations_impl->last_tick_time_); + animation->SetRunState(Animation::WAITING_FOR_DELETION, + last_tick_time_); + if (animation_impl->target_property() == TargetProperty::TRANSFORM) + aborted_transform_animation = true; + else if (animation_impl->target_property() == TargetProperty::OPACITY) + aborted_opacity_animation = true; + } + } + } + + if (aborted_transform_animation) + element_animations_impl->UpdateClientAnimationState( + TargetProperty::TRANSFORM); + if (aborted_opacity_animation) + element_animations_impl->UpdateClientAnimationState( + TargetProperty::OPACITY); +} + +void ElementAnimations::PurgeAnimationsMarkedForDeletion() { + animations_.erase( + std::remove_if(animations_.begin(), animations_.end(), + [](const std::unique_ptr<Animation>& animation) { + return animation->run_state() == + Animation::WAITING_FOR_DELETION; + }), + animations_.end()); +} + +void ElementAnimations::TickAnimations(base::TimeTicks monotonic_time) { + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->run_state() == Animation::STARTING || + animations_[i]->run_state() == Animation::RUNNING || + animations_[i]->run_state() == Animation::PAUSED) { + if (!animations_[i]->InEffect(monotonic_time)) + continue; + + base::TimeDelta trimmed = + animations_[i]->TrimTimeToCurrentIteration(monotonic_time); + + switch (animations_[i]->target_property()) { + case TargetProperty::TRANSFORM: { + const TransformAnimationCurve* transform_animation_curve = + animations_[i]->curve()->ToTransformAnimationCurve(); + const gfx::Transform transform = + transform_animation_curve->GetValue(trimmed); + NotifyClientTransformAnimated( + transform, animations_[i]->affects_active_elements(), + animations_[i]->affects_pending_elements()); + break; + } + + case TargetProperty::OPACITY: { + const FloatAnimationCurve* float_animation_curve = + animations_[i]->curve()->ToFloatAnimationCurve(); + const float opacity = std::max( + std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f); + NotifyClientOpacityAnimated( + opacity, animations_[i]->affects_active_elements(), + animations_[i]->affects_pending_elements()); + break; + } + + case TargetProperty::FILTER: { + const FilterAnimationCurve* filter_animation_curve = + animations_[i]->curve()->ToFilterAnimationCurve(); + const FilterOperations filter = + filter_animation_curve->GetValue(trimmed); + NotifyClientFilterAnimated( + filter, animations_[i]->affects_active_elements(), + animations_[i]->affects_pending_elements()); + break; + } + + case TargetProperty::BACKGROUND_COLOR: { + // Not yet implemented. + break; + } + + case TargetProperty::SCROLL_OFFSET: { + const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = + animations_[i]->curve()->ToScrollOffsetAnimationCurve(); + const gfx::ScrollOffset scroll_offset = + scroll_offset_animation_curve->GetValue(trimmed); + NotifyClientScrollOffsetAnimated( + scroll_offset, animations_[i]->affects_active_elements(), + animations_[i]->affects_pending_elements()); + break; + } + } + } + } +} + +void ElementAnimations::UpdateActivation(UpdateActivationType type) { + bool force = type == FORCE_ACTIVATION; + if (animation_host_) { + bool was_active = is_active_; + is_active_ = false; + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) { + is_active_ = true; + break; + } + } + + if (is_active_ && (!was_active || force)) + animation_host_->DidActivateElementAnimations(this); + else if (!is_active_ && (was_active || force)) + animation_host_->DidDeactivateElementAnimations(this); + } +} + +void ElementAnimations::NotifyClientOpacityAnimated( + float opacity, + bool notify_active_elements, + bool notify_pending_elements) { + if (notify_active_elements && has_element_in_active_list()) + OnOpacityAnimated(ElementListType::ACTIVE, opacity); + if (notify_pending_elements && has_element_in_pending_list()) + OnOpacityAnimated(ElementListType::PENDING, opacity); +} + +void ElementAnimations::NotifyClientTransformAnimated( + const gfx::Transform& transform, + bool notify_active_elements, + bool notify_pending_elements) { + if (notify_active_elements && has_element_in_active_list()) + OnTransformAnimated(ElementListType::ACTIVE, transform); + if (notify_pending_elements && has_element_in_pending_list()) + OnTransformAnimated(ElementListType::PENDING, transform); +} + +void ElementAnimations::NotifyClientFilterAnimated( + const FilterOperations& filters, + bool notify_active_elements, + bool notify_pending_elements) { + if (notify_active_elements && has_element_in_active_list()) + OnFilterAnimated(ElementListType::ACTIVE, filters); + if (notify_pending_elements && has_element_in_pending_list()) + OnFilterAnimated(ElementListType::PENDING, filters); +} + +void ElementAnimations::NotifyClientScrollOffsetAnimated( + const gfx::ScrollOffset& scroll_offset, + bool notify_active_elements, + bool notify_pending_elements) { + if (notify_active_elements && has_element_in_active_list()) + OnScrollOffsetAnimated(ElementListType::ACTIVE, scroll_offset); + if (notify_pending_elements && has_element_in_pending_list()) + OnScrollOffsetAnimated(ElementListType::PENDING, scroll_offset); +} + +void ElementAnimations::NotifyClientAnimationWaitingForDeletion() { + OnAnimationWaitingForDeletion(); +} + +void ElementAnimations::NotifyClientAnimationChanged( + TargetProperty::Type property, + ElementListType list_type, + bool notify_elements_about_potential_animation, + bool notify_elements_about_running_animation) { + struct PropertyAnimationState* animation_state = nullptr; + switch (property) { + case TargetProperty::OPACITY: + animation_state = &opacity_animation_state_; + break; + case TargetProperty::TRANSFORM: + animation_state = &transform_animation_state_; + break; + default: + NOTREACHED(); + break; + } + + bool notify_elements_about_potential_and_running_animation = + notify_elements_about_potential_animation && + notify_elements_about_running_animation; + bool active = list_type == ElementListType::ACTIVE; + if (notify_elements_about_potential_and_running_animation) { + bool potentially_animating = + active ? animation_state->potentially_animating_for_active_elements + : animation_state->potentially_animating_for_pending_elements; + bool currently_animating = + active ? animation_state->currently_running_for_active_elements + : animation_state->currently_running_for_pending_elements; + DCHECK_EQ(potentially_animating, currently_animating); + IsAnimatingChanged(list_type, property, AnimationChangeType::BOTH, + potentially_animating); + } else if (notify_elements_about_potential_animation) { + bool potentially_animating = + active ? animation_state->potentially_animating_for_active_elements + : animation_state->potentially_animating_for_pending_elements; + IsAnimatingChanged(list_type, property, AnimationChangeType::POTENTIAL, + potentially_animating); + } else if (notify_elements_about_running_animation) { + bool currently_animating = + active ? animation_state->currently_running_for_active_elements + : animation_state->currently_running_for_pending_elements; + IsAnimatingChanged(list_type, property, AnimationChangeType::RUNNING, + currently_animating); + } +} + +void ElementAnimations::UpdateClientAnimationState( + TargetProperty::Type property) { + struct PropertyAnimationState* animation_state = nullptr; + switch (property) { + case TargetProperty::OPACITY: + animation_state = &opacity_animation_state_; + break; + case TargetProperty::TRANSFORM: + animation_state = &transform_animation_state_; + break; + default: + NOTREACHED(); + break; + } + bool was_currently_running_animation_for_active_elements = + animation_state->currently_running_for_active_elements; + bool was_currently_running_animation_for_pending_elements = + animation_state->currently_running_for_pending_elements; + bool was_potentially_animating_for_active_elements = + animation_state->potentially_animating_for_active_elements; + bool was_potentially_animating_for_pending_elements = + animation_state->potentially_animating_for_pending_elements; + + animation_state->Clear(); + DCHECK(was_potentially_animating_for_active_elements || + !was_currently_running_animation_for_active_elements); + DCHECK(was_potentially_animating_for_pending_elements || + !was_currently_running_animation_for_pending_elements); + + for (const auto& animation : animations_) { + if (!animation->is_finished() && animation->target_property() == property) { + animation_state->potentially_animating_for_active_elements |= + animation->affects_active_elements(); + animation_state->potentially_animating_for_pending_elements |= + animation->affects_pending_elements(); + animation_state->currently_running_for_active_elements = + animation_state->potentially_animating_for_active_elements && + animation->InEffect(last_tick_time_); + animation_state->currently_running_for_pending_elements = + animation_state->potentially_animating_for_pending_elements && + animation->InEffect(last_tick_time_); + } + } + + bool potentially_animating_changed_for_active_elements = + was_potentially_animating_for_active_elements != + animation_state->potentially_animating_for_active_elements; + bool potentially_animating_changed_for_pending_elements = + was_potentially_animating_for_pending_elements != + animation_state->potentially_animating_for_pending_elements; + bool currently_running_animation_changed_for_active_elements = + was_currently_running_animation_for_active_elements != + animation_state->currently_running_for_active_elements; + bool currently_running_animation_changed_for_pending_elements = + was_currently_running_animation_for_pending_elements != + animation_state->currently_running_for_pending_elements; + if (!potentially_animating_changed_for_active_elements && + !potentially_animating_changed_for_pending_elements && + !currently_running_animation_changed_for_active_elements && + !currently_running_animation_changed_for_pending_elements) + return; + if (has_element_in_active_list()) + NotifyClientAnimationChanged( + property, ElementListType::ACTIVE, + potentially_animating_changed_for_active_elements, + currently_running_animation_changed_for_active_elements); + if (has_element_in_pending_list()) + NotifyClientAnimationChanged( + property, ElementListType::PENDING, + potentially_animating_changed_for_pending_elements, + currently_running_animation_changed_for_pending_elements); +} + +bool ElementAnimations::HasActiveAnimation() const { + for (size_t i = 0; i < animations_.size(); ++i) { + if (!animations_[i]->is_finished()) + return true; + } + return false; +} + +bool ElementAnimations::IsPotentiallyAnimatingProperty( + TargetProperty::Type target_property, + ElementListType list_type) const { + for (size_t i = 0; i < animations_.size(); ++i) { + if (!animations_[i]->is_finished() && + animations_[i]->target_property() == target_property) { + if ((list_type == ElementListType::ACTIVE && + animations_[i]->affects_active_elements()) || + (list_type == ElementListType::PENDING && + animations_[i]->affects_pending_elements())) + return true; + } + } + return false; +} + +bool ElementAnimations::IsCurrentlyAnimatingProperty( + TargetProperty::Type target_property, + ElementListType list_type) const { + for (size_t i = 0; i < animations_.size(); ++i) { + if (!animations_[i]->is_finished() && + animations_[i]->InEffect(last_tick_time_) && + animations_[i]->target_property() == target_property) { + if ((list_type == ElementListType::ACTIVE && + animations_[i]->affects_active_elements()) || + (list_type == ElementListType::PENDING && + animations_[i]->affects_pending_elements())) + return true; + } + } + return false; +} - layer_animation_controller_->PushAnimationUpdatesTo( - element_animations_impl->layer_animation_controller()); +void ElementAnimations::PauseAnimation(int animation_id, + base::TimeDelta time_offset) { + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->id() == animation_id) { + animations_[i]->SetRunState(Animation::PAUSED, + time_offset + animations_[i]->start_time() + + animations_[i]->time_offset()); + } + } +} + +void ElementAnimations::RemoveAnimation(int animation_id) { + bool removed_transform_animation = false; + bool removed_opacity_animation = false; + // Since we want to use the animations that we're going to remove, we need to + // use a stable_parition here instead of remove_if. Remove_if leaves the + // removed items in an unspecified state. + auto animations_to_remove = std::stable_partition( + animations_.begin(), animations_.end(), + [animation_id](const std::unique_ptr<Animation>& animation) { + return animation->id() != animation_id; + }); + for (auto it = animations_to_remove; it != animations_.end(); ++it) { + if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) { + scroll_offset_animation_was_interrupted_ = true; + } else if ((*it)->target_property() == TargetProperty::TRANSFORM && + !(*it)->is_finished()) { + removed_transform_animation = true; + } else if ((*it)->target_property() == TargetProperty::OPACITY && + !(*it)->is_finished()) { + removed_opacity_animation = true; + } + } + + animations_.erase(animations_to_remove, animations_.end()); + UpdateActivation(NORMAL_ACTIVATION); + if (removed_transform_animation) + UpdateClientAnimationState(TargetProperty::TRANSFORM); + if (removed_opacity_animation) + UpdateClientAnimationState(TargetProperty::OPACITY); +} + +void ElementAnimations::AbortAnimation(int animation_id) { + bool aborted_transform_animation = false; + bool aborted_opacity_animation = false; + if (Animation* animation = GetAnimationById(animation_id)) { + if (!animation->is_finished()) { + animation->SetRunState(Animation::ABORTED, last_tick_time_); + if (animation->target_property() == TargetProperty::TRANSFORM) + aborted_transform_animation = true; + else if (animation->target_property() == TargetProperty::OPACITY) + aborted_opacity_animation = true; + } + } + if (aborted_transform_animation) + UpdateClientAnimationState(TargetProperty::TRANSFORM); + if (aborted_opacity_animation) + UpdateClientAnimationState(TargetProperty::OPACITY); +} + +void ElementAnimations::AbortAnimations(TargetProperty::Type target_property, + bool needs_completion) { + if (needs_completion) + DCHECK(target_property == TargetProperty::SCROLL_OFFSET); + + bool aborted_transform_animation = false; + bool aborted_opacity_animation = false; + for (size_t i = 0; i < animations_.size(); ++i) { + if (animations_[i]->target_property() == target_property && + !animations_[i]->is_finished()) { + // Currently only impl-only scroll offset animations can be completed on + // the main thread. + if (needs_completion && animations_[i]->is_impl_only()) { + animations_[i]->SetRunState(Animation::ABORTED_BUT_NEEDS_COMPLETION, + last_tick_time_); + } else { + animations_[i]->SetRunState(Animation::ABORTED, last_tick_time_); + } + if (target_property == TargetProperty::TRANSFORM) + aborted_transform_animation = true; + else if (target_property == TargetProperty::OPACITY) + aborted_opacity_animation = true; + } + } + if (aborted_transform_animation) + UpdateClientAnimationState(TargetProperty::TRANSFORM); + if (aborted_opacity_animation) + UpdateClientAnimationState(TargetProperty::OPACITY); } -void ElementAnimations::SetFilterMutated(LayerTreeType tree_type, +Animation* ElementAnimations::GetAnimation( + TargetProperty::Type target_property) const { + for (size_t i = 0; i < animations_.size(); ++i) { + size_t index = animations_.size() - i - 1; + if (animations_[index]->target_property() == target_property) + return animations_[index].get(); + } + return nullptr; +} + +Animation* ElementAnimations::GetAnimationById(int animation_id) const { + for (size_t i = 0; i < animations_.size(); ++i) + if (animations_[i]->id() == animation_id) + return animations_[i].get(); + return nullptr; +} + +void ElementAnimations::OnFilterAnimated(ElementListType list_type, const FilterOperations& filters) { - DCHECK(layer_id()); + DCHECK(element_id()); DCHECK(animation_host()); DCHECK(animation_host()->mutator_host_client()); - animation_host()->mutator_host_client()->SetLayerFilterMutated( - layer_id(), tree_type, filters); + animation_host()->mutator_host_client()->SetElementFilterMutated( + element_id(), list_type, filters); } -void ElementAnimations::SetOpacityMutated(LayerTreeType tree_type, +void ElementAnimations::OnOpacityAnimated(ElementListType list_type, float opacity) { - DCHECK(layer_id()); + DCHECK(element_id()); DCHECK(animation_host()); DCHECK(animation_host()->mutator_host_client()); - animation_host()->mutator_host_client()->SetLayerOpacityMutated( - layer_id(), tree_type, opacity); + animation_host()->mutator_host_client()->SetElementOpacityMutated( + element_id(), list_type, opacity); } -void ElementAnimations::SetTransformMutated(LayerTreeType tree_type, +void ElementAnimations::OnTransformAnimated(ElementListType list_type, const gfx::Transform& transform) { - DCHECK(layer_id()); + DCHECK(element_id()); DCHECK(animation_host()); DCHECK(animation_host()->mutator_host_client()); - animation_host()->mutator_host_client()->SetLayerTransformMutated( - layer_id(), tree_type, transform); + animation_host()->mutator_host_client()->SetElementTransformMutated( + element_id(), list_type, transform); } -void ElementAnimations::SetScrollOffsetMutated( - LayerTreeType tree_type, +void ElementAnimations::OnScrollOffsetAnimated( + ElementListType list_type, const gfx::ScrollOffset& scroll_offset) { - DCHECK(layer_id()); + DCHECK(element_id()); DCHECK(animation_host()); DCHECK(animation_host()->mutator_host_client()); - animation_host()->mutator_host_client()->SetLayerScrollOffsetMutated( - layer_id(), tree_type, scroll_offset); + animation_host()->mutator_host_client()->SetElementScrollOffsetMutated( + element_id(), list_type, scroll_offset); } -void ElementAnimations::SetTransformIsPotentiallyAnimatingChanged( - LayerTreeType tree_type, - bool is_animating) { - DCHECK(layer_id()); +void ElementAnimations::OnAnimationWaitingForDeletion() { + // TODO(loyso): Invalidate AnimationHost::SetNeedsPushProperties here. + // But we always do PushProperties in AnimationHost for now. crbug.com/604280 DCHECK(animation_host()); - DCHECK(animation_host()->mutator_host_client()); - animation_host() - ->mutator_host_client() - ->LayerTransformIsPotentiallyAnimatingChanged(layer_id(), tree_type, - is_animating); -} - -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()); + animation_host()->OnAnimationWaitingForDeletion(); } -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::IsAnimatingChanged(ElementListType list_type, + TargetProperty::Type property, + AnimationChangeType change_type, + bool is_animating) { + if (!element_id()) + return; + DCHECK(animation_host()); + if (animation_host()->mutator_host_client()) { + switch (property) { + case TargetProperty::OPACITY: + animation_host() + ->mutator_host_client() + ->ElementOpacityIsAnimatingChanged(element_id(), list_type, + change_type, is_animating); + break; + case TargetProperty::TRANSFORM: + animation_host() + ->mutator_host_client() + ->ElementTransformIsAnimatingChanged(element_id(), list_type, + change_type, is_animating); + break; + default: + NOTREACHED(); + break; + } + } } -void ElementAnimations::NotifyAnimationStarted( +void ElementAnimations::NotifyPlayersAnimationStarted( base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) { @@ -248,7 +1388,7 @@ void ElementAnimations::NotifyAnimationStarted( } } -void ElementAnimations::NotifyAnimationFinished( +void ElementAnimations::NotifyPlayersAnimationFinished( base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) { @@ -259,7 +1399,7 @@ void ElementAnimations::NotifyAnimationFinished( } } -void ElementAnimations::NotifyAnimationAborted( +void ElementAnimations::NotifyPlayersAnimationAborted( base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) { @@ -270,15 +1410,15 @@ void ElementAnimations::NotifyAnimationAborted( } } -void ElementAnimations::NotifyAnimationTakeover( +void ElementAnimations::NotifyPlayersAnimationTakeover( base::TimeTicks monotonic_time, TargetProperty::Type target_property, double animation_start_time, - scoped_ptr<AnimationCurve> curve) { + std::unique_ptr<AnimationCurve> curve) { DCHECK(curve); for (PlayersListNode* node = players_list_->head(); node != players_list_->end(); node = node->next()) { - scoped_ptr<AnimationCurve> animation_curve = curve->Clone(); + std::unique_ptr<AnimationCurve> animation_curve = curve->Clone(); AnimationPlayer* player = node->value(); player->NotifyAnimationTakeover(monotonic_time, target_property, animation_start_time, @@ -287,11 +1427,10 @@ void ElementAnimations::NotifyAnimationTakeover( } 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()); + element_id()); } return gfx::ScrollOffset(); diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h index 17dfbd0670e..f8fdcb9169b 100644 --- a/chromium/cc/animation/element_animations.h +++ b/chromium/cc/animation/element_animations.h @@ -5,66 +5,58 @@ #ifndef CC_ANIMATION_ELEMENT_ANIMATIONS_H_ #define CC_ANIMATION_ELEMENT_ANIMATIONS_H_ +#include <bitset> +#include <memory> +#include <vector> + #include "base/containers/linked_list.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" +#include "base/time/time.h" +#include "cc/animation/animation.h" #include "cc/animation/animation_curve.h" -#include "cc/animation/animation_delegate.h" -#include "cc/animation/layer_animation_controller.h" -#include "cc/animation/layer_animation_value_provider.h" +#include "cc/animation/animation_events.h" +#include "cc/animation/target_property.h" #include "cc/base/cc_export.h" +#include "ui/gfx/geometry/scroll_offset.h" +#include "ui/gfx/transform.h" namespace gfx { -class ScrollOffset; -class Transform; +class BoxF; } namespace cc { +class AnimationDelegate; +class AnimationEvents; class AnimationHost; class AnimationPlayer; class FilterOperations; -class LayerAnimationController; -enum class LayerTreeType; +class KeyframeValueList; +enum class ElementListType; +enum class AnimationChangeType; // 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. +// the element. // 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 { +class CC_EXPORT ElementAnimations : public base::RefCounted<ElementAnimations> { public: - static scoped_ptr<ElementAnimations> Create(AnimationHost* host); - ~ElementAnimations() override; + static scoped_refptr<ElementAnimations> Create(); - int layer_id() const { - return layer_animation_controller_ ? layer_animation_controller_->id() : 0; - } + ElementId element_id() const { return element_id_; } + void SetElementId(ElementId element_id); // Parent AnimationHost. AnimationHost* animation_host() { return animation_host_; } const AnimationHost* animation_host() const { return animation_host_; } + void SetAnimationHost(AnimationHost* host); - LayerAnimationController* layer_animation_controller() const { - return layer_animation_controller_.get(); - } - - void CreateLayerAnimationController(int layer_id); - void DestroyLayerAnimationController(); + void InitAffectedElementTypes(); + void ClearAffectedElementTypes(); - 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 ElementRegistered(ElementId element_id, ElementListType list_type); + void ElementUnregistered(ElementId element_id, ElementListType list_type); void AddPlayer(AnimationPlayer* player); void RemovePlayer(AnimationPlayer* player); @@ -74,54 +66,233 @@ class CC_EXPORT ElementAnimations : public AnimationDelegate, typedef base::LinkNode<AnimationPlayer> PlayersListNode; const PlayersList& players_list() const { return *players_list_.get(); } - void PushPropertiesTo(ElementAnimations* element_animations_impl); + // Ensures that the list of active animations on the main thread and the impl + // thread are kept in sync. This function does not take ownership of the impl + // thread ElementAnimations. + void PushPropertiesTo( + scoped_refptr<ElementAnimations> element_animations_impl); + + void AddAnimation(std::unique_ptr<Animation> animation); + void PauseAnimation(int animation_id, base::TimeDelta time_offset); + void RemoveAnimation(int animation_id); + void AbortAnimation(int animation_id); + void AbortAnimations(TargetProperty::Type target_property, + bool needs_completion = false); + + void Animate(base::TimeTicks monotonic_time); + + void UpdateState(bool start_ready_animations, AnimationEvents* events); + + // Make animations affect active elements if and only if they affect + // pending elements. Any animations that no longer affect any elements + // are deleted. + void ActivateAnimations(); + + // Returns the active animation animating the given property that is either + // running, or is next to run, if such an animation exists. + Animation* GetAnimation(TargetProperty::Type target_property) const; + + // Returns the active animation for the given unique animation id. + Animation* GetAnimationById(int animation_id) const; + + // Returns true if there are any animations that have neither finished nor + // aborted. + bool HasActiveAnimation() const; + + // Returns true if there are any animations at all to process. + bool has_any_animation() const { return !animations_.empty(); } + + // Returns true if there is an animation that is either currently animating + // the given property or scheduled to animate this property in the future, and + // that affects the given tree type. + bool IsPotentiallyAnimatingProperty(TargetProperty::Type target_property, + ElementListType list_type) const; + + // Returns true if there is an animation that is currently animating the given + // property and that affects the given tree type. + bool IsCurrentlyAnimatingProperty(TargetProperty::Type target_property, + ElementListType list_type) const; + + void NotifyAnimationStarted(const AnimationEvent& event); + void NotifyAnimationFinished(const AnimationEvent& event); + void NotifyAnimationAborted(const AnimationEvent& event); + void NotifyAnimationPropertyUpdate(const AnimationEvent& event); + void NotifyAnimationTakeover(const AnimationEvent& event); + + bool has_element_in_active_list() const { + return has_element_in_active_list_; + } + bool has_element_in_pending_list() const { + return has_element_in_pending_list_; + } + + void set_has_element_in_active_list(bool has_element_in_active_list) { + has_element_in_active_list_ = has_element_in_active_list; + } + void set_has_element_in_pending_list(bool has_element_in_pending_list) { + has_element_in_pending_list_ = has_element_in_pending_list; + } + + bool HasFilterAnimationThatInflatesBounds() const; + bool HasTransformAnimationThatInflatesBounds() const; + bool HasAnimationThatInflatesBounds() const { + return HasTransformAnimationThatInflatesBounds() || + HasFilterAnimationThatInflatesBounds(); + } + + bool FilterAnimationBoundsForBox(const gfx::BoxF& box, + gfx::BoxF* bounds) const; + bool TransformAnimationBoundsForBox(const gfx::BoxF& box, + gfx::BoxF* bounds) const; + + bool HasAnimationThatAffectsScale() const; + + bool HasOnlyTranslationTransforms(ElementListType list_type) const; + + bool AnimationsPreserveAxisAlignment() const; + + // Sets |start_scale| to the maximum of starting animation scale along any + // dimension at any destination in active animations. Returns false if the + // starting scale cannot be computed. + bool AnimationStartScale(ElementListType list_type, float* start_scale) const; + + // Sets |max_scale| to the maximum scale along any dimension at any + // destination in active animations. Returns false if the maximum scale cannot + // be computed. + bool MaximumTargetScale(ElementListType list_type, float* max_scale) const; + + // When a scroll animation is removed on the main thread, its compositor + // thread counterpart continues producing scroll deltas until activation. + // These scroll deltas need to be cleared at activation, so that the active + // element's scroll offset matches the offset provided by the main thread + // rather than a combination of this offset and scroll deltas produced by + // the removed animation. This is to provide the illusion of synchronicity to + // JS that simultaneously removes an animation and sets the scroll offset. + bool scroll_offset_animation_was_interrupted() const { + return scroll_offset_animation_was_interrupted_; + } + + bool needs_to_start_animations_for_testing() { + return needs_to_start_animations_; + } private: - explicit ElementAnimations(AnimationHost* host); + friend class base::RefCounted<ElementAnimations>; + + ElementAnimations(); + ~ElementAnimations(); + + // A set of target properties. TargetProperty must be 0-based enum. + using TargetProperties = + std::bitset<TargetProperty::LAST_TARGET_PROPERTY + 1>; + + void PushNewAnimationsToImplThread( + ElementAnimations* element_animations_impl) const; + void MarkAbortedAnimationsForDeletion( + ElementAnimations* element_animations_impl) const; + void RemoveAnimationsCompletedOnMainThread( + ElementAnimations* element_animations_impl) const; + void PushPropertiesToImplThread(ElementAnimations* element_animations_impl); + + void StartAnimations(base::TimeTicks monotonic_time); + void PromoteStartedAnimations(base::TimeTicks monotonic_time, + AnimationEvents* events); + void MarkFinishedAnimations(base::TimeTicks monotonic_time); + void MarkAnimationsForDeletion(base::TimeTicks monotonic_time, + AnimationEvents* events); + void PurgeAnimationsMarkedForDeletion(); + + void TickAnimations(base::TimeTicks monotonic_time); + + enum UpdateActivationType { NORMAL_ACTIVATION, FORCE_ACTIVATION }; + void UpdateActivation(UpdateActivationType type); - void SetFilterMutated(LayerTreeType tree_type, + void NotifyClientOpacityAnimated(float opacity, + bool notify_active_elements, + bool notify_pending_elements); + void NotifyClientTransformAnimated(const gfx::Transform& transform, + bool notify_active_elements, + bool notify_pending_elements); + void NotifyClientFilterAnimated(const FilterOperations& filter, + bool notify_active_elements, + bool notify_pending_elements); + void NotifyClientScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset, + bool notify_active_elements, + bool notify_pending_elements); + + void NotifyClientAnimationWaitingForDeletion(); + + void NotifyClientAnimationChanged( + TargetProperty::Type property, + ElementListType list_type, + bool notify_elements_about_potential_animation, + bool notify_elements_about_running_animation); + + void UpdateClientAnimationState(TargetProperty::Type property); + + void OnFilterAnimated(ElementListType list_type, const FilterOperations& filters); - void SetOpacityMutated(LayerTreeType tree_type, float opacity); - void SetTransformMutated(LayerTreeType tree_type, + void OnOpacityAnimated(ElementListType list_type, float opacity); + void OnTransformAnimated(ElementListType list_type, const gfx::Transform& transform); - void SetScrollOffsetMutated(LayerTreeType tree_type, + void OnScrollOffsetAnimated(ElementListType list_type, const gfx::ScrollOffset& scroll_offset); - void SetTransformIsPotentiallyAnimatingChanged(LayerTreeType tree_type, - bool is_animating); - - void CreateActiveValueObserver(); - void DestroyActiveValueObserver(); - - void CreatePendingValueObserver(); - void DestroyPendingValueObserver(); - - // AnimationDelegate implementation - void NotifyAnimationStarted(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override; - void NotifyAnimationFinished(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override; - void NotifyAnimationAborted(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override; - void NotifyAnimationTakeover(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - double animation_start_time, - scoped_ptr<AnimationCurve> curve) 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_; + void OnAnimationWaitingForDeletion(); + void IsAnimatingChanged(ElementListType list_type, + TargetProperty::Type property, + AnimationChangeType change_type, + bool is_animating); + gfx::ScrollOffset ScrollOffsetForAnimation() const; + + void NotifyPlayersAnimationStarted(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + int group); + void NotifyPlayersAnimationFinished(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + int group); + void NotifyPlayersAnimationAborted(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + int group); + void NotifyPlayersAnimationPropertyUpdate(const AnimationEvent& event); + void NotifyPlayersAnimationTakeover(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + double animation_start_time, + std::unique_ptr<AnimationCurve> curve); + + std::unique_ptr<PlayersList> players_list_; AnimationHost* animation_host_; + ElementId element_id_; + std::vector<std::unique_ptr<Animation>> animations_; + + // This is used to ensure that we don't spam the animation host. + bool is_active_; + + base::TimeTicks last_tick_time_; + + bool has_element_in_active_list_; + bool has_element_in_pending_list_; + + // Only try to start animations when new animations are added or when the + // previous attempt at starting animations failed to start all animations. + bool needs_to_start_animations_; + + bool scroll_offset_animation_was_interrupted_; + + struct PropertyAnimationState { + bool currently_running_for_active_elements = false; + bool currently_running_for_pending_elements = false; + bool potentially_animating_for_active_elements = false; + bool potentially_animating_for_pending_elements = false; + void Clear() { + currently_running_for_active_elements = false; + currently_running_for_pending_elements = false; + potentially_animating_for_active_elements = false; + potentially_animating_for_pending_elements = false; + } + }; + + struct PropertyAnimationState opacity_animation_state_; + struct PropertyAnimationState transform_animation_state_; DISALLOW_COPY_AND_ASSIGN(ElementAnimations); }; diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc index b676906c3c8..c4e98da87db 100644 --- a/chromium/cc/animation/element_animations_unittest.cc +++ b/chromium/cc/animation/element_animations_unittest.cc @@ -8,14 +8,30 @@ #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/animation/keyframed_animation_curve.h" +#include "cc/animation/scroll_offset_animation_curve.h" +#include "cc/animation/transform_operations.h" #include "cc/test/animation_test_common.h" #include "cc/test/animation_timelines_test_common.h" +#include "ui/gfx/geometry/box_f.h" namespace cc { namespace { +using base::TimeDelta; +using base::TimeTicks; + +static base::TimeTicks TicksFromSecondsF(double seconds) { + return base::TimeTicks::FromInternalValue(seconds * + base::Time::kMicrosecondsPerSecond); +} + +// An ElementAnimations cannot be ticked at 0.0, since an animation +// with start time 0.0 is treated as an animation whose start time has +// not yet been set. +const TimeTicks kInitialTickTime = TicksFromSecondsF(1.0); + class ElementAnimationsTest : public AnimationTimelinesTest { public: ElementAnimationsTest() {} @@ -27,82 +43,76 @@ class ElementAnimationsTest : public AnimationTimelinesTest { 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); + client_.RegisterElement(element_id_, ElementListType::ACTIVE); + client_impl_.RegisterElement(element_id_, ElementListType::PENDING); - EXPECT_TRUE(client_.IsLayerInTree(layer_id_, LayerTreeType::ACTIVE)); - EXPECT_FALSE(client_.IsLayerInTree(layer_id_, LayerTreeType::PENDING)); + EXPECT_TRUE(client_.IsElementInList(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.IsElementInList(element_id_, ElementListType::PENDING)); host_->AddAnimationTimeline(timeline_); timeline_->AttachPlayer(player_); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_id_); - ElementAnimations* element_animations = player_->element_animations(); + scoped_refptr<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()); + EXPECT_TRUE(element_animations->has_element_in_active_list()); + EXPECT_FALSE(element_animations->has_element_in_pending_list()); host_->PushPropertiesTo(host_impl_); GetImplTimelineAndPlayerByID(); - ElementAnimations* element_animations_impl = + scoped_refptr<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()); + EXPECT_FALSE(element_animations_impl->has_element_in_active_list()); + EXPECT_TRUE(element_animations_impl->has_element_in_pending_list()); // 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()); + client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE); + EXPECT_TRUE(element_animations_impl->has_element_in_active_list()); + EXPECT_TRUE(element_animations_impl->has_element_in_pending_list()); - EXPECT_TRUE(client_impl_.IsLayerInTree(layer_id_, LayerTreeType::ACTIVE)); - EXPECT_TRUE(client_impl_.IsLayerInTree(layer_id_, LayerTreeType::PENDING)); + EXPECT_TRUE( + client_impl_.IsElementInList(element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE( + client_impl_.IsElementInList(element_id_, ElementListType::PENDING)); // kill layer on main thread. - client_.UnregisterLayer(layer_id_, LayerTreeType::ACTIVE); + client_.UnregisterElement(element_id_, ElementListType::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()); + EXPECT_FALSE(element_animations->has_element_in_active_list()); + EXPECT_FALSE(element_animations->has_element_in_pending_list()); // 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()); + EXPECT_TRUE(element_animations_impl->has_element_in_active_list()); + EXPECT_TRUE(element_animations_impl->has_element_in_pending_list()); // Kill layer on impl thread in pending tree. - client_impl_.UnregisterLayer(layer_id_, LayerTreeType::PENDING); + client_impl_.UnregisterElement(element_id_, ElementListType::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()); + EXPECT_TRUE(element_animations_impl->has_element_in_active_list()); + EXPECT_FALSE(element_animations_impl->has_element_in_pending_list()); // Kill layer on impl thread in active tree. - client_impl_.UnregisterLayer(layer_id_, LayerTreeType::ACTIVE); + client_impl_.UnregisterElement(element_id_, ElementListType::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()); + EXPECT_FALSE(element_animations_impl->has_element_in_active_list()); + EXPECT_FALSE(element_animations_impl->has_element_in_pending_list()); // 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()); + EXPECT_FALSE(element_animations_impl->has_element_in_active_list()); + EXPECT_FALSE(element_animations_impl->has_element_in_pending_list()); - player_->DetachLayer(); + player_->DetachElement(); EXPECT_FALSE(player_->element_animations()); // Release ptrs now to test the order of destruction. @@ -117,48 +127,45 @@ TEST_F(ElementAnimationsTest, AttachToNotYetCreatedLayer) { GetImplTimelineAndPlayerByID(); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_id_); - ElementAnimations* element_animations = player_->element_animations(); + scoped_refptr<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()); + EXPECT_FALSE(element_animations->has_element_in_active_list()); + EXPECT_FALSE(element_animations->has_element_in_pending_list()); host_->PushPropertiesTo(host_impl_); - ElementAnimations* element_animations_impl = + scoped_refptr<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()); + EXPECT_FALSE(element_animations_impl->has_element_in_active_list()); + EXPECT_FALSE(element_animations_impl->has_element_in_pending_list()); // 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_.RegisterElement(element_id_, ElementListType::ACTIVE); + EXPECT_TRUE(element_animations->has_element_in_active_list()); + EXPECT_FALSE(element_animations->has_element_in_pending_list()); - 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_.RegisterElement(element_id_, ElementListType::PENDING); + EXPECT_FALSE(element_animations_impl->has_element_in_active_list()); + EXPECT_TRUE(element_animations_impl->has_element_in_pending_list()); - 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()); + client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE); + EXPECT_TRUE(element_animations_impl->has_element_in_active_list()); + EXPECT_TRUE(element_animations_impl->has_element_in_pending_list()); } TEST_F(ElementAnimationsTest, AddRemovePlayers) { host_->AddAnimationTimeline(timeline_); timeline_->AttachPlayer(player_); - player_->AttachLayer(layer_id_); + player_->AttachElement(element_id_); - ElementAnimations* element_animations = player_->element_animations(); + scoped_refptr<ElementAnimations> element_animations = + player_->element_animations(); EXPECT_TRUE(element_animations); scoped_refptr<AnimationPlayer> player1 = @@ -170,8 +177,8 @@ TEST_F(ElementAnimationsTest, AddRemovePlayers) { timeline_->AttachPlayer(player2); // Attach players to the same layer. - player1->AttachLayer(layer_id_); - player2->AttachLayer(layer_id_); + player1->AttachElement(element_id_); + player2->AttachElement(element_id_); EXPECT_EQ(element_animations, player1->element_animations()); EXPECT_EQ(element_animations, player2->element_animations()); @@ -179,7 +186,7 @@ TEST_F(ElementAnimationsTest, AddRemovePlayers) { host_->PushPropertiesTo(host_impl_); GetImplTimelineAndPlayerByID(); - ElementAnimations* element_animations_impl = + scoped_refptr<ElementAnimations> element_animations_impl = player_impl_->element_animations(); EXPECT_TRUE(element_animations_impl); @@ -194,7 +201,7 @@ TEST_F(ElementAnimationsTest, AddRemovePlayers) { } EXPECT_EQ(3, list_size_before); - player2->DetachLayer(); + player2->DetachElement(); EXPECT_FALSE(player2->element_animations()); EXPECT_EQ(element_animations, player_->element_animations()); EXPECT_EQ(element_animations, player1->element_animations()); @@ -214,5 +221,3178 @@ TEST_F(ElementAnimationsTest, AddRemovePlayers) { EXPECT_EQ(2, list_size_after); } +TEST_F(ElementAnimationsTest, SyncNewAnimation) { + auto animations_impl = ElementAnimations::Create(); + animations_impl->set_has_element_in_active_list(true); + + auto animations = ElementAnimations::Create(); + animations->set_has_element_in_active_list(true); + + EXPECT_FALSE(animations_impl->GetAnimation(TargetProperty::OPACITY)); + + EXPECT_FALSE(animations->needs_to_start_animations_for_testing()); + EXPECT_FALSE(animations_impl->needs_to_start_animations_for_testing()); + + int animation_id = + AddOpacityTransitionToElementAnimations(animations.get(), 1, 0, 1, false); + EXPECT_TRUE(animations->needs_to_start_animations_for_testing()); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(animations_impl->needs_to_start_animations_for_testing()); + animations_impl->ActivateAnimations(); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); +} + +TEST_F(ElementAnimationsTest, + SyncScrollOffsetAnimationRespectsHasSetInitialValue) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + EXPECT_FALSE(animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET)); + + EXPECT_FALSE(animations->needs_to_start_animations_for_testing()); + EXPECT_FALSE(animations_impl->needs_to_start_animations_for_testing()); + + gfx::ScrollOffset initial_value(100.f, 300.f); + gfx::ScrollOffset provider_initial_value(150.f, 300.f); + gfx::ScrollOffset target_value(300.f, 200.f); + + client_impl_.SetScrollOffsetForAnimation(provider_initial_value); + + // Animation with initial value set. + std::unique_ptr<ScrollOffsetAnimationCurve> curve_fixed( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + curve_fixed->SetInitialValue(initial_value); + const int animation1_id = 1; + std::unique_ptr<Animation> animation_fixed(Animation::Create( + std::move(curve_fixed), animation1_id, 0, TargetProperty::SCROLL_OFFSET)); + animations->AddAnimation(std::move(animation_fixed)); + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_VECTOR2DF_EQ(initial_value, + animations_impl->GetAnimationById(animation1_id) + ->curve() + ->ToScrollOffsetAnimationCurve() + ->GetValue(base::TimeDelta())); + + // Animation without initial value set. + std::unique_ptr<ScrollOffsetAnimationCurve> curve( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + const int animation2_id = 2; + std::unique_ptr<Animation> animation(Animation::Create( + std::move(curve), animation2_id, 0, TargetProperty::SCROLL_OFFSET)); + animations->AddAnimation(std::move(animation)); + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_VECTOR2DF_EQ(provider_initial_value, + animations_impl->GetAnimationById(animation2_id) + ->curve() + ->ToScrollOffsetAnimationCurve() + ->GetValue(base::TimeDelta())); +} + +// If an animation is started on the impl thread before it is ticked on the main +// thread, we must be sure to respect the synchronized start time. +TEST_F(ElementAnimationsTest, DoNotClobberStartTimes) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + EXPECT_FALSE(animations_impl->GetAnimation(TargetProperty::OPACITY)); + + int animation_id = + AddOpacityTransitionToElementAnimations(animations.get(), 1, 0, 1, false); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); + + auto events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + // Synchronize the start times. + EXPECT_EQ(1u, events->events_.size()); + animations->NotifyAnimationStarted(events->events_[0]); + EXPECT_EQ(animations->GetAnimationById(animation_id)->start_time(), + animations_impl->GetAnimationById(animation_id)->start_time()); + + // Start the animation on the main thread. Should not affect the start time. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations->UpdateState(true, nullptr); + EXPECT_EQ(animations->GetAnimationById(animation_id)->start_time(), + animations_impl->GetAnimationById(animation_id)->start_time()); +} + +TEST_F(ElementAnimationsTest, UseSpecifiedStartTimes) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + int animation_id = + AddOpacityTransitionToElementAnimations(animations.get(), 1, 0, 1, false); + + const TimeTicks start_time = TicksFromSecondsF(123); + animations->GetAnimation(TargetProperty::OPACITY)->set_start_time(start_time); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); + + auto events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + // Synchronize the start times. + EXPECT_EQ(1u, events->events_.size()); + animations->NotifyAnimationStarted(events->events_[0]); + + EXPECT_EQ(start_time, + animations->GetAnimationById(animation_id)->start_time()); + EXPECT_EQ(animations->GetAnimationById(animation_id)->start_time(), + animations_impl->GetAnimationById(animation_id)->start_time()); + + // Start the animation on the main thread. Should not affect the start time. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations->UpdateState(true, nullptr); + EXPECT_EQ(start_time, + animations->GetAnimationById(animation_id)->start_time()); + EXPECT_EQ(animations->GetAnimationById(animation_id)->start_time(), + animations_impl->GetAnimationById(animation_id)->start_time()); +} + +// Tests that animationss activate and deactivate as expected. +TEST_F(ElementAnimationsTest, Activation) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + AnimationHost* host = client_.host(); + AnimationHost* host_impl = client_impl_.host(); + + auto events = host_impl_->CreateEvents(); + + EXPECT_EQ(1u, host->all_element_animations_for_testing().size()); + EXPECT_EQ(1u, host_impl->all_element_animations_for_testing().size()); + + // Initially, both animationss should be inactive. + EXPECT_EQ(0u, host->active_element_animations_for_testing().size()); + EXPECT_EQ(0u, host_impl->active_element_animations_for_testing().size()); + + AddOpacityTransitionToElementAnimations(animations.get(), 1, 0, 1, false); + // The main thread animations should now be active. + EXPECT_EQ(1u, host->active_element_animations_for_testing().size()); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + // Both animationss should now be active. + EXPECT_EQ(1u, host->active_element_animations_for_testing().size()); + EXPECT_EQ(1u, host_impl->active_element_animations_for_testing().size()); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + EXPECT_EQ(1u, events->events_.size()); + animations->NotifyAnimationStarted(events->events_[0]); + + EXPECT_EQ(1u, host->active_element_animations_for_testing().size()); + EXPECT_EQ(1u, host_impl->active_element_animations_for_testing().size()); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations->UpdateState(true, nullptr); + EXPECT_EQ(1u, host->active_element_animations_for_testing().size()); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, nullptr); + EXPECT_EQ(Animation::FINISHED, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + EXPECT_EQ(1u, host->active_element_animations_for_testing().size()); + + events = host_impl_->CreateEvents(); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1500)); + animations_impl->UpdateState(true, events.get()); + + EXPECT_EQ( + Animation::WAITING_FOR_DELETION, + animations_impl->GetAnimation(TargetProperty::OPACITY)->run_state()); + // The impl thread animations should have de-activated. + EXPECT_EQ(0u, host_impl->active_element_animations_for_testing().size()); + + EXPECT_EQ(1u, events->events_.size()); + animations->NotifyAnimationFinished(events->events_[0]); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1500)); + animations->UpdateState(true, nullptr); + + EXPECT_EQ(Animation::WAITING_FOR_DELETION, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + // The main thread animations should have de-activated. + EXPECT_EQ(0u, host->active_element_animations_for_testing().size()); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->has_any_animation()); + EXPECT_FALSE(animations_impl->has_any_animation()); + EXPECT_EQ(0u, host->active_element_animations_for_testing().size()); + EXPECT_EQ(0u, host_impl->active_element_animations_for_testing().size()); +} + +TEST_F(ElementAnimationsTest, SyncPause) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + EXPECT_FALSE(animations_impl->GetAnimation(TargetProperty::OPACITY)); + + // Two steps, three ranges: [0-1) -> 0.2, [1-2) -> 0.3, [2-3] -> 0.4. + const double duration = 3.0; + const int animation_id = AddOpacityStepsToElementAnimations( + animations.get(), duration, 0.2f, 0.4f, 2); + + // Set start offset to be at the beginning of the second range. + animations->GetAnimationById(animation_id) + ->set_time_offset(TimeDelta::FromSecondsD(1.01)); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); + + TimeTicks time = kInitialTickTime; + + // Start the animations on each animations. + auto events = host_impl_->CreateEvents(); + animations_impl->Animate(time); + animations_impl->UpdateState(true, events.get()); + EXPECT_EQ(1u, events->events_.size()); + + animations->Animate(time); + animations->UpdateState(true, nullptr); + animations->NotifyAnimationStarted(events->events_[0]); + + EXPECT_EQ(Animation::RUNNING, + animations_impl->GetAnimationById(animation_id)->run_state()); + EXPECT_EQ(Animation::RUNNING, + animations->GetAnimationById(animation_id)->run_state()); + + EXPECT_EQ(0.3f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_EQ(0.3f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + EXPECT_EQ(kInitialTickTime, + animations->GetAnimationById(animation_id)->start_time()); + EXPECT_EQ(kInitialTickTime, + animations_impl->GetAnimationById(animation_id)->start_time()); + + // Pause the animation at the middle of the second range so the offset + // delays animation until the middle of the third range. + animations->PauseAnimation(animation_id, TimeDelta::FromSecondsD(1.5)); + EXPECT_EQ(Animation::PAUSED, + animations->GetAnimationById(animation_id)->run_state()); + + // The pause run state change should make it to the impl thread animations. + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + // Advance time so it stays within the first range. + time += TimeDelta::FromMilliseconds(10); + animations->Animate(time); + animations_impl->Animate(time); + + EXPECT_EQ(Animation::PAUSED, + animations_impl->GetAnimationById(animation_id)->run_state()); + + // Opacity value doesn't depend on time if paused at specified time offset. + EXPECT_EQ(0.4f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_EQ(0.4f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, DoNotSyncFinishedAnimation) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + EXPECT_FALSE(animations_impl->GetAnimation(TargetProperty::OPACITY)); + + int animation_id = + AddOpacityTransitionToElementAnimations(animations.get(), 1, 0, 1, false); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); + + events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + EXPECT_EQ(1u, events->events_.size()); + EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); + + // Notify main thread animations that the animation has started. + animations->NotifyAnimationStarted(events->events_[0]); + + // Complete animation on impl thread. + events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime + TimeDelta::FromSeconds(1)); + animations_impl->UpdateState(true, events.get()); + EXPECT_EQ(1u, events->events_.size()); + EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); + + animations->NotifyAnimationFinished(events->events_[0]); + + animations->Animate(kInitialTickTime + TimeDelta::FromSeconds(2)); + animations->UpdateState(true, nullptr); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->GetAnimationById(animation_id)); + EXPECT_FALSE(animations_impl->GetAnimationById(animation_id)); +} + +// Ensure that a finished animation is eventually deleted by both the +// main-thread and the impl-thread animationss. +TEST_F(ElementAnimationsTest, AnimationsAreDeleted) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + AddOpacityTransitionToElementAnimations(animations.get(), 1.0, 0.0f, 1.0f, + false); + animations->Animate(kInitialTickTime); + animations->UpdateState(true, nullptr); + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + animations_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations_impl->UpdateState(true, events.get()); + + // There should be a STARTED event for the animation. + EXPECT_EQ(1u, events->events_.size()); + EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); + animations->NotifyAnimationStarted(events->events_[0]); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, nullptr); + + EXPECT_FALSE(host_->animation_waiting_for_deletion()); + EXPECT_FALSE(host_impl_->animation_waiting_for_deletion()); + + events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(2000)); + animations_impl->UpdateState(true, events.get()); + + EXPECT_TRUE(host_impl_->animation_waiting_for_deletion()); + + // There should be a FINISHED event for the animation. + EXPECT_EQ(1u, events->events_.size()); + EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); + + // Neither animations should have deleted the animation yet. + EXPECT_TRUE(animations->GetAnimation(TargetProperty::OPACITY)); + EXPECT_TRUE(animations_impl->GetAnimation(TargetProperty::OPACITY)); + + animations->NotifyAnimationFinished(events->events_[0]); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); + animations->UpdateState(true, nullptr); + EXPECT_TRUE(host_->animation_waiting_for_deletion()); + + animations->PushPropertiesTo(animations_impl.get()); + + // Both animationss should now have deleted the animation. The impl animations + // should have deleted the animation even though activation has not occurred, + // since the animation was already waiting for deletion when + // PushPropertiesTo was called. + EXPECT_FALSE(animations->has_any_animation()); + EXPECT_FALSE(animations_impl->has_any_animation()); +} + +// Tests that transitioning opacity from 0 to 1 works as expected. + +static std::unique_ptr<Animation> CreateAnimation( + std::unique_ptr<AnimationCurve> curve, + int group_id, + TargetProperty::Type property) { + return Animation::Create(std::move(curve), 0, group_id, property); +} + +static const AnimationEvent* GetMostRecentPropertyUpdateEvent( + const AnimationEvents* events) { + const AnimationEvent* event = 0; + for (size_t i = 0; i < events->events_.size(); ++i) + if (events->events_[i].type == AnimationEvent::PROPERTY_UPDATE) + event = &events->events_[i]; + + return event; +} + +TEST_F(ElementAnimationsTest, TrivialTransition) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + std::unique_ptr<Animation> to_add(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + + EXPECT_FALSE(animations->needs_to_start_animations_for_testing()); + animations->AddAnimation(std::move(to_add)); + EXPECT_TRUE(animations->needs_to_start_animations_for_testing()); + animations->Animate(kInitialTickTime); + EXPECT_FALSE(animations->needs_to_start_animations_for_testing()); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + // A non-impl-only animation should not generate property updates. + const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); +} + +TEST_F(ElementAnimationsTest, FilterTransition) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + std::unique_ptr<KeyframedFilterAnimationCurve> curve( + KeyframedFilterAnimationCurve::Create()); + + FilterOperations start_filters; + start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f)); + curve->AddKeyframe( + FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); + FilterOperations end_filters; + end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f)); + curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), + end_filters, nullptr)); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve), 1, 0, TargetProperty::FILTER)); + animations->AddAnimation(std::move(animation)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(start_filters, + client_.GetFilters(element_id_, ElementListType::ACTIVE)); + // A non-impl-only animation should not generate property updates. + const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(1u, + client_.GetFilters(element_id_, ElementListType::ACTIVE).size()); + EXPECT_EQ(FilterOperation::CreateBrightnessFilter(1.5f), + client_.GetFilters(element_id_, ElementListType::ACTIVE).at(0)); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(end_filters, + client_.GetFilters(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); +} + +TEST_F(ElementAnimationsTest, ScrollOffsetTransition) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + gfx::ScrollOffset initial_value(100.f, 300.f); + gfx::ScrollOffset target_value(300.f, 200.f); + std::unique_ptr<ScrollOffsetAnimationCurve> curve( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); + animation->set_needs_synchronized_start_time(true); + animations->AddAnimation(std::move(animation)); + + client_impl_.SetScrollOffsetForAnimation(initial_value); + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET)); + TimeDelta duration = + animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) + ->curve() + ->Duration(); + EXPECT_EQ(duration, animations->GetAnimation(TargetProperty::SCROLL_OFFSET) + ->curve() + ->Duration()); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, nullptr); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(initial_value, + client_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + EXPECT_TRUE(animations_impl->HasActiveAnimation()); + EXPECT_EQ(initial_value, + client_impl_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + // Scroll offset animations should not generate property updates. + const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations->NotifyAnimationStarted(events->events_[0]); + animations->Animate(kInitialTickTime + duration / 2); + animations->UpdateState(true, nullptr); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(200.f, 250.f), + client_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + duration / 2); + animations_impl->UpdateState(true, events.get()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(200.f, 250.f), + client_impl_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations_impl->Animate(kInitialTickTime + duration); + animations_impl->UpdateState(true, events.get()); + EXPECT_VECTOR2DF_EQ(target_value, client_impl_.GetScrollOffset( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations_impl->HasActiveAnimation()); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations->Animate(kInitialTickTime + duration); + animations->UpdateState(true, nullptr); + EXPECT_VECTOR2DF_EQ(target_value, client_.GetScrollOffset( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +TEST_F(ElementAnimationsTest, ScrollOffsetTransitionOnImplOnly) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + gfx::ScrollOffset initial_value(100.f, 300.f); + gfx::ScrollOffset target_value(300.f, 200.f); + std::unique_ptr<ScrollOffsetAnimationCurve> curve( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + curve->SetInitialValue(initial_value); + double duration_in_seconds = curve->Duration().InSecondsF(); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); + animation->set_is_impl_only(true); + animations_impl->AddAnimation(std::move(animation)); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + EXPECT_TRUE(animations_impl->HasActiveAnimation()); + EXPECT_EQ(initial_value, + client_impl_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + // Scroll offset animations should not generate property updates. + const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + TimeDelta duration = TimeDelta::FromMicroseconds( + duration_in_seconds * base::Time::kMicrosecondsPerSecond); + + animations_impl->Animate(kInitialTickTime + duration / 2); + animations_impl->UpdateState(true, events.get()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(200.f, 250.f), + client_impl_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations_impl->Animate(kInitialTickTime + duration); + animations_impl->UpdateState(true, events.get()); + EXPECT_VECTOR2DF_EQ(target_value, client_impl_.GetScrollOffset( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations_impl->HasActiveAnimation()); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); +} + +// Ensure that when the impl animations doesn't have a value provider, +// the main-thread animations's value provider is used to obtain the intial +// scroll offset. +TEST_F(ElementAnimationsTest, ScrollOffsetTransitionNoImplProvider) { + CreateTestLayer(false, false); + CreateTestImplLayer(ElementListType::PENDING); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + EXPECT_TRUE(animations_impl->has_element_in_pending_list()); + EXPECT_FALSE(animations_impl->has_element_in_active_list()); + + auto events = host_impl_->CreateEvents(); + + gfx::ScrollOffset initial_value(500.f, 100.f); + gfx::ScrollOffset target_value(300.f, 200.f); + std::unique_ptr<ScrollOffsetAnimationCurve> curve( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); + animation->set_needs_synchronized_start_time(true); + animations->AddAnimation(std::move(animation)); + + client_.SetScrollOffsetForAnimation(initial_value); + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET)); + TimeDelta duration = + animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) + ->curve() + ->Duration(); + EXPECT_EQ(duration, animations->GetAnimation(TargetProperty::SCROLL_OFFSET) + ->curve() + ->Duration()); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, nullptr); + + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(initial_value, + client_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + EXPECT_EQ(gfx::ScrollOffset(), client_impl_.GetScrollOffset( + element_id_, ElementListType::PENDING)); + + animations_impl->Animate(kInitialTickTime); + + EXPECT_TRUE(animations_impl->HasActiveAnimation()); + EXPECT_EQ(initial_value, client_impl_.GetScrollOffset( + element_id_, ElementListType::PENDING)); + + CreateTestImplLayer(ElementListType::ACTIVE); + + animations_impl->UpdateState(true, events.get()); + DCHECK_EQ(1UL, events->events_.size()); + + // Scroll offset animations should not generate property updates. + const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations->NotifyAnimationStarted(events->events_[0]); + animations->Animate(kInitialTickTime + duration / 2); + animations->UpdateState(true, nullptr); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(400.f, 150.f), + client_.GetScrollOffset(element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + duration / 2); + animations_impl->UpdateState(true, events.get()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(400.f, 150.f), + client_impl_.GetScrollOffset(element_id_, ElementListType::PENDING)); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations_impl->Animate(kInitialTickTime + duration); + animations_impl->UpdateState(true, events.get()); + EXPECT_VECTOR2DF_EQ(target_value, client_impl_.GetScrollOffset( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(animations_impl->HasActiveAnimation()); + event = GetMostRecentPropertyUpdateEvent(events.get()); + EXPECT_FALSE(event); + + animations->Animate(kInitialTickTime + duration); + animations->UpdateState(true, nullptr); + EXPECT_VECTOR2DF_EQ(target_value, client_.GetScrollOffset( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +TEST_F(ElementAnimationsTest, ScrollOffsetRemovalClearsScrollDelta) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + // First test the 1-argument version of RemoveAnimation. + gfx::ScrollOffset target_value(300.f, 200.f); + std::unique_ptr<ScrollOffsetAnimationCurve> curve( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + + int animation_id = 1; + std::unique_ptr<Animation> animation(Animation::Create( + std::move(curve), animation_id, 0, TargetProperty::SCROLL_OFFSET)); + animation->set_needs_synchronized_start_time(true); + animations->AddAnimation(std::move(animation)); + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + + animations->RemoveAnimation(animation_id); + EXPECT_TRUE(animations->scroll_offset_animation_was_interrupted()); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(animations_impl->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + + // Now, test the 2-argument version of RemoveAnimation. + curve = ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create()); + animation = Animation::Create(std::move(curve), animation_id, 0, + TargetProperty::SCROLL_OFFSET); + animation->set_needs_synchronized_start_time(true); + animations->AddAnimation(std::move(animation)); + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + + animations->RemoveAnimation(animation_id); + EXPECT_TRUE(animations->scroll_offset_animation_was_interrupted()); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(animations_impl->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + + // Check that removing non-scroll-offset animations does not cause + // scroll_offset_animation_was_interrupted() to get set. + animation_id = + AddAnimatedTransformToElementAnimations(animations.get(), 1.0, 1, 2); + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + + animations->RemoveAnimation(animation_id); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + + animation_id = + AddAnimatedFilterToElementAnimations(animations.get(), 1.0, 0.1f, 0.2f); + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + + animations->RemoveAnimation(animation_id); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); + EXPECT_FALSE(animations->scroll_offset_animation_was_interrupted()); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations_impl->scroll_offset_animation_was_interrupted()); +} + +// Tests that impl-only animations lead to start and finished notifications +// on the impl thread animations's animation delegate. +TEST_F(ElementAnimationsTest, + NotificationsForImplOnlyAnimationsAreSentToImplThreadDelegate) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + TestAnimationDelegate delegate; + player_impl_->set_animation_delegate(&delegate); + + gfx::ScrollOffset initial_value(100.f, 300.f); + gfx::ScrollOffset target_value(300.f, 200.f); + std::unique_ptr<ScrollOffsetAnimationCurve> curve( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + curve->SetInitialValue(initial_value); + TimeDelta duration = curve->Duration(); + std::unique_ptr<Animation> to_add( + Animation::Create(std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); + to_add->set_is_impl_only(true); + animations_impl->AddAnimation(std::move(to_add)); + + EXPECT_FALSE(delegate.started()); + EXPECT_FALSE(delegate.finished()); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + EXPECT_TRUE(delegate.started()); + EXPECT_FALSE(delegate.finished()); + + events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime + duration); + EXPECT_EQ(duration, + animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) + ->curve() + ->Duration()); + animations_impl->UpdateState(true, events.get()); + + EXPECT_TRUE(delegate.started()); + EXPECT_TRUE(delegate.finished()); +} + +// Tests that specified start times are sent to the main thread delegate +TEST_F(ElementAnimationsTest, SpecifiedStartTimesAreSentToMainThreadDelegate) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + TestAnimationDelegate delegate; + player_->set_animation_delegate(&delegate); + + int animation_id = + AddOpacityTransitionToElementAnimations(animations.get(), 1, 0, 1, false); + + const TimeTicks start_time = TicksFromSecondsF(123); + animations->GetAnimation(TargetProperty::OPACITY)->set_start_time(start_time); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); + + auto events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + // Synchronize the start times. + EXPECT_EQ(1u, events->events_.size()); + animations->NotifyAnimationStarted(events->events_[0]); + + // Validate start time on the main thread delegate. + EXPECT_EQ(start_time, delegate.start_time()); +} + +// Tests animations that are waiting for a synchronized start time do not +// finish. +TEST_F(ElementAnimationsTest, + AnimationsWaitingForStartTimeDoNotFinishIfTheyOutwaitTheirFinish) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + std::unique_ptr<Animation> to_add(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + to_add->set_needs_synchronized_start_time(true); + + // We should pause at the first keyframe indefinitely waiting for that + // animation to start. + animations->AddAnimation(std::move(to_add)); + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + // Send the synchronized start time. + animations->NotifyAnimationStarted( + AnimationEvent(AnimationEvent::STARTED, 0, 1, TargetProperty::OPACITY, + kInitialTickTime + TimeDelta::FromMilliseconds(2000))); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(5000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +// Tests that two queued animations affecting the same property run in sequence. +TEST_F(ElementAnimationsTest, TrivialQueuing) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + EXPECT_FALSE(animations->needs_to_start_animations_for_testing()); + + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.5f)), + 2, TargetProperty::OPACITY)); + + EXPECT_TRUE(animations->needs_to_start_animations_for_testing()); + + animations->Animate(kInitialTickTime); + + // The second animation still needs to be started. + EXPECT_TRUE(animations->needs_to_start_animations_for_testing()); + + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + EXPECT_TRUE(animations->needs_to_start_animations_for_testing()); + animations->UpdateState(true, events.get()); + EXPECT_FALSE(animations->needs_to_start_animations_for_testing()); + + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(0.5f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +// Tests interrupting a transition with another transition. +TEST_F(ElementAnimationsTest, Interrupt) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + std::unique_ptr<Animation> to_add(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.5f)), + 2, TargetProperty::OPACITY)); + animations->AbortAnimations(TargetProperty::OPACITY); + animations->AddAnimation(std::move(to_add)); + + // Since the previous animation was aborted, the new animation should start + // right in this call to animate. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1500)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(0.5f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +// Tests scheduling two animations to run together when only one property is +// free. +TEST_F(ElementAnimationsTest, ScheduleTogetherWhenAPropertyIsBlocked) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, + TargetProperty::TRANSFORM)); + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1)), 2, + TargetProperty::TRANSFORM)); + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 2, TargetProperty::OPACITY)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(animations->HasActiveAnimation()); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, events.get()); + // Should not have started the float transition yet. + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + // The float animation should have started at time 1 and should be done. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +// Tests scheduling two animations to run together with different lengths and +// another animation queued to start when the shorter animation finishes (should +// wait for both to finish). +TEST_F(ElementAnimationsTest, ScheduleTogetherWithAnAnimWaiting) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(2)), 1, + TargetProperty::TRANSFORM)); + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.5f)), + 2, TargetProperty::OPACITY)); + + // Animations with id 1 should both start now. + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + // The opacity animation should have finished at time 1, but the group + // of animations with id 1 don't finish until time 2 because of the length + // of the transform animation. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + animations->UpdateState(true, events.get()); + // Should not have started the float transition yet. + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + // The second opacity animation should start at time 2 and should be done by + // time 3. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(0.5f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +// Test that a looping animation loops and for the correct number of iterations. +TEST_F(ElementAnimationsTest, TrivialLooping) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + std::unique_ptr<Animation> to_add(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + to_add->set_iterations(3); + animations->AddAnimation(std::move(to_add)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1250)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.25f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1750)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.75f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2250)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.25f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2750)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.75f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); + animations->UpdateState(true, events.get()); + EXPECT_FALSE(animations->HasActiveAnimation()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + // Just be extra sure. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(4000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +// Test that an infinitely looping animation does indeed go until aborted. +TEST_F(ElementAnimationsTest, InfiniteLooping) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + std::unique_ptr<Animation> to_add(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + to_add->set_iterations(-1); + animations->AddAnimation(std::move(to_add)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1250)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.25f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1750)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.75f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1073741824250)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.25f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1073741824750)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.75f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + EXPECT_TRUE(animations->GetAnimation(TargetProperty::OPACITY)); + animations->GetAnimation(TargetProperty::OPACITY) + ->SetRunState(Animation::ABORTED, + kInitialTickTime + TimeDelta::FromMilliseconds(750)); + EXPECT_FALSE(animations->HasActiveAnimation()); + EXPECT_EQ(0.75f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +// Test that pausing and resuming work as expected. +TEST_F(ElementAnimationsTest, PauseResume) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.5f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + EXPECT_TRUE(animations->GetAnimation(TargetProperty::OPACITY)); + animations->GetAnimation(TargetProperty::OPACITY) + ->SetRunState(Animation::PAUSED, + kInitialTickTime + TimeDelta::FromMilliseconds(500)); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024000)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.5f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + EXPECT_TRUE(animations->GetAnimation(TargetProperty::OPACITY)); + animations->GetAnimation(TargetProperty::OPACITY) + ->SetRunState(Animation::RUNNING, + kInitialTickTime + TimeDelta::FromMilliseconds(1024000)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024250)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.75f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024500)); + animations->UpdateState(true, events.get()); + EXPECT_FALSE(animations->HasActiveAnimation()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, AbortAGroupedAnimation) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + const int animation_id = 2; + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, 1, + TargetProperty::TRANSFORM)); + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)), + animation_id, 1, TargetProperty::OPACITY)); + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.75f)), + 3, 2, TargetProperty::OPACITY)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.5f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + EXPECT_TRUE(animations->GetAnimationById(animation_id)); + animations->GetAnimationById(animation_id) + ->SetRunState(Animation::ABORTED, + kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(!animations->HasActiveAnimation()); + EXPECT_EQ(0.75f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, PushUpdatesWhenSynchronizedStartTimeNeeded) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + std::unique_ptr<Animation> to_add(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)), + 0, TargetProperty::OPACITY)); + to_add->set_needs_synchronized_start_time(true); + animations->AddAnimation(std::move(to_add)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_TRUE(animations->HasActiveAnimation()); + Animation* active_animation = + animations->GetAnimation(TargetProperty::OPACITY); + EXPECT_TRUE(active_animation); + EXPECT_TRUE(active_animation->needs_synchronized_start_time()); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + + active_animation = animations_impl->GetAnimation(TargetProperty::OPACITY); + EXPECT_TRUE(active_animation); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + active_animation->run_state()); +} + +// Tests that skipping a call to UpdateState works as expected. +TEST_F(ElementAnimationsTest, SkipUpdateState) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + auto events = host_impl_->CreateEvents(); + + std::unique_ptr<Animation> first_animation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, + TargetProperty::TRANSFORM)); + first_animation->set_is_controlling_instance_for_test(true); + animations->AddAnimation(std::move(first_animation)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + + std::unique_ptr<Animation> second_animation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 2, TargetProperty::OPACITY)); + second_animation->set_is_controlling_instance_for_test(true); + animations->AddAnimation(std::move(second_animation)); + + // Animate but don't UpdateState. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + events = host_impl_->CreateEvents(); + animations->UpdateState(true, events.get()); + + // Should have one STARTED event and one FINISHED event. + EXPECT_EQ(2u, events->events_.size()); + EXPECT_NE(events->events_[0].type, events->events_[1].type); + + // The float transition should still be at its starting point. + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); + animations->UpdateState(true, events.get()); + + // The float tranisition should now be done. + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->HasActiveAnimation()); +} + +// Tests that an animation animations with only a pending observer gets ticked +// but doesn't progress animations past the STARTING state. +TEST_F(ElementAnimationsTest, InactiveObserverGetsTicked) { + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + const int id = 1; + animations->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.5f, 1.f)), + id, TargetProperty::OPACITY)); + + // Without an observer, the animation shouldn't progress to the STARTING + // state. + animations->Animate(kInitialTickTime); + animations->UpdateState(true, events.get()); + EXPECT_EQ(0u, events->events_.size()); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + + CreateTestImplLayer(ElementListType::PENDING); + + // With only a pending observer, the animation should progress to the + // STARTING state and get ticked at its starting point, but should not + // progress to RUNNING. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(0u, events->events_.size()); + EXPECT_EQ(Animation::STARTING, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + + // Even when already in the STARTING state, the animation should stay + // there, and shouldn't be ticked past its starting point. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(0u, events->events_.size()); + EXPECT_EQ(Animation::STARTING, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + + CreateTestImplLayer(ElementListType::ACTIVE); + + // Now that an active observer has been added, the animation should still + // initially tick at its starting point, but should now progress to RUNNING. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); + animations->UpdateState(true, events.get()); + EXPECT_EQ(1u, events->events_.size()); + EXPECT_EQ(Animation::RUNNING, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + // The animation should now tick past its starting point. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3500)); + EXPECT_NE(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_NE(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, TransformAnimationBounds) { + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve1( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations1; + curve1->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); + operations1.AppendTranslate(10.0, 15.0, 0.0); + curve1->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); + animations_impl->AddAnimation(std::move(animation)); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve2( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations2; + curve2->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); + operations2.AppendScale(2.0, 3.0, 4.0); + curve2->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); + + animation = + Animation::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM); + animations_impl->AddAnimation(std::move(animation)); + + gfx::BoxF box(1.f, 2.f, -1.f, 3.f, 4.f, 5.f); + gfx::BoxF bounds; + + EXPECT_TRUE(animations_impl->TransformAnimationBoundsForBox(box, &bounds)); + EXPECT_EQ(gfx::BoxF(1.f, 2.f, -4.f, 13.f, 19.f, 20.f).ToString(), + bounds.ToString()); + + animations_impl->GetAnimationById(1)->SetRunState(Animation::FINISHED, + TicksFromSecondsF(0.0)); + + // Only the unfinished animation should affect the animated bounds. + EXPECT_TRUE(animations_impl->TransformAnimationBoundsForBox(box, &bounds)); + EXPECT_EQ(gfx::BoxF(1.f, 2.f, -4.f, 7.f, 16.f, 20.f).ToString(), + bounds.ToString()); + + animations_impl->GetAnimationById(2)->SetRunState(Animation::FINISHED, + TicksFromSecondsF(0.0)); + + // There are no longer any running animations. + EXPECT_FALSE(animations_impl->HasTransformAnimationThatInflatesBounds()); + + // Add an animation whose bounds we don't yet support computing. + std::unique_ptr<KeyframedTransformAnimationCurve> curve3( + KeyframedTransformAnimationCurve::Create()); + TransformOperations operations3; + gfx::Transform transform3; + transform3.Scale3d(1.0, 2.0, 3.0); + curve3->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr)); + operations3.AppendMatrix(transform3); + curve3->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations3, nullptr)); + animation = + Animation::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM); + animations_impl->AddAnimation(std::move(animation)); + EXPECT_FALSE(animations_impl->TransformAnimationBoundsForBox(box, &bounds)); +} + +// Tests that AbortAnimations aborts all animations targeting the specified +// property. +TEST_F(ElementAnimationsTest, AbortAnimations) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + // Start with several animations, and allow some of them to reach the finished + // state. + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 1, 1, + TargetProperty::TRANSFORM)); + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 2, 2, TargetProperty::OPACITY)); + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 3, 3, + TargetProperty::TRANSFORM)); + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(2.0)), 4, 4, + TargetProperty::TRANSFORM)); + animations->AddAnimation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 5, 5, TargetProperty::OPACITY)); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, nullptr); + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, nullptr); + + EXPECT_EQ(Animation::FINISHED, animations->GetAnimationById(1)->run_state()); + EXPECT_EQ(Animation::FINISHED, animations->GetAnimationById(2)->run_state()); + EXPECT_EQ(Animation::RUNNING, animations->GetAnimationById(3)->run_state()); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations->GetAnimationById(4)->run_state()); + EXPECT_EQ(Animation::RUNNING, animations->GetAnimationById(5)->run_state()); + + animations->AbortAnimations(TargetProperty::TRANSFORM); + + // Only un-finished TRANSFORM animations should have been aborted. + EXPECT_EQ(Animation::FINISHED, animations->GetAnimationById(1)->run_state()); + EXPECT_EQ(Animation::FINISHED, animations->GetAnimationById(2)->run_state()); + EXPECT_EQ(Animation::ABORTED, animations->GetAnimationById(3)->run_state()); + EXPECT_EQ(Animation::ABORTED, animations->GetAnimationById(4)->run_state()); + EXPECT_EQ(Animation::RUNNING, animations->GetAnimationById(5)->run_state()); +} + +// An animation aborted on the main thread should get deleted on both threads. +TEST_F(ElementAnimationsTest, MainThreadAbortedAnimationGetsDeleted) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + int animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1.0, 0.f, 1.f, false); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + + animations->AbortAnimations(TargetProperty::OPACITY); + EXPECT_EQ(Animation::ABORTED, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + EXPECT_FALSE(host_->animation_waiting_for_deletion()); + EXPECT_FALSE(host_impl_->animation_waiting_for_deletion()); + + animations->Animate(kInitialTickTime); + animations->UpdateState(true, nullptr); + EXPECT_FALSE(host_->animation_waiting_for_deletion()); + EXPECT_EQ(Animation::ABORTED, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_FALSE(animations->GetAnimationById(animation_id)); + EXPECT_FALSE(animations_impl->GetAnimationById(animation_id)); +} + +// An animation aborted on the impl thread should get deleted on both threads. +TEST_F(ElementAnimationsTest, ImplThreadAbortedAnimationGetsDeleted) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + TestAnimationDelegate delegate; + player_->set_animation_delegate(&delegate); + + int animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1.0, 0.f, 1.f, false); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + + animations_impl->AbortAnimations(TargetProperty::OPACITY); + EXPECT_EQ( + Animation::ABORTED, + animations_impl->GetAnimation(TargetProperty::OPACITY)->run_state()); + EXPECT_FALSE(host_->animation_waiting_for_deletion()); + EXPECT_FALSE(host_impl_->animation_waiting_for_deletion()); + + auto events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + EXPECT_TRUE(host_impl_->animation_waiting_for_deletion()); + EXPECT_EQ(1u, events->events_.size()); + EXPECT_EQ(AnimationEvent::ABORTED, events->events_[0].type); + EXPECT_EQ( + Animation::WAITING_FOR_DELETION, + animations_impl->GetAnimation(TargetProperty::OPACITY)->run_state()); + + animations->NotifyAnimationAborted(events->events_[0]); + EXPECT_EQ(Animation::ABORTED, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + EXPECT_TRUE(delegate.aborted()); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations->UpdateState(true, nullptr); + EXPECT_TRUE(host_->animation_waiting_for_deletion()); + EXPECT_EQ(Animation::WAITING_FOR_DELETION, + animations->GetAnimation(TargetProperty::OPACITY)->run_state()); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->GetAnimationById(animation_id)); + EXPECT_FALSE(animations_impl->GetAnimationById(animation_id)); +} + +// Test that an impl-only scroll offset animation that needs to be completed on +// the main thread gets deleted. +TEST_F(ElementAnimationsTest, ImplThreadTakeoverAnimationGetsDeleted) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + TestAnimationDelegate delegate_impl; + player_impl_->set_animation_delegate(&delegate_impl); + TestAnimationDelegate delegate; + player_->set_animation_delegate(&delegate); + + // Add impl-only scroll offset animation. + const int animation_id = 1; + gfx::ScrollOffset initial_value(100.f, 300.f); + gfx::ScrollOffset target_value(300.f, 200.f); + std::unique_ptr<ScrollOffsetAnimationCurve> curve( + ScrollOffsetAnimationCurve::Create(target_value, + EaseInOutTimingFunction::Create())); + curve->SetInitialValue(initial_value); + std::unique_ptr<Animation> animation(Animation::Create( + std::move(curve), animation_id, 0, TargetProperty::SCROLL_OFFSET)); + animation->set_start_time(TicksFromSecondsF(123)); + animation->set_is_impl_only(true); + animations_impl->AddAnimation(std::move(animation)); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + + const bool needs_completion = true; + animations_impl->AbortAnimations(TargetProperty::SCROLL_OFFSET, + needs_completion); + EXPECT_EQ(Animation::ABORTED_BUT_NEEDS_COMPLETION, + animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) + ->run_state()); + EXPECT_FALSE(host_->animation_waiting_for_deletion()); + EXPECT_FALSE(host_impl_->animation_waiting_for_deletion()); + + auto events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + EXPECT_TRUE(delegate_impl.finished()); + EXPECT_TRUE(host_impl_->animation_waiting_for_deletion()); + EXPECT_EQ(1u, events->events_.size()); + EXPECT_EQ(AnimationEvent::TAKEOVER, events->events_[0].type); + EXPECT_EQ(123, events->events_[0].animation_start_time); + EXPECT_EQ( + target_value, + events->events_[0].curve->ToScrollOffsetAnimationCurve()->target_value()); + EXPECT_EQ(Animation::WAITING_FOR_DELETION, + animations_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) + ->run_state()); + + animations->NotifyAnimationTakeover(events->events_[0]); + EXPECT_TRUE(delegate.takeover()); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations->GetAnimationById(animation_id)); + EXPECT_FALSE(animations_impl->GetAnimationById(animation_id)); +} + +// Ensure that we only generate FINISHED events for animations in a group +// once all animations in that group are finished. +TEST_F(ElementAnimationsTest, FinishedEventsForGroup) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + const int group_id = 1; + + // Add two animations with the same group id but different durations. + std::unique_ptr<Animation> first_animation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(2.0)), 1, + group_id, TargetProperty::TRANSFORM)); + first_animation->set_is_controlling_instance_for_test(true); + animations_impl->AddAnimation(std::move(first_animation)); + + std::unique_ptr<Animation> second_animation(Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 2, group_id, TargetProperty::OPACITY)); + second_animation->set_is_controlling_instance_for_test(true); + animations_impl->AddAnimation(std::move(second_animation)); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + // Both animations should have started. + EXPECT_EQ(2u, events->events_.size()); + EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); + EXPECT_EQ(AnimationEvent::STARTED, events->events_[1].type); + + events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1000)); + animations_impl->UpdateState(true, events.get()); + + // The opacity animation should be finished, but should not have generated + // a FINISHED event yet. + EXPECT_EQ(0u, events->events_.size()); + EXPECT_EQ(Animation::FINISHED, + animations_impl->GetAnimationById(2)->run_state()); + EXPECT_EQ(Animation::RUNNING, + animations_impl->GetAnimationById(1)->run_state()); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(2000)); + animations_impl->UpdateState(true, events.get()); + + // Both animations should have generated FINISHED events. + EXPECT_EQ(2u, events->events_.size()); + EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); + EXPECT_EQ(AnimationEvent::FINISHED, events->events_[1].type); +} + +// Ensure that when a group has a mix of aborted and finished animations, +// we generate a FINISHED event for the finished animation and an ABORTED +// event for the aborted animation. +TEST_F(ElementAnimationsTest, FinishedAndAbortedEventsForGroup) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + // Add two animations with the same group id. + std::unique_ptr<Animation> first_animation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 1, + TargetProperty::TRANSFORM)); + first_animation->set_is_controlling_instance_for_test(true); + animations_impl->AddAnimation(std::move(first_animation)); + + std::unique_ptr<Animation> second_animation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + second_animation->set_is_controlling_instance_for_test(true); + animations_impl->AddAnimation(std::move(second_animation)); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + // Both animations should have started. + EXPECT_EQ(2u, events->events_.size()); + EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); + EXPECT_EQ(AnimationEvent::STARTED, events->events_[1].type); + + animations_impl->AbortAnimations(TargetProperty::OPACITY); + + events = host_impl_->CreateEvents(); + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1000)); + animations_impl->UpdateState(true, events.get()); + + // We should have exactly 2 events: a FINISHED event for the tranform + // animation, and an ABORTED event for the opacity animation. + EXPECT_EQ(2u, events->events_.size()); + EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); + EXPECT_EQ(TargetProperty::TRANSFORM, events->events_[0].target_property); + EXPECT_EQ(AnimationEvent::ABORTED, events->events_[1].type); + EXPECT_EQ(TargetProperty::OPACITY, events->events_[1].target_property); +} + +TEST_F(ElementAnimationsTest, HasAnimationThatAffectsScale) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + EXPECT_FALSE(animations_impl->HasAnimationThatAffectsScale()); + + animations_impl->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + + // Opacity animations don't affect scale. + EXPECT_FALSE(animations_impl->HasAnimationThatAffectsScale()); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve1( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations1; + curve1->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); + operations1.AppendTranslate(10.0, 15.0, 0.0); + curve1->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve1), 2, 2, TargetProperty::TRANSFORM)); + animations_impl->AddAnimation(std::move(animation)); + + // Translations don't affect scale. + EXPECT_FALSE(animations_impl->HasAnimationThatAffectsScale()); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve2( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations2; + curve2->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); + operations2.AppendScale(2.0, 3.0, 4.0); + curve2->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); + + animation = + Animation::Create(std::move(curve2), 3, 3, TargetProperty::TRANSFORM); + animations_impl->AddAnimation(std::move(animation)); + + EXPECT_TRUE(animations_impl->HasAnimationThatAffectsScale()); + + animations_impl->GetAnimationById(3)->SetRunState(Animation::FINISHED, + TicksFromSecondsF(0.0)); + + // Only unfinished animations should be considered by + // HasAnimationThatAffectsScale. + EXPECT_FALSE(animations_impl->HasAnimationThatAffectsScale()); +} + +TEST_F(ElementAnimationsTest, HasOnlyTranslationTransforms) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::ACTIVE)); + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::PENDING)); + + animations_impl->AddAnimation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + + // Opacity animations aren't non-translation transforms. + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::ACTIVE)); + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::PENDING)); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve1( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations1; + curve1->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); + operations1.AppendTranslate(10.0, 15.0, 0.0); + curve1->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve1), 2, 2, TargetProperty::TRANSFORM)); + animations_impl->AddAnimation(std::move(animation)); + + // The only transform animation we've added is a translation. + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::ACTIVE)); + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::PENDING)); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve2( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations2; + curve2->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); + operations2.AppendScale(2.0, 3.0, 4.0); + curve2->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); + + animation = + Animation::Create(std::move(curve2), 3, 3, TargetProperty::TRANSFORM); + animation->set_affects_active_elements(false); + animations_impl->AddAnimation(std::move(animation)); + + // A scale animation is not a translation. + EXPECT_FALSE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::PENDING)); + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::PENDING)); + EXPECT_FALSE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::ACTIVE)); + + animations_impl->GetAnimationById(3)->set_affects_pending_elements(false); + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::PENDING)); + EXPECT_FALSE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::ACTIVE)); + + animations_impl->GetAnimationById(3)->SetRunState(Animation::FINISHED, + TicksFromSecondsF(0.0)); + + // Only unfinished animations should be considered by + // HasOnlyTranslationTransforms. + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::PENDING)); + EXPECT_TRUE( + animations_impl->HasOnlyTranslationTransforms(ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, AnimationStartScale) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve1( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations1; + operations1.AppendScale(2.0, 3.0, 4.0); + curve1->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); + TransformOperations operations2; + curve1->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); + animation->set_affects_active_elements(false); + animations_impl->AddAnimation(std::move(animation)); + + float start_scale = 0.f; + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::PENDING, + &start_scale)); + EXPECT_EQ(4.f, start_scale); + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::ACTIVE, + &start_scale)); + EXPECT_EQ(0.f, start_scale); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::PENDING, + &start_scale)); + EXPECT_EQ(4.f, start_scale); + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::ACTIVE, + &start_scale)); + EXPECT_EQ(4.f, start_scale); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve2( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations3; + curve2->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr)); + operations3.AppendScale(6.0, 5.0, 4.0); + curve2->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations3, nullptr)); + + animations_impl->RemoveAnimation(1); + animation = + Animation::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM); + + // Reverse Direction + animation->set_direction(Animation::Direction::REVERSE); + animation->set_affects_active_elements(false); + animations_impl->AddAnimation(std::move(animation)); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve3( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations4; + operations4.AppendScale(5.0, 3.0, 1.0); + curve3->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations4, nullptr)); + TransformOperations operations5; + curve3->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations5, nullptr)); + + animation = + Animation::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM); + animation->set_affects_active_elements(false); + animations_impl->AddAnimation(std::move(animation)); + + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::PENDING, + &start_scale)); + EXPECT_EQ(6.f, start_scale); + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::ACTIVE, + &start_scale)); + EXPECT_EQ(0.f, start_scale); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::PENDING, + &start_scale)); + EXPECT_EQ(6.f, start_scale); + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::ACTIVE, + &start_scale)); + EXPECT_EQ(6.f, start_scale); + + animations_impl->GetAnimationById(2)->SetRunState(Animation::FINISHED, + TicksFromSecondsF(0.0)); + + // Only unfinished animations should be considered by + // AnimationStartScale. + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::PENDING, + &start_scale)); + EXPECT_EQ(5.f, start_scale); + EXPECT_TRUE(animations_impl->AnimationStartScale(ElementListType::ACTIVE, + &start_scale)); + EXPECT_EQ(5.f, start_scale); +} + +TEST_F(ElementAnimationsTest, MaximumTargetScale) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + float max_scale = 0.f; + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(0.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(0.f, max_scale); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve1( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations1; + curve1->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); + operations1.AppendScale(2.0, 3.0, 4.0); + curve1->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); + + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); + animation->set_affects_active_elements(false); + animations_impl->AddAnimation(std::move(animation)); + + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(4.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(0.f, max_scale); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(4.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(4.f, max_scale); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve2( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations2; + curve2->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); + operations2.AppendScale(6.0, 5.0, 4.0); + curve2->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); + + animation = + Animation::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM); + animation->set_affects_active_elements(false); + animations_impl->AddAnimation(std::move(animation)); + + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(6.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(4.f, max_scale); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(6.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(6.f, max_scale); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve3( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations3; + curve3->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr)); + operations3.AppendPerspective(6.0); + curve3->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations3, nullptr)); + + animation = + Animation::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM); + animation->set_affects_active_elements(false); + animations_impl->AddAnimation(std::move(animation)); + + EXPECT_FALSE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(6.f, max_scale); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_FALSE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + + animations_impl->GetAnimationById(3)->SetRunState(Animation::FINISHED, + TicksFromSecondsF(0.0)); + animations_impl->GetAnimationById(2)->SetRunState(Animation::FINISHED, + TicksFromSecondsF(0.0)); + + // Only unfinished animations should be considered by + // MaximumTargetScale. + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(4.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(4.f, max_scale); +} + +TEST_F(ElementAnimationsTest, MaximumTargetScaleWithDirection) { + CreateTestLayer(true, false); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve1( + KeyframedTransformAnimationCurve::Create()); + TransformOperations operations1; + operations1.AppendScale(1.0, 2.0, 3.0); + curve1->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); + TransformOperations operations2; + operations2.AppendScale(4.0, 5.0, 6.0); + curve1->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); + + std::unique_ptr<Animation> animation_owned( + Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); + Animation* animation = animation_owned.get(); + animations_impl->AddAnimation(std::move(animation_owned)); + + float max_scale = 0.f; + + EXPECT_GT(animation->playback_rate(), 0.0); + + // NORMAL direction with positive playback rate. + animation->set_direction(Animation::Direction::NORMAL); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(6.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(6.f, max_scale); + + // ALTERNATE direction with positive playback rate. + animation->set_direction(Animation::Direction::ALTERNATE_NORMAL); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(6.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(6.f, max_scale); + + // REVERSE direction with positive playback rate. + animation->set_direction(Animation::Direction::REVERSE); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(3.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(3.f, max_scale); + + // ALTERNATE reverse direction. + animation->set_direction(Animation::Direction::REVERSE); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(3.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(3.f, max_scale); + + animation->set_playback_rate(-1.0); + + // NORMAL direction with negative playback rate. + animation->set_direction(Animation::Direction::NORMAL); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(3.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(3.f, max_scale); + + // ALTERNATE direction with negative playback rate. + animation->set_direction(Animation::Direction::ALTERNATE_NORMAL); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(3.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(3.f, max_scale); + + // REVERSE direction with negative playback rate. + animation->set_direction(Animation::Direction::REVERSE); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(6.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(6.f, max_scale); + + // ALTERNATE reverse direction with negative playback rate. + animation->set_direction(Animation::Direction::REVERSE); + EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING, + &max_scale)); + EXPECT_EQ(6.f, max_scale); + EXPECT_TRUE( + animations_impl->MaximumTargetScale(ElementListType::ACTIVE, &max_scale)); + EXPECT_EQ(6.f, max_scale); +} + +TEST_F(ElementAnimationsTest, NewlyPushedAnimationWaitsForActivation) { + CreateTestLayer(true, true); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + EXPECT_FALSE(animations->needs_to_start_animations_for_testing()); + int animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1, 0.5f, 1.f, false); + EXPECT_TRUE(animations->needs_to_start_animations_for_testing()); + + EXPECT_FALSE(animations_impl->needs_to_start_animations_for_testing()); + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(animations_impl->needs_to_start_animations_for_testing()); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_pending_elements()); + EXPECT_FALSE(animations_impl->GetAnimationById(animation_id) + ->affects_active_elements()); + + animations_impl->Animate(kInitialTickTime); + EXPECT_FALSE(animations_impl->needs_to_start_animations_for_testing()); + animations_impl->UpdateState(true, events.get()); + + // Since the animation hasn't been activated, it should still be STARTING + // rather than RUNNING. + EXPECT_EQ(Animation::STARTING, + animations_impl->GetAnimationById(animation_id)->run_state()); + + // Since the animation hasn't been activated, only the pending observer + // should have been ticked. + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.f, client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_pending_elements()); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_active_elements()); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1000)); + animations_impl->UpdateState(true, events.get()); + + // Since the animation has been activated, it should have reached the + // RUNNING state and the active observer should start to get ticked. + EXPECT_EQ(Animation::RUNNING, + animations_impl->GetAnimationById(animation_id)->run_state()); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, ActivationBetweenAnimateAndUpdateState) { + CreateTestLayer(true, true); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + const int animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1, 0.5f, 1.f, true); + + animations->PushPropertiesTo(animations_impl.get()); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); + EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, + animations_impl->GetAnimationById(animation_id)->run_state()); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_pending_elements()); + EXPECT_FALSE(animations_impl->GetAnimationById(animation_id) + ->affects_active_elements()); + + animations_impl->Animate(kInitialTickTime); + + // Since the animation hasn't been activated, only the pending observer + // should have been ticked. + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.f, client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_pending_elements()); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_active_elements()); + + animations_impl->UpdateState(true, events.get()); + + // Since the animation has been activated, it should have reached the + // RUNNING state. + EXPECT_EQ(Animation::RUNNING, + animations_impl->GetAnimationById(animation_id)->run_state()); + + animations_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + + // Both elements should have been ticked. + EXPECT_EQ(0.75f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.75f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, ObserverNotifiedWhenTransformAnimationChanges) { + CreateTestLayer(true, true); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + EXPECT_FALSE(client_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + // Case 1: An animation that's allowed to run until its finish point. + AddAnimatedTransformToElementAnimations(animations.get(), 1.0, 1, 1); + EXPECT_TRUE(client_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationStarted(events->events_[0]); + events->events_.clear(); + + // Finish the animation. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, nullptr); + EXPECT_FALSE(client_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + + // animations_impl hasn't yet ticked at/past the end of the animation. + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1000)); + animations_impl->UpdateState(true, events.get()); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + // Case 2: An animation that's removed before it finishes. + int animation_id = + AddAnimatedTransformToElementAnimations(animations.get(), 10.0, 2, 2); + EXPECT_TRUE(client_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(2000)); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationStarted(events->events_[0]); + events->events_.clear(); + + animations->RemoveAnimation(animation_id); + EXPECT_FALSE(client_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + // Case 3: An animation that's aborted before it finishes. + animation_id = + AddAnimatedTransformToElementAnimations(animations.get(), 10.0, 3, 3); + EXPECT_TRUE(client_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(2000)); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationStarted(events->events_[0]); + events->events_.clear(); + + animations_impl->AbortAnimations(TargetProperty::TRANSFORM); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(4000)); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationAborted(events->events_[0]); + EXPECT_FALSE(client_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + // Case 4 : An animation that's not in effect. + animation_id = + AddAnimatedTransformToElementAnimations(animations.get(), 1.0, 1, 6); + animations->GetAnimationById(animation_id) + ->set_time_offset(base::TimeDelta::FromMilliseconds(-10000)); + animations->GetAnimationById(animation_id) + ->set_fill_mode(Animation::FillMode::NONE); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialTransformAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetTransformIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, ObserverNotifiedWhenOpacityAnimationChanges) { + CreateTestLayer(true, true); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + EXPECT_FALSE(client_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetOpacityIsCurrentlyAnimating(element_id_, + ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + // Case 1: An animation that's allowed to run until its finish point. + AddOpacityTransitionToElementAnimations(animations.get(), 1.0, 0.f, 1.f, + false /*use_timing_function*/); + EXPECT_TRUE(client_.GetHasPotentialOpacityAnimation(element_id_, + ElementListType::ACTIVE)); + EXPECT_TRUE(client_.GetOpacityIsCurrentlyAnimating(element_id_, + ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationStarted(events->events_[0]); + events->events_.clear(); + + // Finish the animation. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + animations->UpdateState(true, nullptr); + EXPECT_FALSE(client_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetOpacityIsCurrentlyAnimating(element_id_, + ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + + // animations_impl hasn't yet ticked at/past the end of the animation. + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1000)); + animations_impl->UpdateState(true, events.get()); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + // Case 2: An animation that's removed before it finishes. + int animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 10.0, 0.f, 1.f, false /*use_timing_function*/); + EXPECT_TRUE(client_.GetHasPotentialOpacityAnimation(element_id_, + ElementListType::ACTIVE)); + EXPECT_TRUE(client_.GetOpacityIsCurrentlyAnimating(element_id_, + ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(2000)); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationStarted(events->events_[0]); + events->events_.clear(); + + animations->RemoveAnimation(animation_id); + EXPECT_FALSE(client_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetOpacityIsCurrentlyAnimating(element_id_, + ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + // Case 3: An animation that's aborted before it finishes. + animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 10.0, 0.f, 0.5f, false /*use_timing_function*/); + EXPECT_TRUE(client_.GetHasPotentialOpacityAnimation(element_id_, + ElementListType::ACTIVE)); + EXPECT_TRUE(client_.GetOpacityIsCurrentlyAnimating(element_id_, + ElementListType::ACTIVE)); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_TRUE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(2000)); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationStarted(events->events_[0]); + events->events_.clear(); + + animations_impl->AbortAnimations(TargetProperty::OPACITY); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(4000)); + animations_impl->UpdateState(true, events.get()); + + animations->NotifyAnimationAborted(events->events_[0]); + EXPECT_FALSE(client_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_.GetOpacityIsCurrentlyAnimating(element_id_, + ElementListType::ACTIVE)); + + // Case 4 : An animation that's not in effect. + animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1.0, 0.f, 0.5f, false /*use_timing_function*/); + animations->GetAnimationById(animation_id) + ->set_time_offset(base::TimeDelta::FromMilliseconds(-10000)); + animations->GetAnimationById(animation_id) + ->set_fill_mode(Animation::FillMode::NONE); + + animations->PushPropertiesTo(animations_impl.get()); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::PENDING)); + EXPECT_FALSE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation( + element_id_, ElementListType::ACTIVE)); + EXPECT_FALSE(client_impl_.GetOpacityIsCurrentlyAnimating( + element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, ClippedOpacityValues) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + AddOpacityTransitionToElementAnimations(animations.get(), 1, 1.f, 2.f, true); + + animations->Animate(kInitialTickTime); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + // Opacity values are clipped [0,1] + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, ClippedNegativeOpacityValues) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + AddOpacityTransitionToElementAnimations(animations.get(), 1, 0.f, -2.f, true); + + animations->Animate(kInitialTickTime); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + // Opacity values are clipped [0,1] + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, PushedDeletedAnimationWaitsForActivation) { + CreateTestLayer(true, true); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + const int animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1, 0.5f, 1.f, true); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + EXPECT_EQ(Animation::RUNNING, + animations_impl->GetAnimationById(animation_id)->run_state()); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_pending_elements()); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_active_elements()); + + // Delete the animation on the main-thread animations. + animations->RemoveAnimation( + animations->GetAnimation(TargetProperty::OPACITY)->id()); + animations->PushPropertiesTo(animations_impl.get()); + + // The animation should no longer affect pending elements. + EXPECT_FALSE(animations_impl->GetAnimationById(animation_id) + ->affects_pending_elements()); + EXPECT_TRUE(animations_impl->GetAnimationById(animation_id) + ->affects_active_elements()); + + animations_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations_impl->UpdateState(true, events.get()); + + // Only the active observer should have been ticked. + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.75f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + + // Activation should cause the animation to be deleted. + EXPECT_FALSE(animations_impl->has_any_animation()); +} + +// Tests that an animation that affects only active elements won't block +// an animation that affects only pending elements from starting. +TEST_F(ElementAnimationsTest, StartAnimationsAffectingDifferentObservers) { + CreateTestLayer(true, true); + AttachTimelinePlayerLayer(); + CreateImplTimelineAndPlayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); + + auto events = host_impl_->CreateEvents(); + + const int first_animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1, 0.f, 1.f, true); + + animations->PushPropertiesTo(animations_impl.get()); + animations_impl->ActivateAnimations(); + animations_impl->Animate(kInitialTickTime); + animations_impl->UpdateState(true, events.get()); + + // Remove the first animation from the main-thread animations, and add a + // new animation affecting the same property. + animations->RemoveAnimation( + animations->GetAnimation(TargetProperty::OPACITY)->id()); + const int second_animation_id = AddOpacityTransitionToElementAnimations( + animations.get(), 1, 1.f, 0.5f, true); + animations->PushPropertiesTo(animations_impl.get()); + + // The original animation should only affect active elements, and the new + // animation should only affect pending elements. + EXPECT_FALSE(animations_impl->GetAnimationById(first_animation_id) + ->affects_pending_elements()); + EXPECT_TRUE(animations_impl->GetAnimationById(first_animation_id) + ->affects_active_elements()); + EXPECT_TRUE(animations_impl->GetAnimationById(second_animation_id) + ->affects_pending_elements()); + EXPECT_FALSE(animations_impl->GetAnimationById(second_animation_id) + ->affects_active_elements()); + + animations_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); + animations_impl->UpdateState(true, events.get()); + + // The original animation should still be running, and the new animation + // should be starting. + EXPECT_EQ(Animation::RUNNING, + animations_impl->GetAnimationById(first_animation_id)->run_state()); + EXPECT_EQ( + Animation::STARTING, + animations_impl->GetAnimationById(second_animation_id)->run_state()); + + // The active observer should have been ticked by the original animation, + // and the pending observer should have been ticked by the new animation. + EXPECT_EQ(1.f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(0.5f, + client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + animations_impl->ActivateAnimations(); + + // The original animation should have been deleted, and the new animation + // should now affect both elements. + EXPECT_FALSE(animations_impl->GetAnimationById(first_animation_id)); + EXPECT_TRUE(animations_impl->GetAnimationById(second_animation_id) + ->affects_pending_elements()); + EXPECT_TRUE(animations_impl->GetAnimationById(second_animation_id) + ->affects_active_elements()); + + animations_impl->Animate(kInitialTickTime + + TimeDelta::FromMilliseconds(1000)); + animations_impl->UpdateState(true, events.get()); + + // The new animation should be running, and the active observer should have + // been ticked at the new animation's starting point. + EXPECT_EQ( + Animation::RUNNING, + animations_impl->GetAnimationById(second_animation_id)->run_state()); + EXPECT_EQ(1.f, + client_impl_.GetOpacity(element_id_, ElementListType::PENDING)); + EXPECT_EQ(1.f, client_impl_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, TestIsCurrentlyAnimatingProperty) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + // Create an animation that initially affects only pending elements. + std::unique_ptr<Animation> animation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + animation->set_affects_active_elements(false); + + animations->AddAnimation(std::move(animation)); + animations->Animate(kInitialTickTime); + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + animations->UpdateState(true, nullptr); + EXPECT_TRUE(animations->HasActiveAnimation()); + + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::ACTIVE)); + + animations->ActivateAnimations(); + + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::ACTIVE)); + + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(10)); + animations->UpdateState(true, nullptr); + + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::ACTIVE)); + + EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); + + // Tick past the end of the animation. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1100)); + animations->UpdateState(true, nullptr); + + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::FILTER, ElementListType::ACTIVE)); + + EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE)); +} + +TEST_F(ElementAnimationsTest, TestIsAnimatingPropertyTimeOffsetFillMode) { + CreateTestLayer(false, false); + AttachTimelinePlayerLayer(); + + scoped_refptr<ElementAnimations> animations = element_animations(); + + // Create an animation that initially affects only pending elements, and has + // a start delay of 2 seconds. + std::unique_ptr<Animation> animation(CreateAnimation( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + 1, TargetProperty::OPACITY)); + animation->set_fill_mode(Animation::FillMode::NONE); + animation->set_time_offset(TimeDelta::FromMilliseconds(-2000)); + animation->set_affects_active_elements(false); + + animations->AddAnimation(std::move(animation)); + + animations->Animate(kInitialTickTime); + + // Since the animation has a start delay, the elements it affects have a + // potentially running transform animation but aren't currently animating + // transform. + EXPECT_TRUE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::FILTER, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::FILTER, ElementListType::ACTIVE)); + + animations->ActivateAnimations(); + + EXPECT_TRUE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_TRUE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_TRUE(animations->HasActiveAnimation()); + EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::FILTER, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::FILTER, ElementListType::ACTIVE)); + + animations->UpdateState(true, nullptr); + + // Tick past the start delay. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); + animations->UpdateState(true, nullptr); + EXPECT_TRUE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_TRUE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_TRUE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + + // After the animaton finishes, the elements it affects have neither a + // potentially running transform animation nor a currently running transform + // animation. + animations->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(4000)); + animations->UpdateState(true, nullptr); + EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::PENDING)); + EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( + TargetProperty::OPACITY, ElementListType::ACTIVE)); +} + } // namespace } // namespace cc diff --git a/chromium/cc/animation/keyframed_animation_curve.cc b/chromium/cc/animation/keyframed_animation_curve.cc index a8dd9bdaa65..061d48e23a8 100644 --- a/chromium/cc/animation/keyframed_animation_curve.cc +++ b/chromium/cc/animation/keyframed_animation_curve.cc @@ -2,11 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/animation/keyframed_animation_curve.h" + #include <stddef.h> #include <algorithm> -#include "cc/animation/keyframed_animation_curve.h" +#include "base/memory/ptr_util.h" #include "cc/base/time_util.h" #include "ui/gfx/animation/tween.h" #include "ui/gfx/geometry/box_f.h" @@ -16,8 +18,8 @@ namespace cc { namespace { template <class KeyframeType> -void InsertKeyframe(scoped_ptr<KeyframeType> keyframe, - std::vector<scoped_ptr<KeyframeType>>* keyframes) { +void InsertKeyframe(std::unique_ptr<KeyframeType> keyframe, + std::vector<std::unique_ptr<KeyframeType>>* keyframes) { // Usually, the keyframes will be added in order, so this loop would be // unnecessary and we should skip it if possible. if (!keyframes->empty() && keyframe->Time() < keyframes->back()->Time()) { @@ -34,8 +36,8 @@ void InsertKeyframe(scoped_ptr<KeyframeType> keyframe, template <typename KeyframeType> base::TimeDelta TransformedAnimationTime( - const std::vector<scoped_ptr<KeyframeType>>& keyframes, - const scoped_ptr<TimingFunction>& timing_function, + const std::vector<std::unique_ptr<KeyframeType>>& keyframes, + const std::unique_ptr<TimingFunction>& timing_function, base::TimeDelta time) { if (timing_function) { base::TimeDelta start_time = keyframes.front()->Time(); @@ -51,8 +53,9 @@ base::TimeDelta TransformedAnimationTime( } template <typename KeyframeType> -size_t GetActiveKeyframe(const std::vector<scoped_ptr<KeyframeType>>& keyframes, - base::TimeDelta time) { +size_t GetActiveKeyframe( + const std::vector<std::unique_ptr<KeyframeType>>& keyframes, + base::TimeDelta time) { DCHECK_GE(keyframes.size(), 2ul); size_t i = 0; for (; i < keyframes.size() - 2; ++i) { // Last keyframe is never active. @@ -65,7 +68,7 @@ size_t GetActiveKeyframe(const std::vector<scoped_ptr<KeyframeType>>& keyframes, template <typename KeyframeType> double TransformedKeyframeProgress( - const std::vector<scoped_ptr<KeyframeType>>& keyframes, + const std::vector<std::unique_ptr<KeyframeType>>& keyframes, base::TimeDelta time, size_t i) { double progress = @@ -82,7 +85,7 @@ double TransformedKeyframeProgress( } // namespace Keyframe::Keyframe(base::TimeDelta time, - scoped_ptr<TimingFunction> timing_function) + std::unique_ptr<TimingFunction> timing_function) : time_(time), timing_function_(std::move(timing_function)) {} Keyframe::~Keyframe() {} @@ -91,41 +94,41 @@ base::TimeDelta Keyframe::Time() const { return time_; } -scoped_ptr<ColorKeyframe> ColorKeyframe::Create( +std::unique_ptr<ColorKeyframe> ColorKeyframe::Create( base::TimeDelta time, SkColor value, - scoped_ptr<TimingFunction> timing_function) { - return make_scoped_ptr( + std::unique_ptr<TimingFunction> timing_function) { + return base::WrapUnique( new ColorKeyframe(time, value, std::move(timing_function))); } ColorKeyframe::ColorKeyframe(base::TimeDelta time, SkColor value, - scoped_ptr<TimingFunction> timing_function) + std::unique_ptr<TimingFunction> timing_function) : Keyframe(time, std::move(timing_function)), value_(value) {} ColorKeyframe::~ColorKeyframe() {} SkColor ColorKeyframe::Value() const { return value_; } -scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const { - scoped_ptr<TimingFunction> func; +std::unique_ptr<ColorKeyframe> ColorKeyframe::Clone() const { + std::unique_ptr<TimingFunction> func; if (timing_function()) func = timing_function()->Clone(); return ColorKeyframe::Create(Time(), Value(), std::move(func)); } -scoped_ptr<FloatKeyframe> FloatKeyframe::Create( +std::unique_ptr<FloatKeyframe> FloatKeyframe::Create( base::TimeDelta time, float value, - scoped_ptr<TimingFunction> timing_function) { - return make_scoped_ptr( + std::unique_ptr<TimingFunction> timing_function) { + return base::WrapUnique( new FloatKeyframe(time, value, std::move(timing_function))); } FloatKeyframe::FloatKeyframe(base::TimeDelta time, float value, - scoped_ptr<TimingFunction> timing_function) + std::unique_ptr<TimingFunction> timing_function) : Keyframe(time, std::move(timing_function)), value_(value) {} FloatKeyframe::~FloatKeyframe() {} @@ -134,24 +137,25 @@ float FloatKeyframe::Value() const { return value_; } -scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const { - scoped_ptr<TimingFunction> func; +std::unique_ptr<FloatKeyframe> FloatKeyframe::Clone() const { + std::unique_ptr<TimingFunction> func; if (timing_function()) func = timing_function()->Clone(); return FloatKeyframe::Create(Time(), Value(), std::move(func)); } -scoped_ptr<TransformKeyframe> TransformKeyframe::Create( +std::unique_ptr<TransformKeyframe> TransformKeyframe::Create( base::TimeDelta time, const TransformOperations& value, - scoped_ptr<TimingFunction> timing_function) { - return make_scoped_ptr( + std::unique_ptr<TimingFunction> timing_function) { + return base::WrapUnique( new TransformKeyframe(time, value, std::move(timing_function))); } -TransformKeyframe::TransformKeyframe(base::TimeDelta time, - const TransformOperations& value, - scoped_ptr<TimingFunction> timing_function) +TransformKeyframe::TransformKeyframe( + base::TimeDelta time, + const TransformOperations& value, + std::unique_ptr<TimingFunction> timing_function) : Keyframe(time, std::move(timing_function)), value_(value) {} TransformKeyframe::~TransformKeyframe() {} @@ -160,24 +164,24 @@ const TransformOperations& TransformKeyframe::Value() const { return value_; } -scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const { - scoped_ptr<TimingFunction> func; +std::unique_ptr<TransformKeyframe> TransformKeyframe::Clone() const { + std::unique_ptr<TimingFunction> func; if (timing_function()) func = timing_function()->Clone(); return TransformKeyframe::Create(Time(), Value(), std::move(func)); } -scoped_ptr<FilterKeyframe> FilterKeyframe::Create( +std::unique_ptr<FilterKeyframe> FilterKeyframe::Create( base::TimeDelta time, const FilterOperations& value, - scoped_ptr<TimingFunction> timing_function) { - return make_scoped_ptr( + std::unique_ptr<TimingFunction> timing_function) { + return base::WrapUnique( new FilterKeyframe(time, value, std::move(timing_function))); } FilterKeyframe::FilterKeyframe(base::TimeDelta time, const FilterOperations& value, - scoped_ptr<TimingFunction> timing_function) + std::unique_ptr<TimingFunction> timing_function) : Keyframe(time, std::move(timing_function)), value_(value) {} FilterKeyframe::~FilterKeyframe() {} @@ -186,16 +190,16 @@ const FilterOperations& FilterKeyframe::Value() const { return value_; } -scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const { - scoped_ptr<TimingFunction> func; +std::unique_ptr<FilterKeyframe> FilterKeyframe::Clone() const { + std::unique_ptr<TimingFunction> func; if (timing_function()) func = timing_function()->Clone(); return FilterKeyframe::Create(Time(), Value(), std::move(func)); } -scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve:: - Create() { - return make_scoped_ptr(new KeyframedColorAnimationCurve); +std::unique_ptr<KeyframedColorAnimationCurve> +KeyframedColorAnimationCurve::Create() { + return base::WrapUnique(new KeyframedColorAnimationCurve); } KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {} @@ -203,7 +207,7 @@ KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {} KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {} void KeyframedColorAnimationCurve::AddKeyframe( - scoped_ptr<ColorKeyframe> keyframe) { + std::unique_ptr<ColorKeyframe> keyframe) { InsertKeyframe(std::move(keyframe), &keyframes_); } @@ -211,8 +215,8 @@ base::TimeDelta KeyframedColorAnimationCurve::Duration() const { return keyframes_.back()->Time() - keyframes_.front()->Time(); } -scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const { - scoped_ptr<KeyframedColorAnimationCurve> to_return = +std::unique_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const { + std::unique_ptr<KeyframedColorAnimationCurve> to_return = KeyframedColorAnimationCurve::Create(); for (size_t i = 0; i < keyframes_.size(); ++i) to_return->AddKeyframe(keyframes_[i]->Clone()); @@ -240,9 +244,9 @@ SkColor KeyframedColorAnimationCurve::GetValue(base::TimeDelta t) const { // KeyframedFloatAnimationCurve -scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve:: - Create() { - return make_scoped_ptr(new KeyframedFloatAnimationCurve); +std::unique_ptr<KeyframedFloatAnimationCurve> +KeyframedFloatAnimationCurve::Create() { + return base::WrapUnique(new KeyframedFloatAnimationCurve); } KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {} @@ -250,7 +254,7 @@ KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {} KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {} void KeyframedFloatAnimationCurve::AddKeyframe( - scoped_ptr<FloatKeyframe> keyframe) { + std::unique_ptr<FloatKeyframe> keyframe) { InsertKeyframe(std::move(keyframe), &keyframes_); } @@ -258,8 +262,8 @@ base::TimeDelta KeyframedFloatAnimationCurve::Duration() const { return keyframes_.back()->Time() - keyframes_.front()->Time(); } -scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { - scoped_ptr<KeyframedFloatAnimationCurve> to_return = +std::unique_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { + std::unique_ptr<KeyframedFloatAnimationCurve> to_return = KeyframedFloatAnimationCurve::Create(); for (size_t i = 0; i < keyframes_.size(); ++i) to_return->AddKeyframe(keyframes_[i]->Clone()); @@ -285,9 +289,9 @@ float KeyframedFloatAnimationCurve::GetValue(base::TimeDelta t) const { (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress; } -scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve:: - Create() { - return make_scoped_ptr(new KeyframedTransformAnimationCurve); +std::unique_ptr<KeyframedTransformAnimationCurve> +KeyframedTransformAnimationCurve::Create() { + return base::WrapUnique(new KeyframedTransformAnimationCurve); } KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {} @@ -295,7 +299,7 @@ KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {} KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {} void KeyframedTransformAnimationCurve::AddKeyframe( - scoped_ptr<TransformKeyframe> keyframe) { + std::unique_ptr<TransformKeyframe> keyframe) { InsertKeyframe(std::move(keyframe), &keyframes_); } @@ -303,8 +307,9 @@ base::TimeDelta KeyframedTransformAnimationCurve::Duration() const { return keyframes_.back()->Time() - keyframes_.front()->Time(); } -scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const { - scoped_ptr<KeyframedTransformAnimationCurve> to_return = +std::unique_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() + const { + std::unique_ptr<KeyframedTransformAnimationCurve> to_return = KeyframedTransformAnimationCurve::Create(); for (size_t i = 0; i < keyframes_.size(); ++i) to_return->AddKeyframe(keyframes_[i]->Clone()); @@ -425,9 +430,9 @@ bool KeyframedTransformAnimationCurve::MaximumTargetScale( return true; } -scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve:: - Create() { - return make_scoped_ptr(new KeyframedFilterAnimationCurve); +std::unique_ptr<KeyframedFilterAnimationCurve> +KeyframedFilterAnimationCurve::Create() { + return base::WrapUnique(new KeyframedFilterAnimationCurve); } KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {} @@ -435,7 +440,7 @@ KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {} KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {} void KeyframedFilterAnimationCurve::AddKeyframe( - scoped_ptr<FilterKeyframe> keyframe) { + std::unique_ptr<FilterKeyframe> keyframe) { InsertKeyframe(std::move(keyframe), &keyframes_); } @@ -443,8 +448,8 @@ base::TimeDelta KeyframedFilterAnimationCurve::Duration() const { return keyframes_.back()->Time() - keyframes_.front()->Time(); } -scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { - scoped_ptr<KeyframedFilterAnimationCurve> to_return = +std::unique_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { + std::unique_ptr<KeyframedFilterAnimationCurve> to_return = KeyframedFilterAnimationCurve::Create(); for (size_t i = 0; i < keyframes_.size(); ++i) to_return->AddKeyframe(keyframes_[i]->Clone()); diff --git a/chromium/cc/animation/keyframed_animation_curve.h b/chromium/cc/animation/keyframed_animation_curve.h index 24101f65740..6e268754672 100644 --- a/chromium/cc/animation/keyframed_animation_curve.h +++ b/chromium/cc/animation/keyframed_animation_curve.h @@ -24,92 +24,93 @@ class CC_EXPORT Keyframe { } protected: - Keyframe(base::TimeDelta time, scoped_ptr<TimingFunction> timing_function); + Keyframe(base::TimeDelta time, + std::unique_ptr<TimingFunction> timing_function); virtual ~Keyframe(); private: base::TimeDelta time_; - scoped_ptr<TimingFunction> timing_function_; + std::unique_ptr<TimingFunction> timing_function_; DISALLOW_COPY_AND_ASSIGN(Keyframe); }; class CC_EXPORT ColorKeyframe : public Keyframe { public: - static scoped_ptr<ColorKeyframe> Create( + static std::unique_ptr<ColorKeyframe> Create( base::TimeDelta time, SkColor value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); ~ColorKeyframe() override; SkColor Value() const; - scoped_ptr<ColorKeyframe> Clone() const; + std::unique_ptr<ColorKeyframe> Clone() const; private: ColorKeyframe(base::TimeDelta time, SkColor value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); SkColor value_; }; class CC_EXPORT FloatKeyframe : public Keyframe { public: - static scoped_ptr<FloatKeyframe> Create( + static std::unique_ptr<FloatKeyframe> Create( base::TimeDelta time, float value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); ~FloatKeyframe() override; float Value() const; - scoped_ptr<FloatKeyframe> Clone() const; + std::unique_ptr<FloatKeyframe> Clone() const; private: FloatKeyframe(base::TimeDelta time, float value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); float value_; }; class CC_EXPORT TransformKeyframe : public Keyframe { public: - static scoped_ptr<TransformKeyframe> Create( + static std::unique_ptr<TransformKeyframe> Create( base::TimeDelta time, const TransformOperations& value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); ~TransformKeyframe() override; const TransformOperations& Value() const; - scoped_ptr<TransformKeyframe> Clone() const; + std::unique_ptr<TransformKeyframe> Clone() const; private: TransformKeyframe(base::TimeDelta time, const TransformOperations& value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); TransformOperations value_; }; class CC_EXPORT FilterKeyframe : public Keyframe { public: - static scoped_ptr<FilterKeyframe> Create( + static std::unique_ptr<FilterKeyframe> Create( base::TimeDelta time, const FilterOperations& value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); ~FilterKeyframe() override; const FilterOperations& Value() const; - scoped_ptr<FilterKeyframe> Clone() const; + std::unique_ptr<FilterKeyframe> Clone() const; private: FilterKeyframe(base::TimeDelta time, const FilterOperations& value, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); FilterOperations value_; }; @@ -117,18 +118,18 @@ class CC_EXPORT FilterKeyframe : public Keyframe { class CC_EXPORT KeyframedColorAnimationCurve : public ColorAnimationCurve { public: // It is required that the keyframes be sorted by time. - static scoped_ptr<KeyframedColorAnimationCurve> Create(); + static std::unique_ptr<KeyframedColorAnimationCurve> Create(); ~KeyframedColorAnimationCurve() override; - void AddKeyframe(scoped_ptr<ColorKeyframe> keyframe); - void SetTimingFunction(scoped_ptr<TimingFunction> timing_function) { + void AddKeyframe(std::unique_ptr<ColorKeyframe> keyframe); + void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); } // AnimationCurve implementation base::TimeDelta Duration() const override; - scoped_ptr<AnimationCurve> Clone() const override; + std::unique_ptr<AnimationCurve> Clone() const override; // BackgrounColorAnimationCurve implementation SkColor GetValue(base::TimeDelta t) const override; @@ -138,8 +139,8 @@ class CC_EXPORT KeyframedColorAnimationCurve : public ColorAnimationCurve { // Always sorted in order of increasing time. No two keyframes have the // same time. - std::vector<scoped_ptr<ColorKeyframe>> keyframes_; - scoped_ptr<TimingFunction> timing_function_; + std::vector<std::unique_ptr<ColorKeyframe>> keyframes_; + std::unique_ptr<TimingFunction> timing_function_; DISALLOW_COPY_AND_ASSIGN(KeyframedColorAnimationCurve); }; @@ -147,18 +148,18 @@ class CC_EXPORT KeyframedColorAnimationCurve : public ColorAnimationCurve { class CC_EXPORT KeyframedFloatAnimationCurve : public FloatAnimationCurve { public: // It is required that the keyframes be sorted by time. - static scoped_ptr<KeyframedFloatAnimationCurve> Create(); + static std::unique_ptr<KeyframedFloatAnimationCurve> Create(); ~KeyframedFloatAnimationCurve() override; - void AddKeyframe(scoped_ptr<FloatKeyframe> keyframe); - void SetTimingFunction(scoped_ptr<TimingFunction> timing_function) { + void AddKeyframe(std::unique_ptr<FloatKeyframe> keyframe); + void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); } // AnimationCurve implementation base::TimeDelta Duration() const override; - scoped_ptr<AnimationCurve> Clone() const override; + std::unique_ptr<AnimationCurve> Clone() const override; // FloatAnimationCurve implementation float GetValue(base::TimeDelta t) const override; @@ -168,8 +169,8 @@ class CC_EXPORT KeyframedFloatAnimationCurve : public FloatAnimationCurve { // Always sorted in order of increasing time. No two keyframes have the // same time. - std::vector<scoped_ptr<FloatKeyframe>> keyframes_; - scoped_ptr<TimingFunction> timing_function_; + std::vector<std::unique_ptr<FloatKeyframe>> keyframes_; + std::unique_ptr<TimingFunction> timing_function_; DISALLOW_COPY_AND_ASSIGN(KeyframedFloatAnimationCurve); }; @@ -178,18 +179,18 @@ class CC_EXPORT KeyframedTransformAnimationCurve : public TransformAnimationCurve { public: // It is required that the keyframes be sorted by time. - static scoped_ptr<KeyframedTransformAnimationCurve> Create(); + static std::unique_ptr<KeyframedTransformAnimationCurve> Create(); ~KeyframedTransformAnimationCurve() override; - void AddKeyframe(scoped_ptr<TransformKeyframe> keyframe); - void SetTimingFunction(scoped_ptr<TimingFunction> timing_function) { + void AddKeyframe(std::unique_ptr<TransformKeyframe> keyframe); + void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); } // AnimationCurve implementation base::TimeDelta Duration() const override; - scoped_ptr<AnimationCurve> Clone() const override; + std::unique_ptr<AnimationCurve> Clone() const override; // TransformAnimationCurve implementation gfx::Transform GetValue(base::TimeDelta t) const override; @@ -208,8 +209,8 @@ class CC_EXPORT KeyframedTransformAnimationCurve // Always sorted in order of increasing time. No two keyframes have the // same time. - std::vector<scoped_ptr<TransformKeyframe>> keyframes_; - scoped_ptr<TimingFunction> timing_function_; + std::vector<std::unique_ptr<TransformKeyframe>> keyframes_; + std::unique_ptr<TimingFunction> timing_function_; DISALLOW_COPY_AND_ASSIGN(KeyframedTransformAnimationCurve); }; @@ -218,18 +219,18 @@ class CC_EXPORT KeyframedFilterAnimationCurve : public FilterAnimationCurve { public: // It is required that the keyframes be sorted by time. - static scoped_ptr<KeyframedFilterAnimationCurve> Create(); + static std::unique_ptr<KeyframedFilterAnimationCurve> Create(); ~KeyframedFilterAnimationCurve() override; - void AddKeyframe(scoped_ptr<FilterKeyframe> keyframe); - void SetTimingFunction(scoped_ptr<TimingFunction> timing_function) { + void AddKeyframe(std::unique_ptr<FilterKeyframe> keyframe); + void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); } // AnimationCurve implementation base::TimeDelta Duration() const override; - scoped_ptr<AnimationCurve> Clone() const override; + std::unique_ptr<AnimationCurve> Clone() const override; // FilterAnimationCurve implementation FilterOperations GetValue(base::TimeDelta t) const override; @@ -240,8 +241,8 @@ class CC_EXPORT KeyframedFilterAnimationCurve // Always sorted in order of increasing time. No two keyframes have the // same time. - std::vector<scoped_ptr<FilterKeyframe>> keyframes_; - scoped_ptr<TimingFunction> timing_function_; + std::vector<std::unique_ptr<FilterKeyframe>> keyframes_; + std::unique_ptr<TimingFunction> timing_function_; DISALLOW_COPY_AND_ASSIGN(KeyframedFilterAnimationCurve); }; diff --git a/chromium/cc/animation/keyframed_animation_curve_unittest.cc b/chromium/cc/animation/keyframed_animation_curve_unittest.cc index 718872b8d1a..b0010441ab7 100644 --- a/chromium/cc/animation/keyframed_animation_curve_unittest.cc +++ b/chromium/cc/animation/keyframed_animation_curve_unittest.cc @@ -27,7 +27,7 @@ void ExpectBrightness(double brightness, const FilterOperations& filter) { // Tests that a color animation with one keyframe works as expected. TEST(KeyframedAnimationCurveTest, OneColorKeyFrame) { SkColor color = SkColorSetARGB(255, 255, 255, 255); - scoped_ptr<KeyframedColorAnimationCurve> curve( + std::unique_ptr<KeyframedColorAnimationCurve> curve( KeyframedColorAnimationCurve::Create()); curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta(), color, nullptr)); @@ -45,7 +45,7 @@ TEST(KeyframedAnimationCurveTest, TwoColorKeyFrame) { SkColor color_a = SkColorSetARGB(255, 255, 0, 0); SkColor color_b = SkColorSetARGB(255, 0, 255, 0); SkColor color_midpoint = gfx::Tween::ColorValueBetween(0.5, color_a, color_b); - scoped_ptr<KeyframedColorAnimationCurve> curve( + std::unique_ptr<KeyframedColorAnimationCurve> curve( KeyframedColorAnimationCurve::Create()); curve->AddKeyframe( ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr)); @@ -73,7 +73,7 @@ TEST(KeyframedAnimationCurveTest, ThreeColorKeyFrame) { gfx::Tween::ColorValueBetween(0.5, color_a, color_b); SkColor color_midpoint2 = gfx::Tween::ColorValueBetween(0.5, color_b, color_c); - scoped_ptr<KeyframedColorAnimationCurve> curve( + std::unique_ptr<KeyframedColorAnimationCurve> curve( KeyframedColorAnimationCurve::Create()); curve->AddKeyframe( ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr)); @@ -103,7 +103,7 @@ TEST(KeyframedAnimationCurveTest, RepeatedColorKeyFrame) { SkColor color_a = SkColorSetARGB(255, 64, 0, 0); SkColor color_b = SkColorSetARGB(255, 192, 0, 0); - scoped_ptr<KeyframedColorAnimationCurve> curve( + std::unique_ptr<KeyframedColorAnimationCurve> curve( KeyframedColorAnimationCurve::Create()); curve->AddKeyframe( ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr)); @@ -137,7 +137,7 @@ TEST(KeyframedAnimationCurveTest, RepeatedColorKeyFrame) { // Tests that a float animation with one keyframe works as expected. TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr)); EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); @@ -149,7 +149,7 @@ TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) { // Tests that a float animation with two keyframes works as expected. TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr)); curve->AddKeyframe( @@ -163,7 +163,7 @@ TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) { // Tests that a float animation with three keyframes works as expected. TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr)); curve->AddKeyframe( @@ -181,7 +181,7 @@ TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) { // Tests that a float animation with multiple keys at a given time works sanely. TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 4.f, nullptr)); curve->AddKeyframe( @@ -206,7 +206,7 @@ TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) { // Tests that a transform animation with one keyframe works as expected. TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations; operations.AppendTranslate(2.f, 0.f, 0.f); @@ -222,7 +222,7 @@ TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) { // Tests that a transform animation with two keyframes works as expected. TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations1; operations1.AppendTranslate(2.f, 0.f, 0.f); @@ -242,7 +242,7 @@ TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) { // Tests that a transform animation with three keyframes works as expected. TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations1; operations1.AppendTranslate(2.f, 0.f, 0.f); @@ -268,7 +268,7 @@ TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) { // Tests that a transform animation with multiple keys at a given time works // sanely. TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); // A step function. TransformOperations operations1; @@ -304,7 +304,7 @@ TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) { // Tests that a filter animation with one keyframe works as expected. TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) { - scoped_ptr<KeyframedFilterAnimationCurve> curve( + std::unique_ptr<KeyframedFilterAnimationCurve> curve( KeyframedFilterAnimationCurve::Create()); FilterOperations operations; operations.Append(FilterOperation::CreateBrightnessFilter(2.f)); @@ -320,7 +320,7 @@ TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) { // Tests that a filter animation with two keyframes works as expected. TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) { - scoped_ptr<KeyframedFilterAnimationCurve> curve( + std::unique_ptr<KeyframedFilterAnimationCurve> curve( KeyframedFilterAnimationCurve::Create()); FilterOperations operations1; operations1.Append(FilterOperation::CreateBrightnessFilter(2.f)); @@ -340,7 +340,7 @@ TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) { // Tests that a filter animation with three keyframes works as expected. TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) { - scoped_ptr<KeyframedFilterAnimationCurve> curve( + std::unique_ptr<KeyframedFilterAnimationCurve> curve( KeyframedFilterAnimationCurve::Create()); FilterOperations operations1; operations1.Append(FilterOperation::CreateBrightnessFilter(2.f)); @@ -366,7 +366,7 @@ TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) { // Tests that a filter animation with multiple keys at a given time works // sanely. TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) { - scoped_ptr<KeyframedFilterAnimationCurve> curve( + std::unique_ptr<KeyframedFilterAnimationCurve> curve( KeyframedFilterAnimationCurve::Create()); // A step function. FilterOperations operations1; @@ -404,7 +404,7 @@ TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) { // Tests that the keyframes may be added out of order. TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe( FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 8.f, nullptr)); @@ -422,7 +422,7 @@ TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) { // Tests that a cubic bezier timing function works as expected. TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create( base::TimeDelta(), 0.f, @@ -442,13 +442,13 @@ TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) { // Tests a step timing function if the change of values occur at the start. TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtStart) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); const int num_steps = 36; - const float steps_start_offset = 1.0f; curve->AddKeyframe(FloatKeyframe::Create( base::TimeDelta(), 0.f, - StepsTimingFunction::Create(num_steps, steps_start_offset))); + StepsTimingFunction::Create(num_steps, + StepsTimingFunction::StepPosition::START))); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), num_steps, nullptr)); @@ -473,13 +473,13 @@ TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtStart) { // Tests a step timing function if the change of values occur at the middle. TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtMiddle) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); const int num_steps = 36; - const float steps_start_offset = 0.5f; curve->AddKeyframe(FloatKeyframe::Create( base::TimeDelta(), 0.f, - StepsTimingFunction::Create(num_steps, steps_start_offset))); + StepsTimingFunction::Create(num_steps, + StepsTimingFunction::StepPosition::MIDDLE))); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), num_steps, nullptr)); @@ -505,13 +505,13 @@ TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtMiddle) { // Tests a step timing function if the change of values occur at the end. TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtEnd) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); const int num_steps = 36; - const float steps_start_offset = 0.0f; curve->AddKeyframe(FloatKeyframe::Create( base::TimeDelta(), 0.f, - StepsTimingFunction::Create(num_steps, steps_start_offset))); + StepsTimingFunction::Create(num_steps, + StepsTimingFunction::StepPosition::END))); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), num_steps, nullptr)); @@ -537,7 +537,7 @@ TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtEnd) { // Tests that animated bounds are computed as expected. TEST(KeyframedAnimationCurveTest, AnimatedBounds) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations1; @@ -562,7 +562,7 @@ TEST(KeyframedAnimationCurveTest, AnimatedBounds) { // Tests that animations that affect scale are correctly identified. TEST(KeyframedAnimationCurveTest, AffectsScale) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations1; @@ -593,7 +593,7 @@ TEST(KeyframedAnimationCurveTest, AffectsScale) { // Tests that animations that are translations are correctly identified. TEST(KeyframedAnimationCurveTest, IsTranslation) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations1; @@ -624,7 +624,7 @@ TEST(KeyframedAnimationCurveTest, IsTranslation) { // Tests that maximum target scale is computed as expected. TEST(KeyframedAnimationCurveTest, MaximumTargetScale) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations1; @@ -657,7 +657,7 @@ TEST(KeyframedAnimationCurveTest, MaximumTargetScale) { EXPECT_FALSE(curve->MaximumTargetScale(true, &maximum_scale)); // The original scale is not used in computing the max. - scoped_ptr<KeyframedTransformAnimationCurve> curve2( + std::unique_ptr<KeyframedTransformAnimationCurve> curve2( KeyframedTransformAnimationCurve::Create()); TransformOperations operations4; @@ -679,7 +679,7 @@ TEST(KeyframedAnimationCurveTest, MaximumTargetScale) { // Tests that starting animation scale is computed as expected. TEST(KeyframedAnimationCurveTest, AnimationStartScale) { - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations operations1; @@ -726,7 +726,7 @@ TEST(KeyframedAnimationCurveTest, AnimationStartScale) { // Tests that an animation with a curve timing function works as expected. TEST(KeyframedAnimationCurveTest, CurveTiming) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); curve->AddKeyframe( @@ -747,7 +747,7 @@ TEST(KeyframedAnimationCurveTest, CurveTiming) { // Tests that an animation with a curve and keyframe timing function works as // expected. TEST(KeyframedAnimationCurveTest, CurveAndKeyframeTiming) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create( base::TimeDelta(), 0.f, @@ -775,7 +775,7 @@ TEST(KeyframedAnimationCurveTest, CurveAndKeyframeTiming) { // Tests that a linear timing function works as expected for inputs outside of // range [0,1] TEST(KeyframedAnimationCurveTest, LinearTimingInputsOutsideZeroOneRange) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); curve->AddKeyframe( @@ -794,7 +794,7 @@ TEST(KeyframedAnimationCurveTest, LinearTimingInputsOutsideZeroOneRange) { // the range [0, 1] then a keyframe cubic-bezier timing function // should consume that input properly (using end-point gradients). TEST(KeyframedAnimationCurveTest, CurveTimingInputsOutsideZeroOneRange) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); // Keyframe timing function with 0.5 gradients at each end. curve->AddKeyframe(FloatKeyframe::Create( @@ -820,10 +820,12 @@ TEST(KeyframedAnimationCurveTest, CurveTimingInputsOutsideZeroOneRange) { // Tests that a step timing function works as expected for inputs outside of // range [0,1] TEST(KeyframedAnimationCurveTest, StepsTimingInputsOutsideZeroOneRange) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); - curve->AddKeyframe(FloatKeyframe::Create( - base::TimeDelta(), 0.f, StepsTimingFunction::Create(4, 0.5f))); + curve->AddKeyframe( + FloatKeyframe::Create(base::TimeDelta(), 0.f, + StepsTimingFunction::Create( + 4, StepsTimingFunction::StepPosition::MIDDLE))); curve->AddKeyframe( FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr)); // Curve timing function producing timing outputs outside of range [0,1]. @@ -837,7 +839,7 @@ TEST(KeyframedAnimationCurveTest, StepsTimingInputsOutsideZeroOneRange) { // Tests that an animation with a curve timing function and multiple keyframes // works as expected. TEST(KeyframedAnimationCurveTest, CurveTimingMultipleKeyframes) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); curve->AddKeyframe( @@ -866,7 +868,7 @@ TEST(KeyframedAnimationCurveTest, CurveTimingMultipleKeyframes) { // Tests that an animation with a curve timing function that overshoots works as // expected. TEST(KeyframedAnimationCurveTest, CurveTimingOvershootMultipeKeyframes) { - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); curve->AddKeyframe( diff --git a/chromium/cc/animation/layer_animation_controller.cc b/chromium/cc/animation/layer_animation_controller.cc deleted file mode 100644 index f18a4cec4e8..00000000000 --- a/chromium/cc/animation/layer_animation_controller.cc +++ /dev/null @@ -1,1294 +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/animation/layer_animation_controller.h" - -#include <stddef.h> - -#include <algorithm> -#include <vector> - -#include "cc/animation/animation.h" -#include "cc/animation/animation_curve.h" -#include "cc/animation/animation_delegate.h" -#include "cc/animation/animation_events.h" -#include "cc/animation/animation_registrar.h" -#include "cc/animation/keyframed_animation_curve.h" -#include "cc/animation/layer_animation_value_observer.h" -#include "cc/animation/layer_animation_value_provider.h" -#include "cc/animation/scroll_offset_animation_curve.h" -#include "cc/output/filter_operations.h" -#include "ui/gfx/geometry/box_f.h" -#include "ui/gfx/transform.h" - -namespace cc { - -LayerAnimationController::LayerAnimationController(int id) - : registrar_(0), - id_(id), - is_active_(false), - value_provider_(nullptr), - layer_animation_delegate_(nullptr), - needs_to_start_animations_(false), - scroll_offset_animation_was_interrupted_(false), - potentially_animating_transform_for_active_observers_(false), - potentially_animating_transform_for_pending_observers_(false) {} - -LayerAnimationController::~LayerAnimationController() { - if (registrar_) - registrar_->UnregisterAnimationController(this); -} - -scoped_refptr<LayerAnimationController> LayerAnimationController::Create( - int id) { - return make_scoped_refptr(new LayerAnimationController(id)); -} - -void LayerAnimationController::PauseAnimation(int animation_id, - base::TimeDelta time_offset) { - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->id() == animation_id) { - animations_[i]->SetRunState(Animation::PAUSED, - time_offset + animations_[i]->start_time() + - animations_[i]->time_offset()); - } - } -} - -void LayerAnimationController::UpdatePotentiallyAnimatingTransform() { - bool was_potentially_animating_transform_for_active_observers = - potentially_animating_transform_for_active_observers_; - bool was_potentially_animating_transform_for_pending_observers = - potentially_animating_transform_for_pending_observers_; - - potentially_animating_transform_for_active_observers_ = false; - potentially_animating_transform_for_pending_observers_ = false; - - for (const auto& animation : animations_) { - if (!animation->is_finished() && - animation->target_property() == TargetProperty::TRANSFORM) { - potentially_animating_transform_for_active_observers_ |= - animation->affects_active_observers(); - potentially_animating_transform_for_pending_observers_ |= - animation->affects_pending_observers(); - } - } - - bool changed_for_active_observers = - was_potentially_animating_transform_for_active_observers != - potentially_animating_transform_for_active_observers_; - bool changed_for_pending_observers = - was_potentially_animating_transform_for_pending_observers != - potentially_animating_transform_for_pending_observers_; - - if (!changed_for_active_observers && !changed_for_pending_observers) - return; - - NotifyObserversTransformIsPotentiallyAnimatingChanged( - changed_for_active_observers, changed_for_pending_observers); -} - -void LayerAnimationController::RemoveAnimation(int animation_id) { - bool removed_transform_animation = false; - // Since we want to use the animations that we're going to remove, we need to - // use a stable_parition here instead of remove_if. Remove_if leaves the - // removed items in an unspecified state. - auto animations_to_remove = std::stable_partition( - animations_.begin(), animations_.end(), - [animation_id](const scoped_ptr<Animation>& animation) { - return animation->id() != animation_id; - }); - for (auto it = animations_to_remove; it != animations_.end(); ++it) { - if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) { - scroll_offset_animation_was_interrupted_ = true; - } else if ((*it)->target_property() == TargetProperty::TRANSFORM && - !(*it)->is_finished()) { - removed_transform_animation = true; - } - } - - animations_.erase(animations_to_remove, animations_.end()); - UpdateActivation(NORMAL_ACTIVATION); - if (removed_transform_animation) - UpdatePotentiallyAnimatingTransform(); -} - -void LayerAnimationController::AbortAnimation(int animation_id) { - bool aborted_transform_animation = false; - if (Animation* animation = GetAnimationById(animation_id)) { - if (!animation->is_finished()) { - animation->SetRunState(Animation::ABORTED, last_tick_time_); - if (animation->target_property() == TargetProperty::TRANSFORM) - aborted_transform_animation = true; - } - } - if (aborted_transform_animation) - UpdatePotentiallyAnimatingTransform(); -} - -void LayerAnimationController::AbortAnimations( - TargetProperty::Type target_property, - bool needs_completion) { - if (needs_completion) - DCHECK(target_property == TargetProperty::SCROLL_OFFSET); - - bool aborted_transform_animation = false; - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->target_property() == target_property && - !animations_[i]->is_finished()) { - // Currently only impl-only scroll offset animations can be completed on - // the main thread. - if (needs_completion && animations_[i]->is_impl_only()) { - animations_[i]->SetRunState(Animation::ABORTED_BUT_NEEDS_COMPLETION, - last_tick_time_); - } else { - animations_[i]->SetRunState(Animation::ABORTED, last_tick_time_); - } - if (target_property == TargetProperty::TRANSFORM) - aborted_transform_animation = true; - } - } - if (aborted_transform_animation) - UpdatePotentiallyAnimatingTransform(); -} - -// Ensures that the list of active animations on the main thread and the impl -// thread are kept in sync. -void LayerAnimationController::PushAnimationUpdatesTo( - LayerAnimationController* controller_impl) { - DCHECK(this != controller_impl); - if (!has_any_animation() && !controller_impl->has_any_animation()) - return; - MarkAbortedAnimationsForDeletion(controller_impl); - PurgeAnimationsMarkedForDeletion(); - PushNewAnimationsToImplThread(controller_impl); - - // Remove finished impl side animations only after pushing, - // and only after the animations are deleted on the main thread - // this insures we will never push an animation twice. - RemoveAnimationsCompletedOnMainThread(controller_impl); - - PushPropertiesToImplThread(controller_impl); - controller_impl->UpdateActivation(NORMAL_ACTIVATION); - UpdateActivation(NORMAL_ACTIVATION); -} - -void LayerAnimationController::Animate(base::TimeTicks monotonic_time) { - DCHECK(!monotonic_time.is_null()); - if (!HasValueObserver()) - return; - - if (needs_to_start_animations_) - StartAnimations(monotonic_time); - TickAnimations(monotonic_time); - last_tick_time_ = monotonic_time; -} - -void LayerAnimationController::AccumulatePropertyUpdates( - base::TimeTicks monotonic_time, - AnimationEvents* events) { - if (!events) - return; - - for (size_t i = 0; i < animations_.size(); ++i) { - Animation* animation = animations_[i].get(); - if (!animation->is_impl_only()) - continue; - - if (!animation->InEffect(monotonic_time)) - continue; - - base::TimeDelta trimmed = - animation->TrimTimeToCurrentIteration(monotonic_time); - switch (animation->target_property()) { - case TargetProperty::OPACITY: { - AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_, - animation->group(), TargetProperty::OPACITY, - monotonic_time); - const FloatAnimationCurve* float_animation_curve = - animation->curve()->ToFloatAnimationCurve(); - event.opacity = float_animation_curve->GetValue(trimmed); - event.is_impl_only = true; - events->events_.push_back(event); - break; - } - - case TargetProperty::TRANSFORM: { - AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_, - animation->group(), TargetProperty::TRANSFORM, - monotonic_time); - const TransformAnimationCurve* transform_animation_curve = - animation->curve()->ToTransformAnimationCurve(); - event.transform = transform_animation_curve->GetValue(trimmed); - event.is_impl_only = true; - events->events_.push_back(event); - break; - } - - case TargetProperty::FILTER: { - AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_, - animation->group(), TargetProperty::FILTER, - monotonic_time); - const FilterAnimationCurve* filter_animation_curve = - animation->curve()->ToFilterAnimationCurve(); - event.filters = filter_animation_curve->GetValue(trimmed); - event.is_impl_only = true; - events->events_.push_back(event); - break; - } - - case TargetProperty::BACKGROUND_COLOR: { - break; - } - - case TargetProperty::SCROLL_OFFSET: { - // Impl-side changes to scroll offset are already sent back to the - // main thread (e.g. for user-driven scrolling), so a PROPERTY_UPDATE - // isn't needed. - break; - } - } - } -} - -void LayerAnimationController::UpdateState(bool start_ready_animations, - AnimationEvents* events) { - if (!HasActiveValueObserver()) - return; - - // Animate hasn't been called, this happens if an observer has been added - // between the Commit and Draw phases. - if (last_tick_time_ == base::TimeTicks()) - return; - - if (start_ready_animations) - PromoteStartedAnimations(last_tick_time_, events); - - MarkFinishedAnimations(last_tick_time_); - MarkAnimationsForDeletion(last_tick_time_, events); - - if (needs_to_start_animations_ && start_ready_animations) { - StartAnimations(last_tick_time_); - PromoteStartedAnimations(last_tick_time_, events); - } - - AccumulatePropertyUpdates(last_tick_time_, events); - - UpdateActivation(NORMAL_ACTIVATION); -} - -void LayerAnimationController::ActivateAnimations() { - bool changed_transform_animation = false; - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->affects_active_observers() != - animations_[i]->affects_pending_observers() && - animations_[i]->target_property() == TargetProperty::TRANSFORM) - changed_transform_animation = true; - animations_[i]->set_affects_active_observers( - animations_[i]->affects_pending_observers()); - } - auto affects_no_observers = [](const scoped_ptr<Animation>& animation) { - return !animation->affects_active_observers() && - !animation->affects_pending_observers(); - }; - animations_.erase(std::remove_if(animations_.begin(), animations_.end(), - affects_no_observers), - animations_.end()); - scroll_offset_animation_was_interrupted_ = false; - UpdateActivation(NORMAL_ACTIVATION); - if (changed_transform_animation) - UpdatePotentiallyAnimatingTransform(); -} - -void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) { - bool added_transform_animation = - animation->target_property() == TargetProperty::TRANSFORM; - animations_.push_back(std::move(animation)); - needs_to_start_animations_ = true; - UpdateActivation(NORMAL_ACTIVATION); - if (added_transform_animation) - UpdatePotentiallyAnimatingTransform(); -} - -Animation* LayerAnimationController::GetAnimation( - TargetProperty::Type target_property) const { - for (size_t i = 0; i < animations_.size(); ++i) { - size_t index = animations_.size() - i - 1; - if (animations_[index]->target_property() == target_property) - return animations_[index].get(); - } - return nullptr; -} - -Animation* LayerAnimationController::GetAnimationById(int animation_id) const { - for (size_t i = 0; i < animations_.size(); ++i) - if (animations_[i]->id() == animation_id) - return animations_[i].get(); - return nullptr; -} - -bool LayerAnimationController::HasActiveAnimation() const { - for (size_t i = 0; i < animations_.size(); ++i) { - if (!animations_[i]->is_finished()) - return true; - } - return false; -} - -bool LayerAnimationController::IsPotentiallyAnimatingProperty( - TargetProperty::Type target_property, - ObserverType observer_type) const { - for (size_t i = 0; i < animations_.size(); ++i) { - if (!animations_[i]->is_finished() && - animations_[i]->target_property() == target_property) { - if ((observer_type == ObserverType::ACTIVE && - animations_[i]->affects_active_observers()) || - (observer_type == ObserverType::PENDING && - animations_[i]->affects_pending_observers())) - return true; - } - } - return false; -} - -bool LayerAnimationController::IsCurrentlyAnimatingProperty( - TargetProperty::Type target_property, - ObserverType observer_type) const { - for (size_t i = 0; i < animations_.size(); ++i) { - if (!animations_[i]->is_finished() && - animations_[i]->InEffect(last_tick_time_) && - animations_[i]->target_property() == target_property) { - if ((observer_type == ObserverType::ACTIVE && - animations_[i]->affects_active_observers()) || - (observer_type == ObserverType::PENDING && - animations_[i]->affects_pending_observers())) - return true; - } - } - return false; -} - -void LayerAnimationController::SetAnimationRegistrar( - AnimationRegistrar* registrar) { - if (registrar_ == registrar) - return; - - if (registrar_) - registrar_->UnregisterAnimationController(this); - - registrar_ = registrar; - if (registrar_) - registrar_->RegisterAnimationController(this); - - UpdateActivation(FORCE_ACTIVATION); -} - -void LayerAnimationController::NotifyAnimationStarted( - const AnimationEvent& event) { - if (event.is_impl_only) { - FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, - OnAnimationStarted(event)); - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationStarted( - event.monotonic_time, event.target_property, event.group_id); - return; - } - - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->group() == event.group_id && - animations_[i]->target_property() == event.target_property && - animations_[i]->needs_synchronized_start_time()) { - animations_[i]->set_needs_synchronized_start_time(false); - if (!animations_[i]->has_set_start_time()) - animations_[i]->set_start_time(event.monotonic_time); - - FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, - OnAnimationStarted(event)); - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationStarted( - event.monotonic_time, event.target_property, event.group_id); - - return; - } - } -} - -void LayerAnimationController::NotifyAnimationFinished( - const AnimationEvent& event) { - if (event.is_impl_only) { - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationFinished( - event.monotonic_time, event.target_property, event.group_id); - return; - } - - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->group() == event.group_id && - animations_[i]->target_property() == event.target_property) { - animations_[i]->set_received_finished_event(true); - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationFinished( - event.monotonic_time, event.target_property, event.group_id); - - return; - } - } -} - -void LayerAnimationController::NotifyAnimationTakeover( - const AnimationEvent& event) { - DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET); - if (layer_animation_delegate_) { - scoped_ptr<AnimationCurve> animation_curve = event.curve->Clone(); - layer_animation_delegate_->NotifyAnimationTakeover( - event.monotonic_time, event.target_property, event.animation_start_time, - std::move(animation_curve)); - } -} - -void LayerAnimationController::NotifyAnimationAborted( - const AnimationEvent& event) { - bool aborted_transform_animation = false; - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->group() == event.group_id && - animations_[i]->target_property() == event.target_property) { - animations_[i]->SetRunState(Animation::ABORTED, event.monotonic_time); - animations_[i]->set_received_finished_event(true); - if (layer_animation_delegate_) - layer_animation_delegate_->NotifyAnimationAborted( - event.monotonic_time, event.target_property, event.group_id); - if (event.target_property == TargetProperty::TRANSFORM) - aborted_transform_animation = true; - break; - } - } - if (aborted_transform_animation) - UpdatePotentiallyAnimatingTransform(); -} - -void LayerAnimationController::NotifyAnimationPropertyUpdate( - const AnimationEvent& event) { - bool notify_active_observers = true; - bool notify_pending_observers = true; - switch (event.target_property) { - case TargetProperty::OPACITY: - NotifyObserversOpacityAnimated( - event.opacity, notify_active_observers, notify_pending_observers); - break; - case TargetProperty::TRANSFORM: - NotifyObserversTransformAnimated( - event.transform, notify_active_observers, notify_pending_observers); - break; - default: - NOTREACHED(); - } -} - -void LayerAnimationController::AddValueObserver( - LayerAnimationValueObserver* observer) { - if (!value_observers_.HasObserver(observer)) - value_observers_.AddObserver(observer); -} - -void LayerAnimationController::RemoveValueObserver( - LayerAnimationValueObserver* observer) { - value_observers_.RemoveObserver(observer); -} - -void LayerAnimationController::AddEventObserver( - LayerAnimationEventObserver* observer) { - if (!event_observers_.HasObserver(observer)) - event_observers_.AddObserver(observer); -} - -void LayerAnimationController::RemoveEventObserver( - LayerAnimationEventObserver* observer) { - event_observers_.RemoveObserver(observer); -} - -bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const { - for (size_t i = 0; i < animations_.size(); ++i) { - if (!animations_[i]->is_finished() && - animations_[i]->target_property() == TargetProperty::FILTER && - animations_[i] - ->curve() - ->ToFilterAnimationCurve() - ->HasFilterThatMovesPixels()) - return true; - } - - return false; -} - -bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const { - return IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM, - ObserverType::ACTIVE) || - IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM, - ObserverType::PENDING); -} - -bool LayerAnimationController::FilterAnimationBoundsForBox( - const gfx::BoxF& box, gfx::BoxF* bounds) const { - // TODO(avallee): Implement. - return false; -} - -bool LayerAnimationController::TransformAnimationBoundsForBox( - const gfx::BoxF& box, - gfx::BoxF* bounds) const { - DCHECK(HasTransformAnimationThatInflatesBounds()) - << "TransformAnimationBoundsForBox will give incorrect results if there " - << "are no transform animations affecting bounds, non-animated transform " - << "is not known"; - - // Compute bounds based on animations for which is_finished() is false. - // Do nothing if there are no such animations; in this case, it is assumed - // that callers will take care of computing bounds based on the owning layer's - // actual transform. - *bounds = gfx::BoxF(); - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->is_finished() || - animations_[i]->target_property() != TargetProperty::TRANSFORM) - continue; - - const TransformAnimationCurve* transform_animation_curve = - animations_[i]->curve()->ToTransformAnimationCurve(); - gfx::BoxF animation_bounds; - bool success = - transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds); - if (!success) - return false; - bounds->Union(animation_bounds); - } - - return true; -} - -bool LayerAnimationController::HasAnimationThatAffectsScale() const { - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->is_finished() || - animations_[i]->target_property() != TargetProperty::TRANSFORM) - continue; - - const TransformAnimationCurve* transform_animation_curve = - animations_[i]->curve()->ToTransformAnimationCurve(); - if (transform_animation_curve->AffectsScale()) - return true; - } - - return false; -} - -bool LayerAnimationController::HasOnlyTranslationTransforms( - ObserverType observer_type) const { - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->is_finished() || - animations_[i]->target_property() != TargetProperty::TRANSFORM) - continue; - - if ((observer_type == ObserverType::ACTIVE && - !animations_[i]->affects_active_observers()) || - (observer_type == ObserverType::PENDING && - !animations_[i]->affects_pending_observers())) - continue; - - const TransformAnimationCurve* transform_animation_curve = - animations_[i]->curve()->ToTransformAnimationCurve(); - if (!transform_animation_curve->IsTranslation()) - return false; - } - - return true; -} - -bool LayerAnimationController::AnimationsPreserveAxisAlignment() const { - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->is_finished() || - animations_[i]->target_property() != TargetProperty::TRANSFORM) - continue; - - const TransformAnimationCurve* transform_animation_curve = - animations_[i]->curve()->ToTransformAnimationCurve(); - if (!transform_animation_curve->PreservesAxisAlignment()) - return false; - } - - return true; -} - -bool LayerAnimationController::AnimationStartScale(ObserverType observer_type, - float* start_scale) const { - *start_scale = 0.f; - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->is_finished() || - animations_[i]->target_property() != TargetProperty::TRANSFORM) - continue; - - if ((observer_type == ObserverType::ACTIVE && - !animations_[i]->affects_active_observers()) || - (observer_type == ObserverType::PENDING && - !animations_[i]->affects_pending_observers())) - continue; - - bool forward_direction = true; - switch (animations_[i]->direction()) { - case Animation::DIRECTION_NORMAL: - case Animation::DIRECTION_ALTERNATE: - forward_direction = animations_[i]->playback_rate() >= 0.0; - break; - case Animation::DIRECTION_REVERSE: - case Animation::DIRECTION_ALTERNATE_REVERSE: - forward_direction = animations_[i]->playback_rate() < 0.0; - break; - } - - const TransformAnimationCurve* transform_animation_curve = - animations_[i]->curve()->ToTransformAnimationCurve(); - float animation_start_scale = 0.f; - if (!transform_animation_curve->AnimationStartScale(forward_direction, - &animation_start_scale)) - return false; - *start_scale = std::max(*start_scale, animation_start_scale); - } - return true; -} - -bool LayerAnimationController::MaximumTargetScale(ObserverType observer_type, - float* max_scale) const { - *max_scale = 0.f; - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->is_finished() || - animations_[i]->target_property() != TargetProperty::TRANSFORM) - continue; - - if ((observer_type == ObserverType::ACTIVE && - !animations_[i]->affects_active_observers()) || - (observer_type == ObserverType::PENDING && - !animations_[i]->affects_pending_observers())) - continue; - - bool forward_direction = true; - switch (animations_[i]->direction()) { - case Animation::DIRECTION_NORMAL: - case Animation::DIRECTION_ALTERNATE: - forward_direction = animations_[i]->playback_rate() >= 0.0; - break; - case Animation::DIRECTION_REVERSE: - case Animation::DIRECTION_ALTERNATE_REVERSE: - forward_direction = animations_[i]->playback_rate() < 0.0; - break; - } - - const TransformAnimationCurve* transform_animation_curve = - animations_[i]->curve()->ToTransformAnimationCurve(); - float animation_scale = 0.f; - if (!transform_animation_curve->MaximumTargetScale(forward_direction, - &animation_scale)) - return false; - *max_scale = std::max(*max_scale, animation_scale); - } - - return true; -} - -void LayerAnimationController::PushNewAnimationsToImplThread( - LayerAnimationController* controller_impl) const { - // Any new animations owned by the main thread's controller are cloned and - // add to the impl thread's controller. - for (size_t i = 0; i < animations_.size(); ++i) { - // If the animation is already running on the impl thread, there is no - // need to copy it over. - if (controller_impl->GetAnimationById(animations_[i]->id())) - continue; - - if (animations_[i]->target_property() == TargetProperty::SCROLL_OFFSET && - !animations_[i] - ->curve() - ->ToScrollOffsetAnimationCurve() - ->HasSetInitialValue()) { - gfx::ScrollOffset current_scroll_offset; - if (controller_impl->value_provider_) { - current_scroll_offset = - controller_impl->value_provider_->ScrollOffsetForAnimation(); - } else { - // The owning layer isn't yet in the active tree, so the main thread - // scroll offset will be up-to-date. - current_scroll_offset = value_provider_->ScrollOffsetForAnimation(); - } - animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue( - current_scroll_offset); - } - - // The new animation should be set to run as soon as possible. - Animation::RunState initial_run_state = - Animation::WAITING_FOR_TARGET_AVAILABILITY; - scoped_ptr<Animation> to_add( - animations_[i]->CloneAndInitialize(initial_run_state)); - DCHECK(!to_add->needs_synchronized_start_time()); - to_add->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(to_add)); - } -} - -static bool IsCompleted( - Animation* animation, - const LayerAnimationController* main_thread_controller) { - if (animation->is_impl_only()) { - return (animation->run_state() == Animation::WAITING_FOR_DELETION); - } else { - return !main_thread_controller->GetAnimationById(animation->id()); - } -} - -void LayerAnimationController::RemoveAnimationsCompletedOnMainThread( - LayerAnimationController* controller_impl) const { - bool removed_transform_animation = false; - // Animations removed on the main thread should no longer affect pending - // observers, and should stop affecting active observers after the next call - // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed - // immediately. - auto& animations = controller_impl->animations_; - for (const auto& animation : animations) { - if (IsCompleted(animation.get(), this)) { - animation->set_affects_pending_observers(false); - if (animation->target_property() == TargetProperty::TRANSFORM) - removed_transform_animation = true; - } - } - auto affects_active_only_and_is_waiting_for_deletion = []( - const scoped_ptr<Animation>& animation) { - return animation->run_state() == Animation::WAITING_FOR_DELETION && - !animation->affects_pending_observers(); - }; - animations.erase( - std::remove_if(animations.begin(), animations.end(), - affects_active_only_and_is_waiting_for_deletion), - animations.end()); - - if (removed_transform_animation) - controller_impl->UpdatePotentiallyAnimatingTransform(); -} - -void LayerAnimationController::PushPropertiesToImplThread( - LayerAnimationController* controller_impl) { - for (size_t i = 0; i < animations_.size(); ++i) { - Animation* current_impl = - controller_impl->GetAnimationById(animations_[i]->id()); - if (current_impl) - animations_[i]->PushPropertiesTo(current_impl); - } - controller_impl->scroll_offset_animation_was_interrupted_ = - scroll_offset_animation_was_interrupted_; - scroll_offset_animation_was_interrupted_ = false; -} - -void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) { - DCHECK(needs_to_start_animations_); - needs_to_start_animations_ = false; - // First collect running properties affecting each type of observer. - TargetProperties blocked_properties_for_active_observers; - TargetProperties blocked_properties_for_pending_observers; - std::vector<size_t> animations_waiting_for_target; - - animations_waiting_for_target.reserve(animations_.size()); - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->run_state() == Animation::STARTING || - animations_[i]->run_state() == Animation::RUNNING) { - if (animations_[i]->affects_active_observers()) { - blocked_properties_for_active_observers[animations_[i] - ->target_property()] = true; - } - if (animations_[i]->affects_pending_observers()) { - blocked_properties_for_pending_observers[animations_[i] - ->target_property()] = - true; - } - } else if (animations_[i]->run_state() == - Animation::WAITING_FOR_TARGET_AVAILABILITY) { - animations_waiting_for_target.push_back(i); - } - } - - for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) { - // Collect all properties for animations with the same group id (they - // should all also be in the list of animations). - size_t animation_index = animations_waiting_for_target[i]; - Animation* animation_waiting_for_target = - animations_[animation_index].get(); - // Check for the run state again even though the animation was waiting - // for target because it might have changed the run state while handling - // previous animation in this loop (if they belong to same group). - if (animation_waiting_for_target->run_state() == - Animation::WAITING_FOR_TARGET_AVAILABILITY) { - TargetProperties enqueued_properties; - bool affects_active_observers = - animation_waiting_for_target->affects_active_observers(); - bool affects_pending_observers = - animation_waiting_for_target->affects_pending_observers(); - enqueued_properties[animation_waiting_for_target->target_property()] = - true; - for (size_t j = animation_index + 1; j < animations_.size(); ++j) { - if (animation_waiting_for_target->group() == animations_[j]->group()) { - enqueued_properties[animations_[j]->target_property()] = true; - affects_active_observers |= - animations_[j]->affects_active_observers(); - affects_pending_observers |= - animations_[j]->affects_pending_observers(); - } - } - - // Check to see if intersection of the list of properties affected by - // the group and the list of currently blocked properties is null, taking - // into account the type(s) of observers affected by the group. In any - // case, the group's target properties need to be added to the lists of - // blocked properties. - bool null_intersection = true; - static_assert(TargetProperty::FIRST_TARGET_PROPERTY == 0, - "TargetProperty must be 0-based enum"); - for (int property = TargetProperty::FIRST_TARGET_PROPERTY; - property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { - if (enqueued_properties[property]) { - if (affects_active_observers) { - if (blocked_properties_for_active_observers[property]) - null_intersection = false; - else - blocked_properties_for_active_observers[property] = true; - } - if (affects_pending_observers) { - if (blocked_properties_for_pending_observers[property]) - null_intersection = false; - else - blocked_properties_for_pending_observers[property] = true; - } - } - } - - // If the intersection is null, then we are free to start the animations - // in the group. - if (null_intersection) { - animation_waiting_for_target->SetRunState(Animation::STARTING, - monotonic_time); - for (size_t j = animation_index + 1; j < animations_.size(); ++j) { - if (animation_waiting_for_target->group() == - animations_[j]->group()) { - animations_[j]->SetRunState(Animation::STARTING, monotonic_time); - } - } - } else { - needs_to_start_animations_ = true; - } - } - } -} - -void LayerAnimationController::PromoteStartedAnimations( - base::TimeTicks monotonic_time, - AnimationEvents* events) { - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->run_state() == Animation::STARTING && - animations_[i]->affects_active_observers()) { - animations_[i]->SetRunState(Animation::RUNNING, monotonic_time); - if (!animations_[i]->has_set_start_time() && - !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(), start_time); - started_event.is_impl_only = animations_[i]->is_impl_only(); - if (started_event.is_impl_only) - NotifyAnimationStarted(started_event); - else - events->events_.push_back(started_event); - } - } - } -} - -void LayerAnimationController::MarkFinishedAnimations( - base::TimeTicks monotonic_time) { - bool finished_transform_animation = false; - for (size_t i = 0; i < animations_.size(); ++i) { - if (!animations_[i]->is_finished() && - animations_[i]->IsFinishedAt(monotonic_time)) { - animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); - if (animations_[i]->target_property() == TargetProperty::TRANSFORM) { - finished_transform_animation = true; - } - } - } - if (finished_transform_animation) - UpdatePotentiallyAnimatingTransform(); -} - -void LayerAnimationController::MarkAnimationsForDeletion( - base::TimeTicks monotonic_time, - AnimationEvents* events) { - bool marked_animations_for_deletions = false; - std::vector<size_t> animations_with_same_group_id; - - animations_with_same_group_id.reserve(animations_.size()); - // Non-aborted animations are marked for deletion after a corresponding - // AnimationEvent::FINISHED event is sent or received. This means that if - // we don't have an events vector, we must ensure that non-aborted animations - // have received a finished event before marking them for deletion. - for (size_t i = 0; i < animations_.size(); i++) { - int group_id = animations_[i]->group(); - if (animations_[i]->run_state() == Animation::ABORTED) { - if (events && !animations_[i]->is_impl_only()) { - AnimationEvent aborted_event(AnimationEvent::ABORTED, id_, group_id, - animations_[i]->target_property(), - monotonic_time); - events->events_.push_back(aborted_event); - } - // If on the compositor or on the main thread and received finish event, - // animation can be marked for deletion. - if (events || animations_[i]->received_finished_event()) { - animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION, - monotonic_time); - marked_animations_for_deletions = true; - } - continue; - } - - // If running on the compositor and need to complete an aborted animation - // on the main thread. - if (events && - animations_[i]->run_state() == - Animation::ABORTED_BUT_NEEDS_COMPLETION) { - AnimationEvent aborted_event(AnimationEvent::TAKEOVER, id_, group_id, - animations_[i]->target_property(), - monotonic_time); - aborted_event.animation_start_time = - (animations_[i]->start_time() - base::TimeTicks()).InSecondsF(); - const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = - animations_[i]->curve()->ToScrollOffsetAnimationCurve(); - aborted_event.curve = scroll_offset_animation_curve->Clone(); - // Notify the compositor that the animation is finished. - if (layer_animation_delegate_) { - layer_animation_delegate_->NotifyAnimationFinished( - aborted_event.monotonic_time, aborted_event.target_property, - aborted_event.group_id); - } - // Notify main thread. - events->events_.push_back(aborted_event); - - // Remove the animation from the compositor. - animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION, - monotonic_time); - marked_animations_for_deletions = true; - continue; - } - - bool all_anims_with_same_id_are_finished = false; - - // Since deleting an animation on the main thread leads to its deletion - // 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 = - 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 && - animation_i_will_send_or_has_received_finish_event) { - // Clear the animations_with_same_group_id if it was added for - // the previous animation's iteration. - if (animations_with_same_group_id.size() > 0) - animations_with_same_group_id.clear(); - 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 = - 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 && - !animation_j_will_send_or_has_received_finish_event)) { - all_anims_with_same_id_are_finished = false; - break; - } else if (j >= i && - animations_[j]->run_state() != Animation::ABORTED) { - // Mark down the animations which belong to the same group - // and is not yet aborted. If this current iteration finds that all - // animations with same ID are finished, then the marked - // animations below will be set to WAITING_FOR_DELETION in next - // iteration. - animations_with_same_group_id.push_back(j); - } - } - } - } - if (all_anims_with_same_id_are_finished) { - // We now need to remove all animations with the same group id as - // group_id (and send along animation finished notifications, if - // necessary). - for (size_t j = 0; j < animations_with_same_group_id.size(); j++) { - size_t animation_index = animations_with_same_group_id[j]; - if (events) { - AnimationEvent finished_event( - AnimationEvent::FINISHED, id_, - animations_[animation_index]->group(), - animations_[animation_index]->target_property(), - monotonic_time); - finished_event.is_impl_only = - animations_[animation_index]->is_impl_only(); - if (finished_event.is_impl_only) - NotifyAnimationFinished(finished_event); - else - events->events_.push_back(finished_event); - } - animations_[animation_index]->SetRunState( - Animation::WAITING_FOR_DELETION, monotonic_time); - } - marked_animations_for_deletions = true; - } - } - if (marked_animations_for_deletions) - NotifyObserversAnimationWaitingForDeletion(); -} - -void LayerAnimationController::MarkAbortedAnimationsForDeletion( - LayerAnimationController* controller_impl) const { - bool aborted_transform_animation = false; - auto& animations_impl = controller_impl->animations_; - for (const auto& animation_impl : animations_impl) { - // If the animation has been aborted on the main thread, mark it for - // deletion. - if (Animation* animation = GetAnimationById(animation_impl->id())) { - if (animation->run_state() == Animation::ABORTED) { - animation_impl->SetRunState(Animation::WAITING_FOR_DELETION, - controller_impl->last_tick_time_); - animation->SetRunState(Animation::WAITING_FOR_DELETION, - last_tick_time_); - if (animation_impl->target_property() == TargetProperty::TRANSFORM) { - aborted_transform_animation = true; - } - } - } - } - - if (aborted_transform_animation) - controller_impl->UpdatePotentiallyAnimatingTransform(); -} - -void LayerAnimationController::PurgeAnimationsMarkedForDeletion() { - animations_.erase(std::remove_if(animations_.begin(), animations_.end(), - [](const scoped_ptr<Animation>& animation) { - return animation->run_state() == - Animation::WAITING_FOR_DELETION; - }), - animations_.end()); -} - -void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) { - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->run_state() == Animation::STARTING || - animations_[i]->run_state() == Animation::RUNNING || - animations_[i]->run_state() == Animation::PAUSED) { - if (!animations_[i]->InEffect(monotonic_time)) - continue; - - base::TimeDelta trimmed = - animations_[i]->TrimTimeToCurrentIteration(monotonic_time); - - switch (animations_[i]->target_property()) { - case TargetProperty::TRANSFORM: { - const TransformAnimationCurve* transform_animation_curve = - animations_[i]->curve()->ToTransformAnimationCurve(); - const gfx::Transform transform = - transform_animation_curve->GetValue(trimmed); - NotifyObserversTransformAnimated( - transform, - animations_[i]->affects_active_observers(), - animations_[i]->affects_pending_observers()); - break; - } - - case TargetProperty::OPACITY: { - const FloatAnimationCurve* float_animation_curve = - animations_[i]->curve()->ToFloatAnimationCurve(); - const float opacity = std::max( - std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f); - NotifyObserversOpacityAnimated( - opacity, - animations_[i]->affects_active_observers(), - animations_[i]->affects_pending_observers()); - break; - } - - case TargetProperty::FILTER: { - const FilterAnimationCurve* filter_animation_curve = - animations_[i]->curve()->ToFilterAnimationCurve(); - const FilterOperations filter = - filter_animation_curve->GetValue(trimmed); - NotifyObserversFilterAnimated( - filter, - animations_[i]->affects_active_observers(), - animations_[i]->affects_pending_observers()); - break; - } - - case TargetProperty::BACKGROUND_COLOR: { - // Not yet implemented. - break; - } - - case TargetProperty::SCROLL_OFFSET: { - const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = - animations_[i]->curve()->ToScrollOffsetAnimationCurve(); - const gfx::ScrollOffset scroll_offset = - scroll_offset_animation_curve->GetValue(trimmed); - NotifyObserversScrollOffsetAnimated( - scroll_offset, - animations_[i]->affects_active_observers(), - animations_[i]->affects_pending_observers()); - break; - } - } - } - } -} - -void LayerAnimationController::UpdateActivation(UpdateActivationType type) { - bool force = type == FORCE_ACTIVATION; - if (registrar_) { - bool was_active = is_active_; - is_active_ = false; - for (size_t i = 0; i < animations_.size(); ++i) { - if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) { - is_active_ = true; - break; - } - } - - if (is_active_ && (!was_active || force)) - registrar_->DidActivateAnimationController(this); - else if (!is_active_ && (was_active || force)) - registrar_->DidDeactivateAnimationController(this); - } -} - -void LayerAnimationController::NotifyObserversOpacityAnimated( - float opacity, - bool notify_active_observers, - bool notify_pending_observers) { - if (value_observers_.might_have_observers()) { - base::ObserverListBase<LayerAnimationValueObserver>::Iterator it( - &value_observers_); - LayerAnimationValueObserver* obs; - while ((obs = it.GetNext()) != nullptr) { - if ((notify_active_observers && notify_pending_observers) || - (notify_active_observers && obs->IsActive()) || - (notify_pending_observers && !obs->IsActive())) - obs->OnOpacityAnimated(opacity); - } - } -} - -void LayerAnimationController::NotifyObserversTransformAnimated( - const gfx::Transform& transform, - bool notify_active_observers, - bool notify_pending_observers) { - if (value_observers_.might_have_observers()) { - base::ObserverListBase<LayerAnimationValueObserver>::Iterator it( - &value_observers_); - LayerAnimationValueObserver* obs; - while ((obs = it.GetNext()) != nullptr) { - if ((notify_active_observers && notify_pending_observers) || - (notify_active_observers && obs->IsActive()) || - (notify_pending_observers && !obs->IsActive())) - obs->OnTransformAnimated(transform); - } - } -} - -void LayerAnimationController::NotifyObserversFilterAnimated( - const FilterOperations& filters, - bool notify_active_observers, - bool notify_pending_observers) { - if (value_observers_.might_have_observers()) { - base::ObserverListBase<LayerAnimationValueObserver>::Iterator it( - &value_observers_); - LayerAnimationValueObserver* obs; - while ((obs = it.GetNext()) != nullptr) { - if ((notify_active_observers && notify_pending_observers) || - (notify_active_observers && obs->IsActive()) || - (notify_pending_observers && !obs->IsActive())) - obs->OnFilterAnimated(filters); - } - } -} - -void LayerAnimationController::NotifyObserversScrollOffsetAnimated( - const gfx::ScrollOffset& scroll_offset, - bool notify_active_observers, - bool notify_pending_observers) { - if (value_observers_.might_have_observers()) { - base::ObserverListBase<LayerAnimationValueObserver>::Iterator it( - &value_observers_); - LayerAnimationValueObserver* obs; - while ((obs = it.GetNext()) != nullptr) { - if ((notify_active_observers && notify_pending_observers) || - (notify_active_observers && obs->IsActive()) || - (notify_pending_observers && !obs->IsActive())) - obs->OnScrollOffsetAnimated(scroll_offset); - } - } -} - -void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() { - FOR_EACH_OBSERVER(LayerAnimationValueObserver, - value_observers_, - OnAnimationWaitingForDeletion()); -} - -void LayerAnimationController:: - NotifyObserversTransformIsPotentiallyAnimatingChanged( - bool notify_active_observers, - bool notify_pending_observers) { - if (value_observers_.might_have_observers()) { - base::ObserverListBase<LayerAnimationValueObserver>::Iterator it( - &value_observers_); - LayerAnimationValueObserver* obs; - while ((obs = it.GetNext()) != nullptr) { - if (notify_active_observers && obs->IsActive()) - obs->OnTransformIsPotentiallyAnimatingChanged( - potentially_animating_transform_for_active_observers_); - else if (notify_pending_observers && !obs->IsActive()) - obs->OnTransformIsPotentiallyAnimatingChanged( - potentially_animating_transform_for_pending_observers_); - } - } -} - -bool LayerAnimationController::HasValueObserver() { - if (value_observers_.might_have_observers()) { - base::ObserverListBase<LayerAnimationValueObserver>::Iterator it( - &value_observers_); - return it.GetNext() != nullptr; - } - return false; -} - -bool LayerAnimationController::HasActiveValueObserver() { - if (value_observers_.might_have_observers()) { - base::ObserverListBase<LayerAnimationValueObserver>::Iterator it( - &value_observers_); - LayerAnimationValueObserver* obs; - while ((obs = it.GetNext()) != nullptr) - if (obs->IsActive()) - return true; - } - return false; -} - -} // namespace cc diff --git a/chromium/cc/animation/layer_animation_controller.h b/chromium/cc/animation/layer_animation_controller.h deleted file mode 100644 index 2676d812f13..00000000000 --- a/chromium/cc/animation/layer_animation_controller.h +++ /dev/null @@ -1,259 +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_ANIMATION_LAYER_ANIMATION_CONTROLLER_H_ -#define CC_ANIMATION_LAYER_ANIMATION_CONTROLLER_H_ - -#include <bitset> -#include <vector> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/observer_list.h" -#include "base/time/time.h" -#include "cc/animation/animation.h" -#include "cc/animation/layer_animation_event_observer.h" -#include "cc/animation/target_property.h" -#include "cc/base/cc_export.h" -#include "ui/gfx/geometry/scroll_offset.h" -#include "ui/gfx/transform.h" - -namespace gfx { -class BoxF; -class Transform; -} - -namespace cc { - -class AnimationDelegate; -class AnimationEvents; -class AnimationRegistrar; -class FilterOperations; -class KeyframeValueList; -class LayerAnimationValueObserver; -class LayerAnimationValueProvider; - -class CC_EXPORT LayerAnimationController - : public base::RefCounted<LayerAnimationController> { - public: - enum class ObserverType { ACTIVE, PENDING }; - - static scoped_refptr<LayerAnimationController> Create(int id); - - int id() const { return id_; } - - void AddAnimation(scoped_ptr<Animation> animation); - void PauseAnimation(int animation_id, base::TimeDelta time_offset); - void RemoveAnimation(int animation_id); - void AbortAnimation(int animation_id); - void AbortAnimations(TargetProperty::Type target_property, - bool needs_completion = false); - - // Ensures that the list of active animations on the main thread and the impl - // thread are kept in sync. This function does not take ownership of the impl - // thread controller. - void PushAnimationUpdatesTo(LayerAnimationController* controller_impl); - - void Animate(base::TimeTicks monotonic_time); - void AccumulatePropertyUpdates(base::TimeTicks monotonic_time, - AnimationEvents* events); - - void UpdateState(bool start_ready_animations, AnimationEvents* events); - - // Make animations affect active observers if and only if they affect - // pending observers. Any animations that no longer affect any observers - // are deleted. - void ActivateAnimations(); - - // Returns the active animation animating the given property that is either - // running, or is next to run, if such an animation exists. - Animation* GetAnimation(TargetProperty::Type target_property) const; - - // Returns the active animation for the given unique animation id. - Animation* GetAnimationById(int animation_id) const; - - // Returns true if there are any animations that have neither finished nor - // aborted. - bool HasActiveAnimation() const; - - // Returns true if there are any animations at all to process. - bool has_any_animation() const { return !animations_.empty(); } - - // Returns true if there is an animation that is either currently animating - // the given property or scheduled to animate this property in the future, and - // that affects the given observer type. - bool IsPotentiallyAnimatingProperty(TargetProperty::Type target_property, - ObserverType observer_type) const; - - // Returns true if there is an animation that is currently animating the given - // property and that affects the given observer type. - bool IsCurrentlyAnimatingProperty(TargetProperty::Type target_property, - ObserverType observer_type) const; - - void SetAnimationRegistrar(AnimationRegistrar* registrar); - AnimationRegistrar* animation_registrar() { return registrar_; } - - void NotifyAnimationStarted(const AnimationEvent& event); - void NotifyAnimationFinished(const AnimationEvent& event); - void NotifyAnimationAborted(const AnimationEvent& event); - void NotifyAnimationPropertyUpdate(const AnimationEvent& event); - void NotifyAnimationTakeover(const AnimationEvent& event); - - void AddValueObserver(LayerAnimationValueObserver* observer); - void RemoveValueObserver(LayerAnimationValueObserver* observer); - - void AddEventObserver(LayerAnimationEventObserver* observer); - void RemoveEventObserver(LayerAnimationEventObserver* observer); - - void set_value_provider(LayerAnimationValueProvider* provider) { - value_provider_ = provider; - } - - void remove_value_provider(LayerAnimationValueProvider* provider) { - if (value_provider_ == provider) - value_provider_ = nullptr; - } - - void set_layer_animation_delegate(AnimationDelegate* delegate) { - layer_animation_delegate_ = delegate; - } - - void remove_layer_animation_delegate(AnimationDelegate* delegate) { - if (layer_animation_delegate_ == delegate) - layer_animation_delegate_ = nullptr; - } - - bool HasFilterAnimationThatInflatesBounds() const; - bool HasTransformAnimationThatInflatesBounds() const; - bool HasAnimationThatInflatesBounds() const { - return HasTransformAnimationThatInflatesBounds() || - HasFilterAnimationThatInflatesBounds(); - } - - bool FilterAnimationBoundsForBox(const gfx::BoxF& box, - gfx::BoxF* bounds) const; - bool TransformAnimationBoundsForBox(const gfx::BoxF& box, - gfx::BoxF* bounds) const; - - bool HasAnimationThatAffectsScale() const; - - bool HasOnlyTranslationTransforms(ObserverType observer_type) const; - - bool AnimationsPreserveAxisAlignment() const; - - // Sets |start_scale| to the maximum of starting animation scale along any - // dimension at any destination in active animations. Returns false if the - // starting scale cannot be computed. - bool AnimationStartScale(ObserverType observer_type, - float* start_scale) const; - - // Sets |max_scale| to the maximum scale along any dimension at any - // destination in active animations. Returns false if the maximum scale cannot - // be computed. - bool MaximumTargetScale(ObserverType event_observers_, - float* max_scale) const; - - // When a scroll animation is removed on the main thread, its compositor - // thread counterpart continues producing scroll deltas until activation. - // These scroll deltas need to be cleared at activation, so that the active - // layer's scroll offset matches the offset provided by the main thread - // rather than a combination of this offset and scroll deltas produced by - // the removed animation. This is to provide the illusion of synchronicity to - // JS that simultaneously removes an animation and sets the scroll offset. - bool scroll_offset_animation_was_interrupted() const { - return scroll_offset_animation_was_interrupted_; - } - - bool needs_to_start_animations_for_testing() { - return needs_to_start_animations_; - } - - private: - friend class base::RefCounted<LayerAnimationController>; - - explicit LayerAnimationController(int id); - ~LayerAnimationController(); - - // A set of target properties. TargetProperty must be 0-based enum. - using TargetProperties = - std::bitset<TargetProperty::LAST_TARGET_PROPERTY + 1>; - - void PushNewAnimationsToImplThread( - LayerAnimationController* controller_impl) const; - void MarkAbortedAnimationsForDeletion( - LayerAnimationController* controller_impl) const; - void RemoveAnimationsCompletedOnMainThread( - LayerAnimationController* controller_impl) const; - void PushPropertiesToImplThread(LayerAnimationController* controller_impl); - - void StartAnimations(base::TimeTicks monotonic_time); - void PromoteStartedAnimations(base::TimeTicks monotonic_time, - AnimationEvents* events); - void MarkFinishedAnimations(base::TimeTicks monotonic_time); - void MarkAnimationsForDeletion(base::TimeTicks monotonic_time, - AnimationEvents* events); - void PurgeAnimationsMarkedForDeletion(); - - void TickAnimations(base::TimeTicks monotonic_time); - - enum UpdateActivationType { NORMAL_ACTIVATION, FORCE_ACTIVATION }; - void UpdateActivation(UpdateActivationType type); - - void NotifyObserversOpacityAnimated(float opacity, - bool notify_active_observers, - bool notify_pending_observers); - void NotifyObserversTransformAnimated(const gfx::Transform& transform, - bool notify_active_observers, - bool notify_pending_observers); - void NotifyObserversFilterAnimated(const FilterOperations& filter, - bool notify_active_observers, - bool notify_pending_observers); - void NotifyObserversScrollOffsetAnimated( - const gfx::ScrollOffset& scroll_offset, - bool notify_active_observers, - bool notify_pending_observers); - - void NotifyObserversAnimationWaitingForDeletion(); - - void NotifyObserversTransformIsPotentiallyAnimatingChanged( - bool notify_active_observers, - bool notify_pending_observers); - - void UpdatePotentiallyAnimatingTransform(); - - bool HasValueObserver(); - bool HasActiveValueObserver(); - - AnimationRegistrar* registrar_; - int id_; - std::vector<scoped_ptr<Animation>> animations_; - - // This is used to ensure that we don't spam the registrar. - bool is_active_; - - base::TimeTicks last_tick_time_; - - base::ObserverList<LayerAnimationValueObserver> value_observers_; - base::ObserverList<LayerAnimationEventObserver> event_observers_; - - LayerAnimationValueProvider* value_provider_; - - AnimationDelegate* layer_animation_delegate_; - - // Only try to start animations when new animations are added or when the - // previous attempt at starting animations failed to start all animations. - bool needs_to_start_animations_; - - bool scroll_offset_animation_was_interrupted_; - - bool potentially_animating_transform_for_active_observers_; - bool potentially_animating_transform_for_pending_observers_; - - DISALLOW_COPY_AND_ASSIGN(LayerAnimationController); -}; - -} // namespace cc - -#endif // CC_ANIMATION_LAYER_ANIMATION_CONTROLLER_H_ diff --git a/chromium/cc/animation/layer_animation_controller_unittest.cc b/chromium/cc/animation/layer_animation_controller_unittest.cc deleted file mode 100644 index 5390d1b569f..00000000000 --- a/chromium/cc/animation/layer_animation_controller_unittest.cc +++ /dev/null @@ -1,3101 +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/animation/layer_animation_controller.h" - -#include <stddef.h> - -#include "cc/animation/animation.h" -#include "cc/animation/animation_curve.h" -#include "cc/animation/animation_delegate.h" -#include "cc/animation/animation_events.h" -#include "cc/animation/animation_registrar.h" -#include "cc/animation/keyframed_animation_curve.h" -#include "cc/animation/scroll_offset_animation_curve.h" -#include "cc/animation/transform_operations.h" -#include "cc/test/animation_test_common.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/geometry/box_f.h" -#include "ui/gfx/transform.h" - -namespace cc { -namespace { - -using base::TimeDelta; -using base::TimeTicks; - -static base::TimeTicks TicksFromSecondsF(double seconds) { - return base::TimeTicks::FromInternalValue(seconds * - base::Time::kMicrosecondsPerSecond); -} - -// A LayerAnimationController cannot be ticked at 0.0, since an animation -// with start time 0.0 is treated as an animation whose start time has -// not yet been set. -const TimeTicks kInitialTickTime = TicksFromSecondsF(1.0); - -scoped_ptr<Animation> CreateAnimation(scoped_ptr<AnimationCurve> curve, - int group_id, - TargetProperty::Type property) { - return Animation::Create(std::move(curve), 0, group_id, property); -} - -TEST(LayerAnimationControllerTest, SyncNewAnimation) { - 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); - - EXPECT_FALSE(controller_impl->GetAnimation(TargetProperty::OPACITY)); - - EXPECT_FALSE(controller->needs_to_start_animations_for_testing()); - EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing()); - - int animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0, 1, false); - EXPECT_TRUE(controller->needs_to_start_animations_for_testing()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_TRUE(controller_impl->needs_to_start_animations_for_testing()); - controller_impl->ActivateAnimations(); - - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)); - EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, - controller_impl->GetAnimationById(animation_id)->run_state()); -} - -TEST(LayerAnimationControllerTest, - SyncScrollOffsetAnimationRespectsHasSetInitialValue) { - FakeLayerAnimationValueObserver dummy_impl; - FakeLayerAnimationValueProvider dummy_provider_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - controller_impl->set_value_provider(&dummy_provider_impl); - FakeLayerAnimationValueObserver dummy; - FakeLayerAnimationValueProvider dummy_provider; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - controller->set_value_provider(&dummy_provider); - - EXPECT_FALSE(controller_impl->GetAnimation(TargetProperty::SCROLL_OFFSET)); - - EXPECT_FALSE(controller->needs_to_start_animations_for_testing()); - EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing()); - - gfx::ScrollOffset initial_value(100.f, 300.f); - gfx::ScrollOffset provider_initial_value(150.f, 300.f); - gfx::ScrollOffset target_value(300.f, 200.f); - - dummy_provider_impl.set_scroll_offset(provider_initial_value); - - // Animation with initial value set. - scoped_ptr<ScrollOffsetAnimationCurve> curve_fixed( - ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create())); - curve_fixed->SetInitialValue(initial_value); - scoped_ptr<Animation> animation_fixed( - Animation::Create(std::move(curve_fixed), 1 /* animation_id */, 0, - TargetProperty::SCROLL_OFFSET)); - controller->AddAnimation(std::move(animation_fixed)); - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_VECTOR2DF_EQ(initial_value, controller_impl->GetAnimationById(1) - ->curve() - ->ToScrollOffsetAnimationCurve() - ->GetValue(base::TimeDelta())); - - // Animation without initial value set. - scoped_ptr<ScrollOffsetAnimationCurve> curve( - ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create())); - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve), 2 /* animation id */, 0, - TargetProperty::SCROLL_OFFSET)); - controller->AddAnimation(std::move(animation)); - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_VECTOR2DF_EQ(provider_initial_value, - controller_impl->GetAnimationById(2) - ->curve() - ->ToScrollOffsetAnimationCurve() - ->GetValue(base::TimeDelta())); -} - -// If an animation is started on the impl thread before it is ticked on the main -// thread, we must be sure to respect the synchronized start time. -TEST(LayerAnimationControllerTest, DoNotClobberStartTimes) { - 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); - - EXPECT_FALSE(controller_impl->GetAnimation(TargetProperty::OPACITY)); - - int animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0, 1, false); - - 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()); - - AnimationEvents events; - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, &events); - - // Synchronize the start times. - EXPECT_EQ(1u, events.events_.size()); - controller->NotifyAnimationStarted(events.events_[0]); - EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(), - controller_impl->GetAnimationById(animation_id)->start_time()); - - // Start the animation on the main thread. Should not affect the start time. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller->UpdateState(true, nullptr); - EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(), - controller_impl->GetAnimationById(animation_id)->start_time()); -} - -TEST(LayerAnimationControllerTest, UseSpecifiedStartTimes) { - 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); - - int animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0, 1, false); - - const TimeTicks start_time = TicksFromSecondsF(123); - controller->GetAnimation(TargetProperty::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()); - - AnimationEvents events; - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, &events); - - // Synchronize the start times. - EXPECT_EQ(1u, events.events_.size()); - controller->NotifyAnimationStarted(events.events_[0]); - - EXPECT_EQ(start_time, - controller->GetAnimationById(animation_id)->start_time()); - EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(), - controller_impl->GetAnimationById(animation_id)->start_time()); - - // Start the animation on the main thread. Should not affect the start time. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller->UpdateState(true, nullptr); - EXPECT_EQ(start_time, - controller->GetAnimationById(animation_id)->start_time()); - EXPECT_EQ(controller->GetAnimationById(animation_id)->start_time(), - controller_impl->GetAnimationById(animation_id)->start_time()); -} - -// Tests that controllers activate and deactivate as expected. -TEST(LayerAnimationControllerTest, Activation) { - scoped_ptr<AnimationRegistrar> registrar = AnimationRegistrar::Create(); - scoped_ptr<AnimationRegistrar> registrar_impl = AnimationRegistrar::Create(); - - 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); - scoped_ptr<AnimationEvents> events = registrar->CreateEvents(); - - controller->SetAnimationRegistrar(registrar.get()); - controller_impl->SetAnimationRegistrar(registrar_impl.get()); - EXPECT_EQ(1u, registrar->all_animation_controllers_for_testing().size()); - EXPECT_EQ(1u, registrar_impl->all_animation_controllers_for_testing().size()); - - // Initially, both controllers should be inactive. - EXPECT_EQ(0u, registrar->active_animation_controllers_for_testing().size()); - EXPECT_EQ(0u, - registrar_impl->active_animation_controllers_for_testing().size()); - - AddOpacityTransitionToController(controller.get(), 1, 0, 1, false); - // The main thread controller should now be active. - EXPECT_EQ(1u, registrar->active_animation_controllers_for_testing().size()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - // Both controllers should now be active. - EXPECT_EQ(1u, registrar->active_animation_controllers_for_testing().size()); - EXPECT_EQ(1u, - registrar_impl->active_animation_controllers_for_testing().size()); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_EQ(1u, events->events_.size()); - controller->NotifyAnimationStarted(events->events_[0]); - - EXPECT_EQ(1u, registrar->active_animation_controllers_for_testing().size()); - EXPECT_EQ(1u, - registrar_impl->active_animation_controllers_for_testing().size()); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller->UpdateState(true, nullptr); - EXPECT_EQ(1u, registrar->active_animation_controllers_for_testing().size()); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, nullptr); - EXPECT_EQ(Animation::FINISHED, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - EXPECT_EQ(1u, registrar->active_animation_controllers_for_testing().size()); - - events.reset(new AnimationEvents); - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1500)); - controller_impl->UpdateState(true, events.get()); - - EXPECT_EQ( - Animation::WAITING_FOR_DELETION, - controller_impl->GetAnimation(TargetProperty::OPACITY)->run_state()); - // The impl thread controller should have de-activated. - EXPECT_EQ(0u, - registrar_impl->active_animation_controllers_for_testing().size()); - - EXPECT_EQ(1u, events->events_.size()); - controller->NotifyAnimationFinished(events->events_[0]); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1500)); - controller->UpdateState(true, nullptr); - - EXPECT_EQ(Animation::WAITING_FOR_DELETION, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - // The main thread controller should have de-activated. - EXPECT_EQ(0u, registrar->active_animation_controllers_for_testing().size()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->has_any_animation()); - EXPECT_FALSE(controller_impl->has_any_animation()); - EXPECT_EQ(0u, registrar->active_animation_controllers_for_testing().size()); - EXPECT_EQ(0u, - registrar_impl->active_animation_controllers_for_testing().size()); - - controller->SetAnimationRegistrar(nullptr); - controller_impl->SetAnimationRegistrar(nullptr); -} - -TEST(LayerAnimationControllerTest, SyncPause) { - 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); - - EXPECT_FALSE(controller_impl->GetAnimation(TargetProperty::OPACITY)); - - // Two steps, three ranges: [0-1) -> 0.2, [1-2) -> 0.3, [2-3] -> 0.4. - const double duration = 3.0; - const int animation_id = - AddOpacityStepsToController(controller.get(), duration, 0.2f, 0.4f, 2); - - // Set start offset to be at the beginning of the second range. - controller->GetAnimationById(animation_id) - ->set_time_offset(TimeDelta::FromSecondsD(1.01)); - - 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()); - - TimeTicks time = kInitialTickTime; - - // Start the animations on each controller. - AnimationEvents events; - controller_impl->Animate(time); - controller_impl->UpdateState(true, &events); - EXPECT_EQ(1u, events.events_.size()); - - controller->Animate(time); - controller->UpdateState(true, nullptr); - controller->NotifyAnimationStarted(events.events_[0]); - - EXPECT_EQ(Animation::RUNNING, - controller_impl->GetAnimationById(animation_id)->run_state()); - EXPECT_EQ(Animation::RUNNING, - controller->GetAnimationById(animation_id)->run_state()); - - EXPECT_EQ(0.3f, dummy.opacity()); - EXPECT_EQ(0.3f, dummy_impl.opacity()); - - EXPECT_EQ(kInitialTickTime, - controller->GetAnimationById(animation_id)->start_time()); - EXPECT_EQ(kInitialTickTime, - controller_impl->GetAnimationById(animation_id)->start_time()); - - // Pause the animation at the middle of the second range so the offset - // delays animation until the middle of the third range. - controller->PauseAnimation(animation_id, TimeDelta::FromSecondsD(1.5)); - EXPECT_EQ(Animation::PAUSED, - controller->GetAnimationById(animation_id)->run_state()); - - // The pause run state change should make it to the impl thread controller. - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - - // Advance time so it stays within the first range. - time += TimeDelta::FromMilliseconds(10); - controller->Animate(time); - controller_impl->Animate(time); - - EXPECT_EQ(Animation::PAUSED, - controller_impl->GetAnimationById(animation_id)->run_state()); - - // Opacity value doesn't depend on time if paused at specified time offset. - EXPECT_EQ(0.4f, dummy.opacity()); - EXPECT_EQ(0.4f, dummy_impl.opacity()); -} - -TEST(LayerAnimationControllerTest, DoNotSyncFinishedAnimation) { - 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); - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - - EXPECT_FALSE(controller_impl->GetAnimation(TargetProperty::OPACITY)); - - int animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0, 1, false); - - 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()); - - events.reset(new AnimationEvents); - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_EQ(1u, events->events_.size()); - EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); - - // Notify main thread controller that the animation has started. - controller->NotifyAnimationStarted(events->events_[0]); - - // Complete animation on impl thread. - events.reset(new AnimationEvents); - controller_impl->Animate(kInitialTickTime + TimeDelta::FromSeconds(1)); - controller_impl->UpdateState(true, events.get()); - EXPECT_EQ(1u, events->events_.size()); - EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); - - controller->NotifyAnimationFinished(events->events_[0]); - - controller->Animate(kInitialTickTime + TimeDelta::FromSeconds(2)); - controller->UpdateState(true, nullptr); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->GetAnimationById(animation_id)); - EXPECT_FALSE(controller_impl->GetAnimationById(animation_id)); -} - -// Ensure that a finished animation is eventually deleted by both the -// main-thread and the impl-thread controllers. -TEST(LayerAnimationControllerTest, AnimationsAreDeleted) { - FakeLayerAnimationValueObserver dummy; - FakeLayerAnimationValueObserver dummy_impl; - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - controller_impl->AddValueObserver(&dummy_impl); - - AddOpacityTransitionToController(controller.get(), 1.0, 0.0f, 1.0f, false); - controller->Animate(kInitialTickTime); - controller->UpdateState(true, nullptr); - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - - controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller_impl->UpdateState(true, events.get()); - - // There should be a STARTED event for the animation. - EXPECT_EQ(1u, events->events_.size()); - EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); - controller->NotifyAnimationStarted(events->events_[0]); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, nullptr); - - EXPECT_FALSE(dummy.animation_waiting_for_deletion()); - EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion()); - - events.reset(new AnimationEvents); - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(2000)); - controller_impl->UpdateState(true, events.get()); - - EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion()); - - // There should be a FINISHED event for the animation. - EXPECT_EQ(1u, events->events_.size()); - EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); - - // Neither controller should have deleted the animation yet. - EXPECT_TRUE(controller->GetAnimation(TargetProperty::OPACITY)); - EXPECT_TRUE(controller_impl->GetAnimation(TargetProperty::OPACITY)); - - controller->NotifyAnimationFinished(events->events_[0]); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(dummy.animation_waiting_for_deletion()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - - // Both controllers should now have deleted the animation. The impl controller - // should have deleted the animation even though activation has not occurred, - // since the animation was already waiting for deletion when - // PushAnimationUpdatesTo was called. - EXPECT_FALSE(controller->has_any_animation()); - EXPECT_FALSE(controller_impl->has_any_animation()); -} - -// Tests that transitioning opacity from 0 to 1 works as expected. - -static const AnimationEvent* GetMostRecentPropertyUpdateEvent( - const AnimationEvents* events) { - const AnimationEvent* event = 0; - for (size_t i = 0; i < events->events_.size(); ++i) - if (events->events_[i].type == AnimationEvent::PROPERTY_UPDATE) - event = &events->events_[i]; - - return event; -} - -TEST(LayerAnimationControllerTest, TrivialTransition) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - - EXPECT_FALSE(controller->needs_to_start_animations_for_testing()); - controller->AddAnimation(std::move(to_add)); - EXPECT_TRUE(controller->needs_to_start_animations_for_testing()); - controller->Animate(kInitialTickTime); - EXPECT_FALSE(controller->needs_to_start_animations_for_testing()); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - // A non-impl-only animation should not generate property updates. - const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(1.f, dummy.opacity()); - EXPECT_FALSE(controller->HasActiveAnimation()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); -} - -TEST(LayerAnimationControllerTest, TrivialTransitionOnImpl) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - to_add->set_is_impl_only(true); - - controller_impl->AddAnimation(std::move(to_add)); - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_TRUE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy_impl.opacity()); - EXPECT_EQ(1u, events->events_.size()); - const AnimationEvent* start_opacity_event = - GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_EQ(0.f, start_opacity_event->opacity); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - EXPECT_EQ(1.f, dummy_impl.opacity()); - EXPECT_FALSE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(2u, events->events_.size()); - const AnimationEvent* end_opacity_event = - GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_EQ(1.f, end_opacity_event->opacity); -} - -TEST(LayerAnimationControllerTest, TrivialTransformOnImpl) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - - // Choose different values for x and y to avoid coincidental values in the - // observed transforms. - const float delta_x = 3; - const float delta_y = 4; - - scoped_ptr<KeyframedTransformAnimationCurve> curve( - KeyframedTransformAnimationCurve::Create()); - - // Create simple TRANSFORM animation. - TransformOperations operations; - curve->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations, nullptr)); - operations.AppendTranslate(delta_x, delta_y, 0); - curve->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations, nullptr)); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve), 1, 0, TargetProperty::TRANSFORM)); - animation->set_is_impl_only(true); - controller_impl->AddAnimation(std::move(animation)); - - // Run animation. - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_TRUE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(gfx::Transform(), dummy_impl.transform()); - EXPECT_EQ(1u, events->events_.size()); - const AnimationEvent* start_transform_event = - GetMostRecentPropertyUpdateEvent(events.get()); - ASSERT_TRUE(start_transform_event); - EXPECT_EQ(gfx::Transform(), start_transform_event->transform); - EXPECT_TRUE(start_transform_event->is_impl_only); - - gfx::Transform expected_transform; - expected_transform.Translate(delta_x, delta_y); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - EXPECT_EQ(expected_transform, dummy_impl.transform()); - EXPECT_FALSE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(2u, events->events_.size()); - const AnimationEvent* end_transform_event = - GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_EQ(expected_transform, end_transform_event->transform); - EXPECT_TRUE(end_transform_event->is_impl_only); -} - -TEST(LayerAnimationControllerTest, FilterTransition) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - scoped_ptr<KeyframedFilterAnimationCurve> curve( - KeyframedFilterAnimationCurve::Create()); - - FilterOperations start_filters; - start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f)); - curve->AddKeyframe( - FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); - FilterOperations end_filters; - end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f)); - curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), - end_filters, nullptr)); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve), 1, 0, TargetProperty::FILTER)); - controller->AddAnimation(std::move(animation)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(start_filters, dummy.filters()); - // A non-impl-only animation should not generate property updates. - const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(1u, dummy.filters().size()); - EXPECT_EQ(FilterOperation::CreateBrightnessFilter(1.5f), - dummy.filters().at(0)); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(end_filters, dummy.filters()); - EXPECT_FALSE(controller->HasActiveAnimation()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); -} - -TEST(LayerAnimationControllerTest, FilterTransitionOnImplOnly) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - - scoped_ptr<KeyframedFilterAnimationCurve> curve( - KeyframedFilterAnimationCurve::Create()); - - // Create simple FILTER animation. - FilterOperations start_filters; - start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f)); - curve->AddKeyframe( - FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); - FilterOperations end_filters; - end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f)); - curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), - end_filters, nullptr)); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve), 1, 0, TargetProperty::FILTER)); - animation->set_is_impl_only(true); - controller_impl->AddAnimation(std::move(animation)); - - // Run animation. - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_TRUE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(start_filters, dummy_impl.filters()); - EXPECT_EQ(1u, events->events_.size()); - const AnimationEvent* start_filter_event = - GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_TRUE(start_filter_event); - EXPECT_EQ(start_filters, start_filter_event->filters); - EXPECT_TRUE(start_filter_event->is_impl_only); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - EXPECT_EQ(end_filters, dummy_impl.filters()); - EXPECT_FALSE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(2u, events->events_.size()); - const AnimationEvent* end_filter_event = - GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_TRUE(end_filter_event); - EXPECT_EQ(end_filters, end_filter_event->filters); - EXPECT_TRUE(end_filter_event->is_impl_only); -} - -TEST(LayerAnimationControllerTest, ScrollOffsetTransition) { - FakeLayerAnimationValueObserver dummy_impl; - FakeLayerAnimationValueProvider dummy_provider_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - controller_impl->set_value_provider(&dummy_provider_impl); - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - FakeLayerAnimationValueProvider dummy_provider; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - controller->set_value_provider(&dummy_provider); - - gfx::ScrollOffset initial_value(100.f, 300.f); - gfx::ScrollOffset target_value(300.f, 200.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( - ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create())); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); - animation->set_needs_synchronized_start_time(true); - controller->AddAnimation(std::move(animation)); - - dummy_provider_impl.set_scroll_offset(initial_value); - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->GetAnimation(TargetProperty::SCROLL_OFFSET)); - TimeDelta duration = - controller_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) - ->curve() - ->Duration(); - EXPECT_EQ(duration, controller->GetAnimation(TargetProperty::SCROLL_OFFSET) - ->curve() - ->Duration()); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(initial_value, dummy.scroll_offset()); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_TRUE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(initial_value, dummy_impl.scroll_offset()); - // Scroll offset animations should not generate property updates. - const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller->NotifyAnimationStarted(events->events_[0]); - controller->Animate(kInitialTickTime + duration / 2); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(200.f, 250.f), dummy.scroll_offset()); - - controller_impl->Animate(kInitialTickTime + duration / 2); - controller_impl->UpdateState(true, events.get()); - EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(200.f, 250.f), - dummy_impl.scroll_offset()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller_impl->Animate(kInitialTickTime + duration); - controller_impl->UpdateState(true, events.get()); - EXPECT_VECTOR2DF_EQ(target_value, dummy_impl.scroll_offset()); - EXPECT_FALSE(controller_impl->HasActiveAnimation()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller->Animate(kInitialTickTime + duration); - controller->UpdateState(true, nullptr); - EXPECT_VECTOR2DF_EQ(target_value, dummy.scroll_offset()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -// Ensure that when the impl controller doesn't have a value provider, -// the main-thread controller's value provider is used to obtain the intial -// scroll offset. -TEST(LayerAnimationControllerTest, ScrollOffsetTransitionNoImplProvider) { - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - FakeLayerAnimationValueProvider dummy_provider; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - controller->set_value_provider(&dummy_provider); - - gfx::ScrollOffset initial_value(500.f, 100.f); - gfx::ScrollOffset target_value(300.f, 200.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( - ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create())); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); - animation->set_needs_synchronized_start_time(true); - controller->AddAnimation(std::move(animation)); - - dummy_provider.set_scroll_offset(initial_value); - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->GetAnimation(TargetProperty::SCROLL_OFFSET)); - TimeDelta duration = - controller_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) - ->curve() - ->Duration(); - EXPECT_EQ(duration, controller->GetAnimation(TargetProperty::SCROLL_OFFSET) - ->curve() - ->Duration()); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(initial_value, dummy.scroll_offset()); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_TRUE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(initial_value, dummy_impl.scroll_offset()); - // Scroll offset animations should not generate property updates. - const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller->NotifyAnimationStarted(events->events_[0]); - controller->Animate(kInitialTickTime + duration / 2); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(400.f, 150.f), dummy.scroll_offset()); - - controller_impl->Animate(kInitialTickTime + duration / 2); - controller_impl->UpdateState(true, events.get()); - EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(400.f, 150.f), - dummy_impl.scroll_offset()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller_impl->Animate(kInitialTickTime + duration); - controller_impl->UpdateState(true, events.get()); - EXPECT_VECTOR2DF_EQ(target_value, dummy_impl.scroll_offset()); - EXPECT_FALSE(controller_impl->HasActiveAnimation()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller->Animate(kInitialTickTime + duration); - controller->UpdateState(true, nullptr); - EXPECT_VECTOR2DF_EQ(target_value, dummy.scroll_offset()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -TEST(LayerAnimationControllerTest, ScrollOffsetTransitionOnImplOnly) { - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - - gfx::ScrollOffset initial_value(100.f, 300.f); - gfx::ScrollOffset target_value(300.f, 200.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( - ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create())); - curve->SetInitialValue(initial_value); - double duration_in_seconds = curve->Duration().InSecondsF(); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); - animation->set_is_impl_only(true); - controller_impl->AddAnimation(std::move(animation)); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_TRUE(controller_impl->HasActiveAnimation()); - EXPECT_EQ(initial_value, dummy_impl.scroll_offset()); - // Scroll offset animations should not generate property updates. - const AnimationEvent* event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - TimeDelta duration = TimeDelta::FromMicroseconds( - duration_in_seconds * base::Time::kMicrosecondsPerSecond); - - controller_impl->Animate(kInitialTickTime + duration / 2); - controller_impl->UpdateState(true, events.get()); - EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(200.f, 250.f), - dummy_impl.scroll_offset()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); - - controller_impl->Animate(kInitialTickTime + duration); - controller_impl->UpdateState(true, events.get()); - EXPECT_VECTOR2DF_EQ(target_value, dummy_impl.scroll_offset()); - EXPECT_FALSE(controller_impl->HasActiveAnimation()); - event = GetMostRecentPropertyUpdateEvent(events.get()); - EXPECT_FALSE(event); -} - -TEST(LayerAnimationControllerTest, ScrollOffsetRemovalClearsScrollDelta) { - FakeLayerAnimationValueObserver dummy_impl; - FakeLayerAnimationValueProvider dummy_provider_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - controller_impl->set_value_provider(&dummy_provider_impl); - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - FakeLayerAnimationValueProvider dummy_provider; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - controller->set_value_provider(&dummy_provider); - - // First test the 1-argument version of RemoveAnimation. - gfx::ScrollOffset target_value(300.f, 200.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( - ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create())); - - int animation_id = 1; - scoped_ptr<Animation> animation(Animation::Create( - std::move(curve), animation_id, 0, TargetProperty::SCROLL_OFFSET)); - animation->set_needs_synchronized_start_time(true); - controller->AddAnimation(std::move(animation)); - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - - controller->RemoveAnimation(animation_id); - EXPECT_TRUE(controller->scroll_offset_animation_was_interrupted()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_TRUE(controller_impl->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - - // Now, test the 2-argument version of RemoveAnimation. - curve = ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create()); - animation = Animation::Create(std::move(curve), animation_id, 0, - TargetProperty::SCROLL_OFFSET); - animation->set_needs_synchronized_start_time(true); - controller->AddAnimation(std::move(animation)); - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - - controller->RemoveAnimation(animation_id); - EXPECT_TRUE(controller->scroll_offset_animation_was_interrupted()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_TRUE(controller_impl->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - - // Check that removing non-scroll-offset animations does not cause - // scroll_offset_animation_was_interrupted() to get set. - animation_id = AddAnimatedTransformToController(controller.get(), 1.0, 1, 2); - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - - controller->RemoveAnimation(animation_id); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - - animation_id = - AddAnimatedFilterToController(controller.get(), 1.0, 0.1f, 0.2f); - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - - controller->RemoveAnimation(animation_id); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); - EXPECT_FALSE(controller->scroll_offset_animation_was_interrupted()); - - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller_impl->scroll_offset_animation_was_interrupted()); -} - -class FakeAnimationDelegate : public AnimationDelegate { - public: - FakeAnimationDelegate() - : started_(false), - finished_(false), - aborted_(false), - takeover_(false), - start_time_(base::TimeTicks()) {} - - void NotifyAnimationStarted(TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override { - started_ = true; - start_time_ = monotonic_time; - } - - void NotifyAnimationFinished(TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override { - finished_ = true; - } - - void NotifyAnimationAborted(TimeTicks monotonic_time, - TargetProperty::Type target_property, - int group) override { - aborted_ = true; - } - - void NotifyAnimationTakeover(base::TimeTicks monotonic_time, - TargetProperty::Type target_property, - double animation_start_time, - scoped_ptr<AnimationCurve> curve) override { - takeover_ = true; - } - - bool started() { return started_; } - - bool finished() { return finished_; } - - bool aborted() { return aborted_; } - - bool takeover() { return takeover_; } - - TimeTicks start_time() { return start_time_; } - - private: - bool started_; - bool finished_; - bool aborted_; - bool takeover_; - TimeTicks start_time_; -}; - -// Tests that impl-only animations lead to start and finished notifications -// on the impl thread controller's animation delegate. -TEST(LayerAnimationControllerTest, - NotificationsForImplOnlyAnimationsAreSentToImplThreadDelegate) { - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeAnimationDelegate delegate; - controller_impl->set_layer_animation_delegate(&delegate); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - to_add->set_is_impl_only(true); - controller_impl->AddAnimation(std::move(to_add)); - - EXPECT_FALSE(delegate.started()); - EXPECT_FALSE(delegate.finished()); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - - EXPECT_TRUE(delegate.started()); - EXPECT_FALSE(delegate.finished()); - - events.reset(new AnimationEvents); - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - - EXPECT_TRUE(delegate.started()); - 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(TargetProperty::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()); - - AnimationEvents events; - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, &events); - - // Synchronize the start times. - EXPECT_EQ(1u, events.events_.size()); - controller->NotifyAnimationStarted(events.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(TargetProperty::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()); - - AnimationEvents events; - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, &events); - - // Synchronize the start times. - EXPECT_EQ(1u, events.events_.size()); - controller->NotifyAnimationStarted(events.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, - AnimationsWaitingForStartTimeDoNotFinishIfTheyOutwaitTheirFinish) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - to_add->set_needs_synchronized_start_time(true); - - // We should pause at the first keyframe indefinitely waiting for that - // animation to start. - controller->AddAnimation(std::move(to_add)); - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - - // Send the synchronized start time. - controller->NotifyAnimationStarted( - AnimationEvent(AnimationEvent::STARTED, 0, 1, TargetProperty::OPACITY, - kInitialTickTime + TimeDelta::FromMilliseconds(2000))); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(5000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(1.f, dummy.opacity()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -// Tests that two queued animations affecting the same property run in sequence. -TEST(LayerAnimationControllerTest, TrivialQueuing) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - EXPECT_FALSE(controller->needs_to_start_animations_for_testing()); - - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.5f)), 2, - TargetProperty::OPACITY)); - - EXPECT_TRUE(controller->needs_to_start_animations_for_testing()); - - controller->Animate(kInitialTickTime); - - // The second animation still needs to be started. - EXPECT_TRUE(controller->needs_to_start_animations_for_testing()); - - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - EXPECT_TRUE(controller->needs_to_start_animations_for_testing()); - controller->UpdateState(true, events.get()); - EXPECT_FALSE(controller->needs_to_start_animations_for_testing()); - - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(1.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(0.5f, dummy.opacity()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -// Tests interrupting a transition with another transition. -TEST(LayerAnimationControllerTest, Interrupt) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.5f)), 2, - TargetProperty::OPACITY)); - controller->AbortAnimations(TargetProperty::OPACITY); - controller->AddAnimation(std::move(to_add)); - - // Since the previous animation was aborted, the new animation should start - // right in this call to animate. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(1.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1500)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(0.5f, dummy.opacity()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -// Tests scheduling two animations to run together when only one property is -// free. -TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, - TargetProperty::TRANSFORM)); - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)), 2, - TargetProperty::TRANSFORM)); - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 2, - TargetProperty::OPACITY)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_EQ(0.f, dummy.opacity()); - EXPECT_TRUE(controller->HasActiveAnimation()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, events.get()); - // Should not have started the float transition yet. - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - // The float animation should have started at time 1 and should be done. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(1.f, dummy.opacity()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -// Tests scheduling two animations to run together with different lengths and -// another animation queued to start when the shorter animation finishes (should -// wait for both to finish). -TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(2)), 1, - TargetProperty::TRANSFORM)); - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.5f)), 2, - TargetProperty::OPACITY)); - - // Animations with id 1 should both start now. - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - // The opacity animation should have finished at time 1, but the group - // of animations with id 1 don't finish until time 2 because of the length - // of the transform animation. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - controller->UpdateState(true, events.get()); - // Should not have started the float transition yet. - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(1.f, dummy.opacity()); - - // The second opacity animation should start at time 2 and should be done by - // time 3. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(0.5f, dummy.opacity()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -// Test that a looping animation loops and for the correct number of iterations. -TEST(LayerAnimationControllerTest, TrivialLooping) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - to_add->set_iterations(3); - controller->AddAnimation(std::move(to_add)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1250)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.25f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1750)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.75f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2250)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.25f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2750)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.75f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); - controller->UpdateState(true, events.get()); - EXPECT_FALSE(controller->HasActiveAnimation()); - EXPECT_EQ(1.f, dummy.opacity()); - - // Just be extra sure. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(4000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(1.f, dummy.opacity()); -} - -// Test that an infinitely looping animation does indeed go until aborted. -TEST(LayerAnimationControllerTest, InfiniteLooping) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - to_add->set_iterations(-1); - controller->AddAnimation(std::move(to_add)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1250)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.25f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1750)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.75f, dummy.opacity()); - - controller->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1073741824250)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.25f, dummy.opacity()); - controller->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1073741824750)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.75f, dummy.opacity()); - - EXPECT_TRUE(controller->GetAnimation(TargetProperty::OPACITY)); - controller->GetAnimation(TargetProperty::OPACITY) - ->SetRunState(Animation::ABORTED, - kInitialTickTime + TimeDelta::FromMilliseconds(750)); - EXPECT_FALSE(controller->HasActiveAnimation()); - EXPECT_EQ(0.75f, dummy.opacity()); -} - -// Test that pausing and resuming work as expected. -TEST(LayerAnimationControllerTest, PauseResume) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.5f, dummy.opacity()); - - EXPECT_TRUE(controller->GetAnimation(TargetProperty::OPACITY)); - controller->GetAnimation(TargetProperty::OPACITY) - ->SetRunState(Animation::PAUSED, - kInitialTickTime + TimeDelta::FromMilliseconds(500)); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024000)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.5f, dummy.opacity()); - - EXPECT_TRUE(controller->GetAnimation(TargetProperty::OPACITY)); - controller->GetAnimation(TargetProperty::OPACITY) - ->SetRunState(Animation::RUNNING, - kInitialTickTime + TimeDelta::FromMilliseconds(1024000)); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024250)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.75f, dummy.opacity()); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1024500)); - controller->UpdateState(true, events.get()); - EXPECT_FALSE(controller->HasActiveAnimation()); - EXPECT_EQ(1.f, dummy.opacity()); -} - -TEST(LayerAnimationControllerTest, AbortAGroupedAnimation) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - const int animation_id = 2; - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, 1, - TargetProperty::TRANSFORM)); - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)), - animation_id, 1, TargetProperty::OPACITY)); - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.75f)), 3, - 2, TargetProperty::OPACITY)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.5f, dummy.opacity()); - - EXPECT_TRUE(controller->GetAnimationById(animation_id)); - controller->GetAnimationById(animation_id) - ->SetRunState(Animation::ABORTED, - kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(1.f, dummy.opacity()); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(!controller->HasActiveAnimation()); - EXPECT_EQ(0.75f, dummy.opacity()); -} - -TEST(LayerAnimationControllerTest, PushUpdatesWhenSynchronizedStartTimeNeeded) { - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - scoped_ptr<Animation> to_add(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)), 0, - TargetProperty::OPACITY)); - to_add->set_needs_synchronized_start_time(true); - controller->AddAnimation(std::move(to_add)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_TRUE(controller->HasActiveAnimation()); - Animation* active_animation = - controller->GetAnimation(TargetProperty::OPACITY); - EXPECT_TRUE(active_animation); - EXPECT_TRUE(active_animation->needs_synchronized_start_time()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - - active_animation = controller_impl->GetAnimation(TargetProperty::OPACITY); - EXPECT_TRUE(active_animation); - EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, - active_animation->run_state()); -} - -// Tests that skipping a call to UpdateState works as expected. -TEST(LayerAnimationControllerTest, SkipUpdateState) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - scoped_ptr<Animation> first_animation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, - TargetProperty::TRANSFORM)); - first_animation->set_is_controlling_instance_for_test(true); - controller->AddAnimation(std::move(first_animation)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - - scoped_ptr<Animation> second_animation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 2, - TargetProperty::OPACITY)); - second_animation->set_is_controlling_instance_for_test(true); - controller->AddAnimation(std::move(second_animation)); - - // Animate but don't UpdateState. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - events.reset(new AnimationEvents); - controller->UpdateState(true, events.get()); - - // Should have one STARTED event and one FINISHED event. - EXPECT_EQ(2u, events->events_.size()); - EXPECT_NE(events->events_[0].type, events->events_[1].type); - - // The float transition should still be at its starting point. - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_EQ(0.f, dummy.opacity()); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); - controller->UpdateState(true, events.get()); - - // The float tranisition should now be done. - EXPECT_EQ(1.f, dummy.opacity()); - EXPECT_FALSE(controller->HasActiveAnimation()); -} - -// Tests that an animation controller with only a pending observer gets ticked -// but doesn't progress animations past the STARTING state. -TEST(LayerAnimationControllerTest, InactiveObserverGetsTicked) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy; - FakeInactiveLayerAnimationValueObserver pending_dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - - const int id = 1; - controller->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.5f, 1.f)), id, - TargetProperty::OPACITY)); - - // Without an observer, the animation shouldn't progress to the STARTING - // state. - controller->Animate(kInitialTickTime); - controller->UpdateState(true, events.get()); - EXPECT_EQ(0u, events->events_.size()); - EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - - controller->AddValueObserver(&pending_dummy); - - // With only a pending observer, the animation should progress to the - // STARTING state and get ticked at its starting point, but should not - // progress to RUNNING. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(0u, events->events_.size()); - EXPECT_EQ(Animation::STARTING, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - EXPECT_EQ(0.5f, pending_dummy.opacity()); - - // Even when already in the STARTING state, the animation should stay - // there, and shouldn't be ticked past its starting point. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(0u, events->events_.size()); - EXPECT_EQ(Animation::STARTING, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - EXPECT_EQ(0.5f, pending_dummy.opacity()); - - controller->AddValueObserver(&dummy); - - // Now that an active observer has been added, the animation should still - // initially tick at its starting point, but should now progress to RUNNING. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3000)); - controller->UpdateState(true, events.get()); - EXPECT_EQ(1u, events->events_.size()); - EXPECT_EQ(Animation::RUNNING, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - EXPECT_EQ(0.5f, pending_dummy.opacity()); - EXPECT_EQ(0.5f, dummy.opacity()); - - // The animation should now tick past its starting point. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(3500)); - EXPECT_NE(0.5f, pending_dummy.opacity()); - EXPECT_NE(0.5f, dummy.opacity()); -} - -TEST(LayerAnimationControllerTest, TransformAnimationBounds) { - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - - scoped_ptr<KeyframedTransformAnimationCurve> curve1( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations1; - curve1->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); - operations1.AppendTranslate(10.0, 15.0, 0.0); - curve1->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); - controller_impl->AddAnimation(std::move(animation)); - - scoped_ptr<KeyframedTransformAnimationCurve> curve2( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations2; - curve2->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); - operations2.AppendScale(2.0, 3.0, 4.0); - curve2->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); - - animation = - Animation::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM); - controller_impl->AddAnimation(std::move(animation)); - - gfx::BoxF box(1.f, 2.f, -1.f, 3.f, 4.f, 5.f); - gfx::BoxF bounds; - - EXPECT_TRUE(controller_impl->TransformAnimationBoundsForBox(box, &bounds)); - EXPECT_EQ(gfx::BoxF(1.f, 2.f, -4.f, 13.f, 19.f, 20.f).ToString(), - bounds.ToString()); - - controller_impl->GetAnimationById(1) - ->SetRunState(Animation::FINISHED, TicksFromSecondsF(0.0)); - - // Only the unfinished animation should affect the animated bounds. - EXPECT_TRUE(controller_impl->TransformAnimationBoundsForBox(box, &bounds)); - EXPECT_EQ(gfx::BoxF(1.f, 2.f, -4.f, 7.f, 16.f, 20.f).ToString(), - bounds.ToString()); - - controller_impl->GetAnimationById(2) - ->SetRunState(Animation::FINISHED, TicksFromSecondsF(0.0)); - - // There are no longer any running animations. - EXPECT_FALSE(controller_impl->HasTransformAnimationThatInflatesBounds()); - - // Add an animation whose bounds we don't yet support computing. - scoped_ptr<KeyframedTransformAnimationCurve> curve3( - KeyframedTransformAnimationCurve::Create()); - TransformOperations operations3; - gfx::Transform transform3; - transform3.Scale3d(1.0, 2.0, 3.0); - curve3->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr)); - operations3.AppendMatrix(transform3); - curve3->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations3, nullptr)); - animation = - Animation::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM); - controller_impl->AddAnimation(std::move(animation)); - EXPECT_FALSE(controller_impl->TransformAnimationBoundsForBox(box, &bounds)); -} - -// Tests that AbortAnimations aborts all animations targeting the specified -// property. -TEST(LayerAnimationControllerTest, AbortAnimations) { - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - // Start with several animations, and allow some of them to reach the finished - // state. - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 1, 1, - TargetProperty::TRANSFORM)); - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 2, 2, - TargetProperty::OPACITY)); - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 3, 3, - TargetProperty::TRANSFORM)); - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(2.0)), 4, 4, - TargetProperty::TRANSFORM)); - controller->AddAnimation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 5, 5, - TargetProperty::OPACITY)); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, nullptr); - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, nullptr); - - EXPECT_EQ(Animation::FINISHED, controller->GetAnimationById(1)->run_state()); - EXPECT_EQ(Animation::FINISHED, controller->GetAnimationById(2)->run_state()); - EXPECT_EQ(Animation::RUNNING, controller->GetAnimationById(3)->run_state()); - EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, - controller->GetAnimationById(4)->run_state()); - EXPECT_EQ(Animation::RUNNING, controller->GetAnimationById(5)->run_state()); - - controller->AbortAnimations(TargetProperty::TRANSFORM); - - // Only un-finished TRANSFORM animations should have been aborted. - EXPECT_EQ(Animation::FINISHED, controller->GetAnimationById(1)->run_state()); - EXPECT_EQ(Animation::FINISHED, controller->GetAnimationById(2)->run_state()); - EXPECT_EQ(Animation::ABORTED, controller->GetAnimationById(3)->run_state()); - EXPECT_EQ(Animation::ABORTED, controller->GetAnimationById(4)->run_state()); - EXPECT_EQ(Animation::RUNNING, controller->GetAnimationById(5)->run_state()); -} - -// An animation aborted on the main thread should get deleted on both threads. -TEST(LayerAnimationControllerTest, MainThreadAbortedAnimationGetsDeleted) { - 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); - - int animation_id = - AddOpacityTransitionToController(controller.get(), 1.0, 0.f, 1.f, false); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)); - - controller->AbortAnimations(TargetProperty::OPACITY); - EXPECT_EQ(Animation::ABORTED, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - EXPECT_FALSE(dummy.animation_waiting_for_deletion()); - EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion()); - - controller->Animate(kInitialTickTime); - controller->UpdateState(true, nullptr); - EXPECT_FALSE(dummy.animation_waiting_for_deletion()); - EXPECT_EQ(Animation::ABORTED, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_FALSE(controller->GetAnimationById(animation_id)); - EXPECT_FALSE(controller_impl->GetAnimationById(animation_id)); -} - -// An animation aborted on the impl thread should get deleted on both threads. -TEST(LayerAnimationControllerTest, ImplThreadAbortedAnimationGetsDeleted) { - 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, 0.f, 1.f, false); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)); - - controller_impl->AbortAnimations(TargetProperty::OPACITY); - EXPECT_EQ( - Animation::ABORTED, - controller_impl->GetAnimation(TargetProperty::OPACITY)->run_state()); - EXPECT_FALSE(dummy.animation_waiting_for_deletion()); - EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion()); - - AnimationEvents events; - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, &events); - EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion()); - EXPECT_EQ(1u, events.events_.size()); - EXPECT_EQ(AnimationEvent::ABORTED, events.events_[0].type); - EXPECT_EQ( - Animation::WAITING_FOR_DELETION, - controller_impl->GetAnimation(TargetProperty::OPACITY)->run_state()); - - controller->NotifyAnimationAborted(events.events_[0]); - EXPECT_EQ(Animation::ABORTED, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - EXPECT_TRUE(delegate.aborted()); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(dummy.animation_waiting_for_deletion()); - EXPECT_EQ(Animation::WAITING_FOR_DELETION, - controller->GetAnimation(TargetProperty::OPACITY)->run_state()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->GetAnimationById(animation_id)); - EXPECT_FALSE(controller_impl->GetAnimationById(animation_id)); -} - -// Test that an impl-only scroll offset animation that needs to be completed on -// the main thread gets deleted. -TEST(LayerAnimationControllerTest, ImplThreadTakeoverAnimationGetsDeleted) { - 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_impl; - controller_impl->set_layer_animation_delegate(&delegate_impl); - FakeAnimationDelegate delegate; - controller->set_layer_animation_delegate(&delegate); - - // Add impl-only scroll offset animation. - int animation_id = 1; - gfx::ScrollOffset initial_value(100.f, 300.f); - gfx::ScrollOffset target_value(300.f, 200.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( - ScrollOffsetAnimationCurve::Create(target_value, - EaseInOutTimingFunction::Create())); - curve->SetInitialValue(initial_value); - scoped_ptr<Animation> animation(Animation::Create( - std::move(curve), animation_id, 0, TargetProperty::SCROLL_OFFSET)); - animation->set_start_time(TicksFromSecondsF(123)); - animation->set_is_impl_only(true); - controller_impl->AddAnimation(std::move(animation)); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)); - - controller_impl->AbortAnimations(TargetProperty::SCROLL_OFFSET, - true /* needs_completion*/); - EXPECT_EQ(Animation::ABORTED_BUT_NEEDS_COMPLETION, - controller_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) - ->run_state()); - EXPECT_FALSE(dummy.animation_waiting_for_deletion()); - EXPECT_FALSE(dummy_impl.animation_waiting_for_deletion()); - - AnimationEvents events; - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, &events); - EXPECT_TRUE(delegate_impl.finished()); - EXPECT_TRUE(dummy_impl.animation_waiting_for_deletion()); - EXPECT_EQ(1u, events.events_.size()); - EXPECT_EQ(AnimationEvent::TAKEOVER, events.events_[0].type); - EXPECT_EQ(123, events.events_[0].animation_start_time); - EXPECT_EQ( - target_value, - events.events_[0].curve->ToScrollOffsetAnimationCurve()->target_value()); - EXPECT_EQ(Animation::WAITING_FOR_DELETION, - controller_impl->GetAnimation(TargetProperty::SCROLL_OFFSET) - ->run_state()); - - controller->NotifyAnimationTakeover(events.events_[0]); - EXPECT_TRUE(delegate.takeover()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller->GetAnimationById(animation_id)); - EXPECT_FALSE(controller_impl->GetAnimationById(animation_id)); -} - -// Ensure that we only generate FINISHED events for animations in a group -// once all animations in that group are finished. -TEST(LayerAnimationControllerTest, FinishedEventsForGroup) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - - const int group_id = 1; - - // Add two animations with the same group id but different durations. - scoped_ptr<Animation> first_animation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(2.0)), 1, group_id, - TargetProperty::TRANSFORM)); - first_animation->set_is_controlling_instance_for_test(true); - controller_impl->AddAnimation(std::move(first_animation)); - - scoped_ptr<Animation> second_animation(Animation::Create( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 2, - group_id, TargetProperty::OPACITY)); - second_animation->set_is_controlling_instance_for_test(true); - controller_impl->AddAnimation(std::move(second_animation)); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - - // Both animations should have started. - EXPECT_EQ(2u, events->events_.size()); - EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); - EXPECT_EQ(AnimationEvent::STARTED, events->events_[1].type); - - events.reset(new AnimationEvents); - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - - // The opacity animation should be finished, but should not have generated - // a FINISHED event yet. - EXPECT_EQ(0u, events->events_.size()); - EXPECT_EQ(Animation::FINISHED, - controller_impl->GetAnimationById(2)->run_state()); - EXPECT_EQ(Animation::RUNNING, - controller_impl->GetAnimationById(1)->run_state()); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(2000)); - controller_impl->UpdateState(true, events.get()); - - // Both animations should have generated FINISHED events. - EXPECT_EQ(2u, events->events_.size()); - EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); - EXPECT_EQ(AnimationEvent::FINISHED, events->events_[1].type); -} - -// Ensure that when a group has a mix of aborted and finished animations, -// we generate a FINISHED event for the finished animation and an ABORTED -// event for the aborted animation. -TEST(LayerAnimationControllerTest, FinishedAndAbortedEventsForGroup) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - - // Add two animations with the same group id. - scoped_ptr<Animation> first_animation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 1, - TargetProperty::TRANSFORM)); - first_animation->set_is_controlling_instance_for_test(true); - controller_impl->AddAnimation(std::move(first_animation)); - - scoped_ptr<Animation> second_animation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - second_animation->set_is_controlling_instance_for_test(true); - controller_impl->AddAnimation(std::move(second_animation)); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - - // Both animations should have started. - EXPECT_EQ(2u, events->events_.size()); - EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); - EXPECT_EQ(AnimationEvent::STARTED, events->events_[1].type); - - controller_impl->AbortAnimations(TargetProperty::OPACITY); - - events.reset(new AnimationEvents); - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - - // We should have exactly 2 events: a FINISHED event for the tranform - // animation, and an ABORTED event for the opacity animation. - EXPECT_EQ(2u, events->events_.size()); - EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type); - EXPECT_EQ(TargetProperty::TRANSFORM, events->events_[0].target_property); - EXPECT_EQ(AnimationEvent::ABORTED, events->events_[1].type); - EXPECT_EQ(TargetProperty::OPACITY, events->events_[1].target_property); -} - -TEST(LayerAnimationControllerTest, HasAnimationThatAffectsScale) { - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - - EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); - - controller_impl->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - - // Opacity animations don't affect scale. - EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); - - scoped_ptr<KeyframedTransformAnimationCurve> curve1( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations1; - curve1->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); - operations1.AppendTranslate(10.0, 15.0, 0.0); - curve1->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve1), 2, 2, TargetProperty::TRANSFORM)); - controller_impl->AddAnimation(std::move(animation)); - - // Translations don't affect scale. - EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); - - scoped_ptr<KeyframedTransformAnimationCurve> curve2( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations2; - curve2->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); - operations2.AppendScale(2.0, 3.0, 4.0); - curve2->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); - - animation = - Animation::Create(std::move(curve2), 3, 3, TargetProperty::TRANSFORM); - controller_impl->AddAnimation(std::move(animation)); - - EXPECT_TRUE(controller_impl->HasAnimationThatAffectsScale()); - - controller_impl->GetAnimationById(3) - ->SetRunState(Animation::FINISHED, TicksFromSecondsF(0.0)); - - // Only unfinished animations should be considered by - // HasAnimationThatAffectsScale. - EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); -} - -TEST(LayerAnimationControllerTest, HasOnlyTranslationTransforms) { - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::PENDING)); - - controller_impl->AddAnimation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - - // Opacity animations aren't non-translation transforms. - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::PENDING)); - - scoped_ptr<KeyframedTransformAnimationCurve> curve1( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations1; - curve1->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); - operations1.AppendTranslate(10.0, 15.0, 0.0); - curve1->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve1), 2, 2, TargetProperty::TRANSFORM)); - controller_impl->AddAnimation(std::move(animation)); - - // The only transform animation we've added is a translation. - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::PENDING)); - - scoped_ptr<KeyframedTransformAnimationCurve> curve2( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations2; - curve2->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); - operations2.AppendScale(2.0, 3.0, 4.0); - curve2->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); - - animation = - Animation::Create(std::move(curve2), 3, 3, TargetProperty::TRANSFORM); - animation->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(animation)); - - // A scale animation is not a translation. - EXPECT_FALSE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::PENDING)); - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::ACTIVE)); - - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::ACTIVE)); - - controller_impl->GetAnimationById(3)->set_affects_pending_observers(false); - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::ACTIVE)); - - controller_impl->GetAnimationById(3) - ->SetRunState(Animation::FINISHED, TicksFromSecondsF(0.0)); - - // Only unfinished animations should be considered by - // HasOnlyTranslationTransforms. - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::PENDING)); - EXPECT_TRUE(controller_impl->HasOnlyTranslationTransforms( - LayerAnimationController::ObserverType::ACTIVE)); -} - -TEST(LayerAnimationControllerTest, AnimationStartScale) { - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - scoped_ptr<KeyframedTransformAnimationCurve> curve1( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations1; - operations1.AppendScale(2.0, 3.0, 4.0); - curve1->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); - TransformOperations operations2; - curve1->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); - animation->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(animation)); - - float start_scale = 0.f; - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::PENDING, &start_scale)); - EXPECT_EQ(4.f, start_scale); - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::ACTIVE, &start_scale)); - EXPECT_EQ(0.f, start_scale); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::PENDING, &start_scale)); - EXPECT_EQ(4.f, start_scale); - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::ACTIVE, &start_scale)); - EXPECT_EQ(4.f, start_scale); - - scoped_ptr<KeyframedTransformAnimationCurve> curve2( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations3; - curve2->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr)); - operations3.AppendScale(6.0, 5.0, 4.0); - curve2->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations3, nullptr)); - - controller_impl->RemoveAnimation(1); - animation = - Animation::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM); - - // Reverse Direction - animation->set_direction(Animation::DIRECTION_REVERSE); - animation->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(animation)); - - scoped_ptr<KeyframedTransformAnimationCurve> curve3( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations4; - operations4.AppendScale(5.0, 3.0, 1.0); - curve3->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations4, nullptr)); - TransformOperations operations5; - curve3->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations5, nullptr)); - - animation = - Animation::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM); - animation->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(animation)); - - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::PENDING, &start_scale)); - EXPECT_EQ(6.f, start_scale); - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::ACTIVE, &start_scale)); - EXPECT_EQ(0.f, start_scale); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::PENDING, &start_scale)); - EXPECT_EQ(6.f, start_scale); - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::ACTIVE, &start_scale)); - EXPECT_EQ(6.f, start_scale); - - controller_impl->GetAnimationById(2) - ->SetRunState(Animation::FINISHED, TicksFromSecondsF(0.0)); - - // Only unfinished animations should be considered by - // AnimationStartScale. - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::PENDING, &start_scale)); - EXPECT_EQ(5.f, start_scale); - EXPECT_TRUE(controller_impl->AnimationStartScale( - LayerAnimationController::ObserverType::ACTIVE, &start_scale)); - EXPECT_EQ(5.f, start_scale); -} - -TEST(LayerAnimationControllerTest, MaximumTargetScale) { - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - - float max_scale = 0.f; - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(0.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(0.f, max_scale); - - scoped_ptr<KeyframedTransformAnimationCurve> curve1( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations1; - curve1->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); - operations1.AppendScale(2.0, 3.0, 4.0); - curve1->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations1, nullptr)); - - scoped_ptr<Animation> animation( - Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); - animation->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(animation)); - - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(4.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(0.f, max_scale); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(4.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(4.f, max_scale); - - scoped_ptr<KeyframedTransformAnimationCurve> curve2( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations2; - curve2->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr)); - operations2.AppendScale(6.0, 5.0, 4.0); - curve2->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); - - animation = - Animation::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM); - animation->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(animation)); - - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(6.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(4.f, max_scale); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(6.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(6.f, max_scale); - - scoped_ptr<KeyframedTransformAnimationCurve> curve3( - KeyframedTransformAnimationCurve::Create()); - - TransformOperations operations3; - curve3->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr)); - operations3.AppendPerspective(6.0); - curve3->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations3, nullptr)); - - animation = - Animation::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM); - animation->set_affects_active_observers(false); - controller_impl->AddAnimation(std::move(animation)); - - EXPECT_FALSE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(6.f, max_scale); - - controller_impl->ActivateAnimations(); - EXPECT_FALSE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_FALSE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - - controller_impl->GetAnimationById(3) - ->SetRunState(Animation::FINISHED, TicksFromSecondsF(0.0)); - controller_impl->GetAnimationById(2) - ->SetRunState(Animation::FINISHED, TicksFromSecondsF(0.0)); - - // Only unfinished animations should be considered by - // MaximumTargetScale. - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(4.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(4.f, max_scale); -} - -TEST(LayerAnimationControllerTest, MaximumTargetScaleWithDirection) { - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - - scoped_ptr<KeyframedTransformAnimationCurve> curve1( - KeyframedTransformAnimationCurve::Create()); - TransformOperations operations1; - operations1.AppendScale(1.0, 2.0, 3.0); - curve1->AddKeyframe( - TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); - TransformOperations operations2; - operations2.AppendScale(4.0, 5.0, 6.0); - curve1->AddKeyframe(TransformKeyframe::Create( - base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); - - scoped_ptr<Animation> animation_owned( - Animation::Create(std::move(curve1), 1, 1, TargetProperty::TRANSFORM)); - Animation* animation = animation_owned.get(); - controller_impl->AddAnimation(std::move(animation_owned)); - - float max_scale = 0.f; - - EXPECT_GT(animation->playback_rate(), 0.0); - - // NORMAL direction with positive playback rate. - animation->set_direction(Animation::DIRECTION_NORMAL); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(6.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(6.f, max_scale); - - // ALTERNATE direction with positive playback rate. - animation->set_direction(Animation::DIRECTION_ALTERNATE); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(6.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(6.f, max_scale); - - // REVERSE direction with positive playback rate. - animation->set_direction(Animation::DIRECTION_REVERSE); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(3.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(3.f, max_scale); - - // ALTERNATE reverse direction. - animation->set_direction(Animation::DIRECTION_REVERSE); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(3.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(3.f, max_scale); - - animation->set_playback_rate(-1.0); - - // NORMAL direction with negative playback rate. - animation->set_direction(Animation::DIRECTION_NORMAL); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(3.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(3.f, max_scale); - - // ALTERNATE direction with negative playback rate. - animation->set_direction(Animation::DIRECTION_ALTERNATE); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(3.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(3.f, max_scale); - - // REVERSE direction with negative playback rate. - animation->set_direction(Animation::DIRECTION_REVERSE); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(6.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(6.f, max_scale); - - // ALTERNATE reverse direction with negative playback rate. - animation->set_direction(Animation::DIRECTION_REVERSE); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::PENDING, &max_scale)); - EXPECT_EQ(6.f, max_scale); - EXPECT_TRUE(controller_impl->MaximumTargetScale( - LayerAnimationController::ObserverType::ACTIVE, &max_scale)); - EXPECT_EQ(6.f, max_scale); -} - -TEST(LayerAnimationControllerTest, NewlyPushedAnimationWaitsForActivation) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - FakeInactiveLayerAnimationValueObserver pending_dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - controller_impl->AddValueObserver(&pending_dummy_impl); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - EXPECT_FALSE(controller->needs_to_start_animations_for_testing()); - int animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0.5f, 1.f, false); - EXPECT_TRUE(controller->needs_to_start_animations_for_testing()); - - EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing()); - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_TRUE(controller_impl->needs_to_start_animations_for_testing()); - - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)); - EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, - controller_impl->GetAnimationById(animation_id)->run_state()); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_pending_observers()); - EXPECT_FALSE(controller_impl->GetAnimationById(animation_id) - ->affects_active_observers()); - - controller_impl->Animate(kInitialTickTime); - EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing()); - controller_impl->UpdateState(true, events.get()); - - // Since the animation hasn't been activated, it should still be STARTING - // rather than RUNNING. - EXPECT_EQ(Animation::STARTING, - controller_impl->GetAnimationById(animation_id)->run_state()); - - // Since the animation hasn't been activated, only the pending observer - // should have been ticked. - EXPECT_EQ(0.5f, pending_dummy_impl.opacity()); - EXPECT_EQ(0.f, dummy_impl.opacity()); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_pending_observers()); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_active_observers()); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - - // Since the animation has been activated, it should have reached the - // RUNNING state and the active observer should start to get ticked. - EXPECT_EQ(Animation::RUNNING, - controller_impl->GetAnimationById(animation_id)->run_state()); - EXPECT_EQ(0.5f, pending_dummy_impl.opacity()); - EXPECT_EQ(0.5f, dummy_impl.opacity()); -} - -TEST(LayerAnimationControllerTest, ActivationBetweenAnimateAndUpdateState) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - FakeInactiveLayerAnimationValueObserver pending_dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - controller_impl->AddValueObserver(&pending_dummy_impl); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - int animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0.5f, 1.f, true); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id)); - EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, - controller_impl->GetAnimationById(animation_id)->run_state()); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_pending_observers()); - EXPECT_FALSE(controller_impl->GetAnimationById(animation_id) - ->affects_active_observers()); - - controller_impl->Animate(kInitialTickTime); - - // Since the animation hasn't been activated, only the pending observer - // should have been ticked. - EXPECT_EQ(0.5f, pending_dummy_impl.opacity()); - EXPECT_EQ(0.f, dummy_impl.opacity()); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_pending_observers()); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_active_observers()); - - controller_impl->UpdateState(true, events.get()); - - // Since the animation has been activated, it should have reached the - // RUNNING state. - EXPECT_EQ(Animation::RUNNING, - controller_impl->GetAnimationById(animation_id)->run_state()); - - controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - - // Both observers should have been ticked. - EXPECT_EQ(0.75f, pending_dummy_impl.opacity()); - EXPECT_EQ(0.75f, dummy_impl.opacity()); -} - -TEST(LayerAnimationControllerTest, - ObserverNotifiedWhenTransformIsPotentiallyAnimatingChanges) { - AnimationEvents events; - FakeLayerAnimationValueObserver active_dummy_impl; - FakeInactiveLayerAnimationValueObserver pending_dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&active_dummy_impl); - controller_impl->AddValueObserver(&pending_dummy_impl); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - EXPECT_FALSE(dummy.transform_is_animating()); - EXPECT_FALSE(pending_dummy_impl.transform_is_animating()); - EXPECT_FALSE(active_dummy_impl.transform_is_animating()); - - // Case 1: An animation that's allowed to run until its finish point. - AddAnimatedTransformToController(controller.get(), 1.0, 1, 1); - EXPECT_TRUE(dummy.transform_is_animating()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_TRUE(pending_dummy_impl.transform_is_animating()); - EXPECT_FALSE(active_dummy_impl.transform_is_animating()); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(pending_dummy_impl.transform_is_animating()); - EXPECT_TRUE(active_dummy_impl.transform_is_animating()); - - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, &events); - - controller->NotifyAnimationStarted(events.events_[0]); - events.events_.clear(); - - // Finish the animation. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - controller->UpdateState(true, nullptr); - EXPECT_FALSE(dummy.transform_is_animating()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - - // controller_impl hasn't yet ticked at/past the end of the animation. - EXPECT_TRUE(pending_dummy_impl.transform_is_animating()); - EXPECT_TRUE(active_dummy_impl.transform_is_animating()); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, &events); - EXPECT_FALSE(pending_dummy_impl.transform_is_animating()); - EXPECT_FALSE(active_dummy_impl.transform_is_animating()); - - controller->NotifyAnimationFinished(events.events_[0]); - events.events_.clear(); - - // Case 2: An animation that's removed before it finishes. - int animation_id = - AddAnimatedTransformToController(controller.get(), 10.0, 2, 2); - EXPECT_TRUE(dummy.transform_is_animating()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_TRUE(pending_dummy_impl.transform_is_animating()); - EXPECT_FALSE(active_dummy_impl.transform_is_animating()); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(pending_dummy_impl.transform_is_animating()); - EXPECT_TRUE(active_dummy_impl.transform_is_animating()); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(2000)); - controller_impl->UpdateState(true, &events); - - controller->NotifyAnimationStarted(events.events_[0]); - events.events_.clear(); - - controller->RemoveAnimation(animation_id); - EXPECT_FALSE(dummy.transform_is_animating()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_FALSE(pending_dummy_impl.transform_is_animating()); - EXPECT_TRUE(active_dummy_impl.transform_is_animating()); - - controller_impl->ActivateAnimations(); - EXPECT_FALSE(pending_dummy_impl.transform_is_animating()); - EXPECT_FALSE(active_dummy_impl.transform_is_animating()); - - // Case 3: An animation that's aborted before it finishes. - animation_id = AddAnimatedTransformToController(controller.get(), 10.0, 3, 3); - EXPECT_TRUE(dummy.transform_is_animating()); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - EXPECT_TRUE(pending_dummy_impl.transform_is_animating()); - EXPECT_FALSE(active_dummy_impl.transform_is_animating()); - - controller_impl->ActivateAnimations(); - EXPECT_TRUE(pending_dummy_impl.transform_is_animating()); - EXPECT_TRUE(active_dummy_impl.transform_is_animating()); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(3000)); - controller_impl->UpdateState(true, &events); - - controller->NotifyAnimationStarted(events.events_[0]); - events.events_.clear(); - - controller_impl->AbortAnimations(TargetProperty::TRANSFORM); - EXPECT_FALSE(pending_dummy_impl.transform_is_animating()); - EXPECT_FALSE(active_dummy_impl.transform_is_animating()); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(4000)); - controller_impl->UpdateState(true, &events); - - controller->NotifyAnimationAborted(events.events_[0]); - EXPECT_FALSE(dummy.transform_is_animating()); -} - -TEST(LayerAnimationControllerTest, ClippedOpacityValues) { - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - AddOpacityTransitionToController(controller.get(), 1, 1.f, 2.f, true); - - controller->Animate(kInitialTickTime); - EXPECT_EQ(1.f, dummy.opacity()); - - // Opacity values are clipped [0,1] - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - EXPECT_EQ(1.f, dummy.opacity()); -} - -TEST(LayerAnimationControllerTest, ClippedNegativeOpacityValues) { - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - AddOpacityTransitionToController(controller.get(), 1, 0.f, -2.f, true); - - controller->Animate(kInitialTickTime); - EXPECT_EQ(0.f, dummy.opacity()); - - // Opacity values are clipped [0,1] - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); - EXPECT_EQ(0.f, dummy.opacity()); -} - -TEST(LayerAnimationControllerTest, PushedDeletedAnimationWaitsForActivation) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - FakeInactiveLayerAnimationValueObserver pending_dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - controller_impl->AddValueObserver(&pending_dummy_impl); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - int animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0.5f, 1.f, true); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - EXPECT_EQ(Animation::RUNNING, - controller_impl->GetAnimationById(animation_id)->run_state()); - EXPECT_EQ(0.5f, pending_dummy_impl.opacity()); - EXPECT_EQ(0.5f, dummy_impl.opacity()); - - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_pending_observers()); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_active_observers()); - - // Delete the animation on the main-thread controller. - controller->RemoveAnimation( - controller->GetAnimation(TargetProperty::OPACITY)->id()); - controller->PushAnimationUpdatesTo(controller_impl.get()); - - // The animation should no longer affect pending observers. - EXPECT_FALSE(controller_impl->GetAnimationById(animation_id) - ->affects_pending_observers()); - EXPECT_TRUE(controller_impl->GetAnimationById(animation_id) - ->affects_active_observers()); - - controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller_impl->UpdateState(true, events.get()); - - // Only the active observer should have been ticked. - EXPECT_EQ(0.5f, pending_dummy_impl.opacity()); - EXPECT_EQ(0.75f, dummy_impl.opacity()); - - controller_impl->ActivateAnimations(); - - // Activation should cause the animation to be deleted. - EXPECT_FALSE(controller_impl->has_any_animation()); -} - -// Tests that an animation that affects only active observers won't block -// an animation that affects only pending observers from starting. -TEST(LayerAnimationControllerTest, StartAnimationsAffectingDifferentObservers) { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); - FakeLayerAnimationValueObserver dummy_impl; - FakeInactiveLayerAnimationValueObserver pending_dummy_impl; - scoped_refptr<LayerAnimationController> controller_impl( - LayerAnimationController::Create(0)); - controller_impl->AddValueObserver(&dummy_impl); - controller_impl->AddValueObserver(&pending_dummy_impl); - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - int first_animation_id = - AddOpacityTransitionToController(controller.get(), 1, 0.f, 1.f, true); - - controller->PushAnimationUpdatesTo(controller_impl.get()); - controller_impl->ActivateAnimations(); - controller_impl->Animate(kInitialTickTime); - controller_impl->UpdateState(true, events.get()); - - // Remove the first animation from the main-thread controller, and add a - // new animation affecting the same property. - controller->RemoveAnimation( - controller->GetAnimation(TargetProperty::OPACITY)->id()); - int second_animation_id = - AddOpacityTransitionToController(controller.get(), 1, 1.f, 0.5f, true); - controller->PushAnimationUpdatesTo(controller_impl.get()); - - // The original animation should only affect active observers, and the new - // animation should only affect pending observers. - EXPECT_FALSE(controller_impl->GetAnimationById(first_animation_id) - ->affects_pending_observers()); - EXPECT_TRUE(controller_impl->GetAnimationById(first_animation_id) - ->affects_active_observers()); - EXPECT_TRUE(controller_impl->GetAnimationById(second_animation_id) - ->affects_pending_observers()); - EXPECT_FALSE(controller_impl->GetAnimationById(second_animation_id) - ->affects_active_observers()); - - controller_impl->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(500)); - controller_impl->UpdateState(true, events.get()); - - // The original animation should still be running, and the new animation - // should be starting. - EXPECT_EQ(Animation::RUNNING, - controller_impl->GetAnimationById(first_animation_id)->run_state()); - EXPECT_EQ( - Animation::STARTING, - controller_impl->GetAnimationById(second_animation_id)->run_state()); - - // The active observer should have been ticked by the original animation, - // and the pending observer should have been ticked by the new animation. - EXPECT_EQ(1.f, pending_dummy_impl.opacity()); - EXPECT_EQ(0.5f, dummy_impl.opacity()); - - controller_impl->ActivateAnimations(); - - // The original animation should have been deleted, and the new animation - // should now affect both observers. - EXPECT_FALSE(controller_impl->GetAnimationById(first_animation_id)); - EXPECT_TRUE(controller_impl->GetAnimationById(second_animation_id) - ->affects_pending_observers()); - EXPECT_TRUE(controller_impl->GetAnimationById(second_animation_id) - ->affects_active_observers()); - - controller_impl->Animate(kInitialTickTime + - TimeDelta::FromMilliseconds(1000)); - controller_impl->UpdateState(true, events.get()); - - // The new animation should be running, and the active observer should have - // been ticked at the new animation's starting point. - EXPECT_EQ( - Animation::RUNNING, - controller_impl->GetAnimationById(second_animation_id)->run_state()); - EXPECT_EQ(1.f, pending_dummy_impl.opacity()); - EXPECT_EQ(1.f, dummy_impl.opacity()); -} - -TEST(LayerAnimationControllerTest, TestIsCurrentlyAnimatingProperty) { - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - // Create an animation that initially affects only pending observers. - scoped_ptr<Animation> animation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - animation->set_affects_active_observers(false); - - controller->AddAnimation(std::move(animation)); - controller->Animate(kInitialTickTime); - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(controller->HasActiveAnimation()); - - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::ACTIVE)); - - controller->ActivateAnimations(); - - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::ACTIVE)); - - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(10)); - controller->UpdateState(true, nullptr); - - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::ACTIVE)); - - EXPECT_EQ(0.f, dummy.opacity()); - - // Tick past the end of the animation. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1100)); - controller->UpdateState(true, nullptr); - - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::ACTIVE)); - - EXPECT_EQ(1.f, dummy.opacity()); -} - -TEST(LayerAnimationControllerTest, TestIsAnimatingPropertyTimeOffsetFillMode) { - FakeLayerAnimationValueObserver dummy; - scoped_refptr<LayerAnimationController> controller( - LayerAnimationController::Create(0)); - controller->AddValueObserver(&dummy); - - // Create an animation that initially affects only pending observers, and has - // a start delay of 2 seconds. - scoped_ptr<Animation> animation(CreateAnimation( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), 1, - TargetProperty::OPACITY)); - animation->set_fill_mode(Animation::FILL_MODE_NONE); - animation->set_time_offset(TimeDelta::FromMilliseconds(-2000)); - animation->set_affects_active_observers(false); - - controller->AddAnimation(std::move(animation)); - - controller->Animate(kInitialTickTime); - - // Since the animation has a start delay, the observers it affects have a - // potentially running transform animation but aren't currently animating - // transform. - EXPECT_TRUE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_FALSE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::ACTIVE)); - - controller->ActivateAnimations(); - - EXPECT_TRUE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_TRUE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_TRUE(controller->HasActiveAnimation()); - EXPECT_FALSE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::FILTER, LayerAnimationController::ObserverType::ACTIVE)); - - controller->UpdateState(true, nullptr); - - // Tick past the start delay. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - controller->UpdateState(true, nullptr); - EXPECT_TRUE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_TRUE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_TRUE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - - // After the animaton finishes, the observers it affects have neither a - // potentially running transform animation nor a currently running transform - // animation. - controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(4000)); - controller->UpdateState(true, nullptr); - EXPECT_FALSE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsPotentiallyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, - LayerAnimationController::ObserverType::PENDING)); - EXPECT_FALSE(controller->IsCurrentlyAnimatingProperty( - TargetProperty::OPACITY, LayerAnimationController::ObserverType::ACTIVE)); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/animation/layer_animation_event_observer.h b/chromium/cc/animation/layer_animation_event_observer.h deleted file mode 100644 index 93d606edcc8..00000000000 --- a/chromium/cc/animation/layer_animation_event_observer.h +++ /dev/null @@ -1,25 +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_ANIMATION_LAYER_ANIMATION_EVENT_OBSERVER_H_ -#define CC_ANIMATION_LAYER_ANIMATION_EVENT_OBSERVER_H_ - -#include "cc/base/cc_export.h" - -namespace cc { - -struct AnimationEvent; - -class CC_EXPORT LayerAnimationEventObserver { - public: - virtual void OnAnimationStarted(const AnimationEvent& event) = 0; - - protected: - virtual ~LayerAnimationEventObserver() {} -}; - -} // namespace cc - -#endif // CC_ANIMATION_LAYER_ANIMATION_EVENT_OBSERVER_H_ - diff --git a/chromium/cc/animation/layer_animation_value_observer.h b/chromium/cc/animation/layer_animation_value_observer.h deleted file mode 100644 index 092b53b0b9d..00000000000 --- a/chromium/cc/animation/layer_animation_value_observer.h +++ /dev/null @@ -1,35 +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_ANIMATION_LAYER_ANIMATION_VALUE_OBSERVER_H_ -#define CC_ANIMATION_LAYER_ANIMATION_VALUE_OBSERVER_H_ - -#include "cc/base/cc_export.h" - -namespace gfx { -class ScrollOffset; -class Transform; -} - -namespace cc { - -class FilterOperations; - -class CC_EXPORT LayerAnimationValueObserver { - public: - virtual ~LayerAnimationValueObserver() {} - - virtual void OnFilterAnimated(const FilterOperations& filters) = 0; - virtual void OnOpacityAnimated(float opacity) = 0; - virtual void OnTransformAnimated(const gfx::Transform& transform) = 0; - virtual void OnScrollOffsetAnimated( - const gfx::ScrollOffset& scroll_offset) = 0; - virtual void OnAnimationWaitingForDeletion() = 0; - virtual void OnTransformIsPotentiallyAnimatingChanged(bool is_animating) = 0; - virtual bool IsActive() const = 0; -}; - -} // namespace cc - -#endif // CC_ANIMATION_LAYER_ANIMATION_VALUE_OBSERVER_H_ diff --git a/chromium/cc/animation/layer_animation_value_provider.h b/chromium/cc/animation/layer_animation_value_provider.h deleted file mode 100644 index 219afb2f788..00000000000 --- a/chromium/cc/animation/layer_animation_value_provider.h +++ /dev/null @@ -1,28 +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. - -#ifndef CC_ANIMATION_LAYER_ANIMATION_VALUE_PROVIDER_H_ -#define CC_ANIMATION_LAYER_ANIMATION_VALUE_PROVIDER_H_ - -#include "cc/base/cc_export.h" - -namespace gfx { -class ScrollOffset; -} - -namespace cc { - -// A LayerAnimationValueProvider is used for determining the starting value -// for animations that start at their 'current' value rather than at a -// pre-specified value. -class CC_EXPORT LayerAnimationValueProvider { - public: - virtual ~LayerAnimationValueProvider() {} - - virtual gfx::ScrollOffset ScrollOffsetForAnimation() const = 0; -}; - -} // namespace cc - -#endif // CC_ANIMATION_LAYER_ANIMATION_VALUE_PROVIDER_H_ diff --git a/chromium/cc/animation/layer_tree_mutator.h b/chromium/cc/animation/layer_tree_mutator.h new file mode 100644 index 00000000000..d367e268e00 --- /dev/null +++ b/chromium/cc/animation/layer_tree_mutator.h @@ -0,0 +1,24 @@ +// Copyright 2016 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_LAYER_TREE_MUTATOR_H_ +#define CC_ANIMATION_LAYER_TREE_MUTATOR_H_ + +#include "base/callback_forward.h" +#include "cc/base/cc_export.h" + +namespace cc { + +class CC_EXPORT LayerTreeMutator { + public: + virtual ~LayerTreeMutator() {} + + // Returns a callback which is responsible for applying layer tree mutations + // to DOM elements. + virtual base::Closure TakeMutations() = 0; +}; + +} // namespace cc + +#endif // CC_ANIMATION_LAYER_TREE_MUTATOR_H_ diff --git a/chromium/cc/animation/scroll_offset_animation_curve.cc b/chromium/cc/animation/scroll_offset_animation_curve.cc index 86448b73b44..04614b572c8 100644 --- a/chromium/cc/animation/scroll_offset_animation_curve.cc +++ b/chromium/cc/animation/scroll_offset_animation_curve.cc @@ -8,6 +8,7 @@ #include <cmath> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "cc/animation/timing_function.h" #include "cc/base/time_util.h" #include "ui/gfx/animation/tween.h" @@ -63,7 +64,8 @@ static base::TimeDelta SegmentDuration(const gfx::Vector2dF& delta, base::Time::kMicrosecondsPerSecond); } -static scoped_ptr<TimingFunction> EaseOutWithInitialVelocity(double velocity) { +static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity( + double velocity) { // Clamp velocity to a sane value. velocity = std::min(std::max(velocity, -1000.0), 1000.0); @@ -75,17 +77,17 @@ static scoped_ptr<TimingFunction> EaseOutWithInitialVelocity(double velocity) { } // namespace -scoped_ptr<ScrollOffsetAnimationCurve> ScrollOffsetAnimationCurve::Create( +std::unique_ptr<ScrollOffsetAnimationCurve> ScrollOffsetAnimationCurve::Create( const gfx::ScrollOffset& target_value, - scoped_ptr<TimingFunction> timing_function, + std::unique_ptr<TimingFunction> timing_function, DurationBehavior duration_behavior) { - return make_scoped_ptr(new ScrollOffsetAnimationCurve( + return base::WrapUnique(new ScrollOffsetAnimationCurve( target_value, std::move(timing_function), duration_behavior)); } ScrollOffsetAnimationCurve::ScrollOffsetAnimationCurve( const gfx::ScrollOffset& target_value, - scoped_ptr<TimingFunction> timing_function, + std::unique_ptr<TimingFunction> timing_function, DurationBehavior duration_behavior) : target_value_(target_value), timing_function_(std::move(timing_function)), @@ -133,15 +135,15 @@ AnimationCurve::CurveType ScrollOffsetAnimationCurve::Type() const { return SCROLL_OFFSET; } -scoped_ptr<AnimationCurve> ScrollOffsetAnimationCurve::Clone() const { +std::unique_ptr<AnimationCurve> ScrollOffsetAnimationCurve::Clone() const { return CloneToScrollOffsetAnimationCurve(); } -scoped_ptr<ScrollOffsetAnimationCurve> +std::unique_ptr<ScrollOffsetAnimationCurve> ScrollOffsetAnimationCurve::CloneToScrollOffsetAnimationCurve() const { - scoped_ptr<TimingFunction> timing_function( + std::unique_ptr<TimingFunction> timing_function( static_cast<TimingFunction*>(timing_function_->Clone().release())); - scoped_ptr<ScrollOffsetAnimationCurve> curve_clone = + std::unique_ptr<ScrollOffsetAnimationCurve> curve_clone = Create(target_value_, std::move(timing_function), duration_behavior_); curve_clone->initial_value_ = initial_value_; curve_clone->total_animation_duration_ = total_animation_duration_; @@ -180,6 +182,11 @@ static double VelocityBasedDurationBound(gfx::Vector2dF old_delta, void ScrollOffsetAnimationCurve::UpdateTarget( double t, const gfx::ScrollOffset& new_target) { + if (std::abs(MaximumDimension(target_value_.DeltaFrom(new_target))) < + kEpsilon) { + target_value_ = new_target; + return; + } gfx::ScrollOffset current_position = GetValue(base::TimeDelta::FromSecondsD(t)); gfx::Vector2dF old_delta = target_value_.DeltaFrom(initial_value_); diff --git a/chromium/cc/animation/scroll_offset_animation_curve.h b/chromium/cc/animation/scroll_offset_animation_curve.h index 8f9530a0a13..7e5c75bf338 100644 --- a/chromium/cc/animation/scroll_offset_animation_curve.h +++ b/chromium/cc/animation/scroll_offset_animation_curve.h @@ -5,8 +5,9 @@ #ifndef CC_ANIMATION_SCROLL_OFFSET_ANIMATION_CURVE_H_ #define CC_ANIMATION_SCROLL_OFFSET_ANIMATION_CURVE_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/animation/animation_curve.h" #include "cc/base/cc_export.h" @@ -19,9 +20,9 @@ class TimingFunction; class CC_EXPORT ScrollOffsetAnimationCurve : public AnimationCurve { public: enum class DurationBehavior { DELTA_BASED, CONSTANT, INVERSE_DELTA }; - static scoped_ptr<ScrollOffsetAnimationCurve> Create( + static std::unique_ptr<ScrollOffsetAnimationCurve> Create( const gfx::ScrollOffset& target_value, - scoped_ptr<TimingFunction> timing_function, + std::unique_ptr<TimingFunction> timing_function, DurationBehavior = DurationBehavior::DELTA_BASED); ~ScrollOffsetAnimationCurve() override; @@ -35,13 +36,13 @@ class CC_EXPORT ScrollOffsetAnimationCurve : public AnimationCurve { // AnimationCurve implementation base::TimeDelta Duration() const override; CurveType Type() const override; - scoped_ptr<AnimationCurve> Clone() const override; - scoped_ptr<ScrollOffsetAnimationCurve> CloneToScrollOffsetAnimationCurve() - const; + std::unique_ptr<AnimationCurve> Clone() const override; + std::unique_ptr<ScrollOffsetAnimationCurve> + CloneToScrollOffsetAnimationCurve() const; private: ScrollOffsetAnimationCurve(const gfx::ScrollOffset& target_value, - scoped_ptr<TimingFunction> timing_function, + std::unique_ptr<TimingFunction> timing_function, DurationBehavior); gfx::ScrollOffset initial_value_; @@ -51,7 +52,7 @@ class CC_EXPORT ScrollOffsetAnimationCurve : public AnimationCurve { // Time from animation start to most recent UpdateTarget. base::TimeDelta last_retarget_; - scoped_ptr<TimingFunction> timing_function_; + std::unique_ptr<TimingFunction> timing_function_; DurationBehavior duration_behavior_; bool has_set_initial_value_; diff --git a/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc b/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc index 1f6e62a2bf3..f8f95844d81 100644 --- a/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc +++ b/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc @@ -17,7 +17,7 @@ namespace { TEST(ScrollOffsetAnimationCurveTest, DeltaBasedDuration) { gfx::ScrollOffset target_value(100.f, 200.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( + std::unique_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create(target_value, EaseInOutTimingFunction::Create())); @@ -60,7 +60,7 @@ TEST(ScrollOffsetAnimationCurveTest, DeltaBasedDuration) { TEST(ScrollOffsetAnimationCurveTest, GetValue) { gfx::ScrollOffset initial_value(2.f, 40.f); gfx::ScrollOffset target_value(10.f, 20.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( + std::unique_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create(target_value, EaseInOutTimingFunction::Create())); curve->SetInitialValue(initial_value); @@ -93,13 +93,13 @@ TEST(ScrollOffsetAnimationCurveTest, GetValue) { TEST(ScrollOffsetAnimationCurveTest, Clone) { gfx::ScrollOffset initial_value(2.f, 40.f); gfx::ScrollOffset target_value(10.f, 20.f); - scoped_ptr<ScrollOffsetAnimationCurve> curve( + std::unique_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create(target_value, EaseInOutTimingFunction::Create())); curve->SetInitialValue(initial_value); base::TimeDelta duration = curve->Duration(); - scoped_ptr<AnimationCurve> clone(curve->Clone()); + std::unique_ptr<AnimationCurve> clone(curve->Clone()); EXPECT_EQ(AnimationCurve::SCROLL_OFFSET, clone->Type()); EXPECT_EQ(duration, clone->Duration()); @@ -131,7 +131,7 @@ TEST(ScrollOffsetAnimationCurveTest, UpdateTarget) { gfx::ScrollOffset initial_value(0.f, 0.f); gfx::ScrollOffset target_value(0.f, 3600.f); double duration = kConstantDuration / kDurationDivisor; - scoped_ptr<ScrollOffsetAnimationCurve> curve( + std::unique_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create( target_value, EaseInOutTimingFunction::Create(), ScrollOffsetAnimationCurve::DurationBehavior::CONSTANT)); @@ -174,7 +174,7 @@ TEST(ScrollOffsetAnimationCurveTest, UpdateTarget) { } TEST(ScrollOffsetAnimationCurveTest, InverseDeltaDuration) { - scoped_ptr<ScrollOffsetAnimationCurve> curve( + std::unique_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create( gfx::ScrollOffset(0.f, 100.f), EaseInOutTimingFunction::Create(), ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA)); diff --git a/chromium/cc/animation/scroll_offset_animations_impl.cc b/chromium/cc/animation/scroll_offset_animations_impl.cc new file mode 100644 index 00000000000..ba7d1801d29 --- /dev/null +++ b/chromium/cc/animation/scroll_offset_animations_impl.cc @@ -0,0 +1,120 @@ +// 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/animation/scroll_offset_animations_impl.h" + +#include "cc/animation/animation_events.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/timing_function.h" + +namespace cc { + +ScrollOffsetAnimationsImpl::ScrollOffsetAnimationsImpl( + 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_animation_delegate(this); + + animation_host_->AddAnimationTimeline(scroll_offset_timeline_.get()); + scroll_offset_timeline_->AttachPlayer(scroll_offset_animation_player_.get()); +} + +ScrollOffsetAnimationsImpl::~ScrollOffsetAnimationsImpl() { + scroll_offset_timeline_->DetachPlayer(scroll_offset_animation_player_.get()); + animation_host_->RemoveAnimationTimeline(scroll_offset_timeline_.get()); +} + +void ScrollOffsetAnimationsImpl::ScrollAnimationCreate( + ElementId element_id, + const gfx::ScrollOffset& target_offset, + const gfx::ScrollOffset& current_offset) { + std::unique_ptr<ScrollOffsetAnimationCurve> curve = + ScrollOffsetAnimationCurve::Create( + target_offset, EaseInOutTimingFunction::Create(), + ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA); + curve->SetInitialValue(current_offset); + + std::unique_ptr<Animation> animation = Animation::Create( + std::move(curve), AnimationIdProvider::NextAnimationId(), + AnimationIdProvider::NextGroupId(), TargetProperty::SCROLL_OFFSET); + animation->set_is_impl_only(true); + + DCHECK(scroll_offset_animation_player_); + DCHECK(scroll_offset_animation_player_->animation_timeline()); + + ReattachScrollOffsetPlayerIfNeeded(element_id); + + scroll_offset_animation_player_->AddAnimation(std::move(animation)); +} + +bool ScrollOffsetAnimationsImpl::ScrollAnimationUpdateTarget( + ElementId element_id, + const gfx::Vector2dF& scroll_delta, + const gfx::ScrollOffset& max_scroll_offset, + base::TimeTicks frame_monotonic_time) { + DCHECK(scroll_offset_animation_player_); + if (!scroll_offset_animation_player_->element_animations()) + return false; + + DCHECK_EQ(element_id, scroll_offset_animation_player_->element_id()); + + Animation* animation = + scroll_offset_animation_player_->element_animations()->GetAnimation( + TargetProperty::SCROLL_OFFSET); + if (!animation) { + scroll_offset_animation_player_->DetachElement(); + return false; + } + if (scroll_delta.IsZero()) + return true; + + 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; +} + +void ScrollOffsetAnimationsImpl::ScrollAnimationAbort(bool needs_completion) { + DCHECK(scroll_offset_animation_player_); + scroll_offset_animation_player_->AbortAnimations( + TargetProperty::SCROLL_OFFSET, needs_completion); +} + +void ScrollOffsetAnimationsImpl::NotifyAnimationFinished( + base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + int group) { + DCHECK_EQ(target_property, TargetProperty::SCROLL_OFFSET); + DCHECK(animation_host_->mutator_host_client()); + animation_host_->mutator_host_client()->ScrollOffsetAnimationFinished(); +} + +void ScrollOffsetAnimationsImpl::ReattachScrollOffsetPlayerIfNeeded( + ElementId element_id) { + if (scroll_offset_animation_player_->element_id() != element_id) { + if (scroll_offset_animation_player_->element_id()) + scroll_offset_animation_player_->DetachElement(); + if (element_id) + scroll_offset_animation_player_->AttachElement(element_id); + } +} + +} // namespace cc diff --git a/chromium/cc/animation/scroll_offset_animations_impl.h b/chromium/cc/animation/scroll_offset_animations_impl.h new file mode 100644 index 00000000000..47e6d2b37b1 --- /dev/null +++ b/chromium/cc/animation/scroll_offset_animations_impl.h @@ -0,0 +1,77 @@ +// Copyright (c) 2016 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_SCROLL_OFFSET_ANIMATIONS_IMPL_H_ +#define CC_ANIMATION_SCROLL_OFFSET_ANIMATIONS_IMPL_H_ + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "cc/animation/animation_delegate.h" +#include "cc/animation/scroll_offset_animation_curve.h" +#include "cc/trees/mutator_host_client.h" +#include "ui/gfx/geometry/scroll_offset.h" + +namespace cc { + +class AnimationPlayer; +class AnimationHost; +class AnimationTimeline; +class ElementAnimations; + +// Contains an AnimationTimeline and its AnimationPlayer that owns the impl +// only scroll offset animations running on a particular CC Layer. +// We have just one player for impl-only scroll offset animations. I.e. only +// one element can have an impl-only scroll offset animation at any given time. +// Note that this class only exists on the compositor thread. +class CC_EXPORT ScrollOffsetAnimationsImpl : public AnimationDelegate { + public: + explicit ScrollOffsetAnimationsImpl(AnimationHost* animation_host); + + ~ScrollOffsetAnimationsImpl() override; + + void ScrollAnimationCreate(ElementId element_id, + const gfx::ScrollOffset& target_offset, + const gfx::ScrollOffset& current_offset); + + bool ScrollAnimationUpdateTarget(ElementId element_id, + const gfx::Vector2dF& scroll_delta, + const gfx::ScrollOffset& max_scroll_offset, + base::TimeTicks frame_monotonic_time); + + void ScrollAnimationAbort(bool needs_completion); + + // AnimationDelegate implementation. + void NotifyAnimationStarted(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + int group) override {} + void NotifyAnimationFinished(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + int group) override; + void NotifyAnimationAborted(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + int group) override {} + void NotifyAnimationTakeover(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + double animation_start_time, + std::unique_ptr<AnimationCurve> curve) override { + } + + private: + void ReattachScrollOffsetPlayerIfNeeded(ElementId element_id); + + AnimationHost* animation_host_; + scoped_refptr<AnimationTimeline> scroll_offset_timeline_; + + // We have just one player for impl-only scroll offset animations. + // I.e. only one element can have an impl-only scroll offset animation at + // any given time. + scoped_refptr<AnimationPlayer> scroll_offset_animation_player_; + + DISALLOW_COPY_AND_ASSIGN(ScrollOffsetAnimationsImpl); +}; + +} // namespace cc + +#endif // CC_ANIMATION_SCROLL_OFFSET_ANIMATIONS_IMPL_H_ diff --git a/chromium/cc/animation/timing_function.cc b/chromium/cc/animation/timing_function.cc index 94bf12874d3..494d8efda58 100644 --- a/chromium/cc/animation/timing_function.cc +++ b/chromium/cc/animation/timing_function.cc @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "cc/animation/timing_function.h" + +#include <memory> + +#include "base/logging.h" +#include "base/memory/ptr_util.h" #include "cc/base/math_util.h" namespace cc { @@ -13,9 +16,9 @@ TimingFunction::TimingFunction() {} TimingFunction::~TimingFunction() {} -scoped_ptr<CubicBezierTimingFunction> CubicBezierTimingFunction::Create( - double x1, double y1, double x2, double y2) { - return make_scoped_ptr(new CubicBezierTimingFunction(x1, y1, x2, y2)); +std::unique_ptr<CubicBezierTimingFunction> +CubicBezierTimingFunction::Create(double x1, double y1, double x2, double y2) { + return base::WrapUnique(new CubicBezierTimingFunction(x1, y1, x2, y2)); } CubicBezierTimingFunction::CubicBezierTimingFunction(double x1, @@ -35,47 +38,51 @@ float CubicBezierTimingFunction::Velocity(double x) const { } void CubicBezierTimingFunction::Range(float* min, float* max) const { - double min_d = 0; - double max_d = 1; - bezier_.Range(&min_d, &max_d); - *min = static_cast<float>(min_d); - *max = static_cast<float>(max_d); + *min = static_cast<float>(bezier_.range_min()); + *max = static_cast<float>(bezier_.range_max()); } -scoped_ptr<TimingFunction> CubicBezierTimingFunction::Clone() const { - return make_scoped_ptr(new CubicBezierTimingFunction(*this)); +std::unique_ptr<TimingFunction> CubicBezierTimingFunction::Clone() const { + return base::WrapUnique(new CubicBezierTimingFunction(*this)); } // These numbers come from // http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag. -scoped_ptr<TimingFunction> EaseTimingFunction::Create() { +std::unique_ptr<TimingFunction> EaseTimingFunction::Create() { return CubicBezierTimingFunction::Create(0.25, 0.1, 0.25, 1.0); } -scoped_ptr<TimingFunction> EaseInTimingFunction::Create() { +std::unique_ptr<TimingFunction> EaseInTimingFunction::Create() { return CubicBezierTimingFunction::Create(0.42, 0.0, 1.0, 1.0); } -scoped_ptr<TimingFunction> EaseOutTimingFunction::Create() { +std::unique_ptr<TimingFunction> EaseOutTimingFunction::Create() { return CubicBezierTimingFunction::Create(0.0, 0.0, 0.58, 1.0); } -scoped_ptr<TimingFunction> EaseInOutTimingFunction::Create() { +std::unique_ptr<TimingFunction> EaseInOutTimingFunction::Create() { return CubicBezierTimingFunction::Create(0.42, 0.0, 0.58, 1); } -scoped_ptr<StepsTimingFunction> StepsTimingFunction::Create( +std::unique_ptr<StepsTimingFunction> StepsTimingFunction::Create( int steps, - float steps_start_offset) { - return make_scoped_ptr(new StepsTimingFunction(steps, steps_start_offset)); + StepPosition step_position) { + return base::WrapUnique(new StepsTimingFunction(steps, step_position)); } -StepsTimingFunction::StepsTimingFunction(int steps, float steps_start_offset) - : steps_(steps), steps_start_offset_(steps_start_offset) { - // Restrict it to CSS presets: step_start, step_end and step_middle. - // See the Web Animations specification, 3.12.4. Timing in discrete steps. - DCHECK(steps_start_offset_ == 0 || steps_start_offset_ == 1 || - steps_start_offset_ == 0.5); +StepsTimingFunction::StepsTimingFunction(int steps, StepPosition step_position) + : steps_(steps) { + switch (step_position) { + case StepPosition::START: + steps_start_offset_ = 1; + break; + case StepPosition::MIDDLE: + steps_start_offset_ = 0.5; + break; + case StepPosition::END: + steps_start_offset_ = 0; + break; + } } StepsTimingFunction::~StepsTimingFunction() { @@ -88,8 +95,8 @@ float StepsTimingFunction::GetValue(double t) const { return static_cast<float>(value); } -scoped_ptr<TimingFunction> StepsTimingFunction::Clone() const { - return make_scoped_ptr(new StepsTimingFunction(*this)); +std::unique_ptr<TimingFunction> StepsTimingFunction::Clone() const { + return base::WrapUnique(new StepsTimingFunction(*this)); } void StepsTimingFunction::Range(float* min, float* max) const { diff --git a/chromium/cc/animation/timing_function.h b/chromium/cc/animation/timing_function.h index ddc3c51d95d..17b9014c40c 100644 --- a/chromium/cc/animation/timing_function.h +++ b/chromium/cc/animation/timing_function.h @@ -5,8 +5,9 @@ #ifndef CC_ANIMATION_TIMING_FUNCTION_H_ #define CC_ANIMATION_TIMING_FUNCTION_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "ui/gfx/geometry/cubic_bezier.h" @@ -21,7 +22,7 @@ class CC_EXPORT TimingFunction { virtual float Velocity(double time) const = 0; // The smallest and largest values returned by GetValue for inputs in [0, 1]. virtual void Range(float* min, float* max) const = 0; - virtual scoped_ptr<TimingFunction> Clone() const = 0; + virtual std::unique_ptr<TimingFunction> Clone() const = 0; protected: TimingFunction(); @@ -32,15 +33,17 @@ class CC_EXPORT TimingFunction { class CC_EXPORT CubicBezierTimingFunction : public TimingFunction { public: - static scoped_ptr<CubicBezierTimingFunction> Create(double x1, double y1, - double x2, double y2); + static std::unique_ptr<CubicBezierTimingFunction> Create(double x1, + double y1, + double x2, + double y2); ~CubicBezierTimingFunction() override; // TimingFunction implementation. float GetValue(double time) const override; float Velocity(double time) const override; void Range(float* min, float* max) const override; - scoped_ptr<TimingFunction> Clone() const override; + std::unique_ptr<TimingFunction> Clone() const override; protected: CubicBezierTimingFunction(double x1, double y1, double x2, double y2); @@ -53,7 +56,7 @@ class CC_EXPORT CubicBezierTimingFunction : public TimingFunction { class CC_EXPORT EaseTimingFunction { public: - static scoped_ptr<TimingFunction> Create(); + static std::unique_ptr<TimingFunction> Create(); private: DISALLOW_IMPLICIT_CONSTRUCTORS(EaseTimingFunction); @@ -61,7 +64,7 @@ class CC_EXPORT EaseTimingFunction { class CC_EXPORT EaseInTimingFunction { public: - static scoped_ptr<TimingFunction> Create(); + static std::unique_ptr<TimingFunction> Create(); private: DISALLOW_IMPLICIT_CONSTRUCTORS(EaseInTimingFunction); @@ -69,7 +72,7 @@ class CC_EXPORT EaseInTimingFunction { class CC_EXPORT EaseOutTimingFunction { public: - static scoped_ptr<TimingFunction> Create(); + static std::unique_ptr<TimingFunction> Create(); private: DISALLOW_IMPLICIT_CONSTRUCTORS(EaseOutTimingFunction); @@ -77,7 +80,7 @@ class CC_EXPORT EaseOutTimingFunction { class CC_EXPORT EaseInOutTimingFunction { public: - static scoped_ptr<TimingFunction> Create(); + static std::unique_ptr<TimingFunction> Create(); private: DISALLOW_IMPLICIT_CONSTRUCTORS(EaseInOutTimingFunction); @@ -85,18 +88,22 @@ class CC_EXPORT EaseInOutTimingFunction { class CC_EXPORT StepsTimingFunction : public TimingFunction { public: - static scoped_ptr<StepsTimingFunction> Create(int steps, - float steps_start_offset); + // Web Animations specification, 3.12.4. Timing in discrete steps. + enum class StepPosition { START, MIDDLE, END }; + + static std::unique_ptr<StepsTimingFunction> Create( + int steps, + StepPosition step_position); ~StepsTimingFunction() override; float GetValue(double t) const override; - scoped_ptr<TimingFunction> Clone() const override; + std::unique_ptr<TimingFunction> Clone() const override; void Range(float* min, float* max) const override; float Velocity(double time) const override; protected: - StepsTimingFunction(int steps, float steps_start_offset); + StepsTimingFunction(int steps, StepPosition step_position); private: int steps_; diff --git a/chromium/cc/animation/transform_operations.h b/chromium/cc/animation/transform_operations.h index b97ba36c400..e2f547daaff 100644 --- a/chromium/cc/animation/transform_operations.h +++ b/chromium/cc/animation/transform_operations.h @@ -5,11 +5,11 @@ #ifndef CC_ANIMATION_TRANSFORM_OPERATIONS_H_ #define CC_ANIMATION_TRANSFORM_OPERATIONS_H_ +#include <memory> #include <vector> #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/animation/transform_operation.h" #include "cc/base/cc_export.h" #include "ui/gfx/transform.h" @@ -108,7 +108,7 @@ class CC_EXPORT TransformOperations { bool ComputeDecomposedTransform() const; // For efficiency, we cache the decomposed transform. - mutable scoped_ptr<gfx::DecomposedTransform> decomposed_transform_; + mutable std::unique_ptr<gfx::DecomposedTransform> decomposed_transform_; mutable bool decomposed_transform_dirty_; DISALLOW_ASSIGN(TransformOperations); diff --git a/chromium/cc/animation/transform_operations_unittest.cc b/chromium/cc/animation/transform_operations_unittest.cc index 9e3794258af..906be862e51 100644 --- a/chromium/cc/animation/transform_operations_unittest.cc +++ b/chromium/cc/animation/transform_operations_unittest.cc @@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/animation/transform_operations.h" + #include <stddef.h> #include <limits> #include <vector> -#include "cc/animation/transform_operations.h" +#include "base/memory/ptr_util.h" #include "cc/test/geometry_test_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/animation/tween.h" @@ -19,26 +21,26 @@ namespace cc { namespace { TEST(TransformOperationTest, TransformTypesAreUnique) { - std::vector<scoped_ptr<TransformOperations>> transforms; + std::vector<std::unique_ptr<TransformOperations>> transforms; - scoped_ptr<TransformOperations> to_add( - make_scoped_ptr(new TransformOperations())); + std::unique_ptr<TransformOperations> to_add( + base::WrapUnique(new TransformOperations())); to_add->AppendTranslate(1, 0, 0); transforms.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendRotate(0, 0, 1, 2); transforms.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendScale(2, 2, 2); transforms.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendSkew(1, 0); transforms.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendPerspective(800); transforms.push_back(std::move(to_add)); @@ -91,53 +93,53 @@ TEST(TransformOperationTest, MatchTypesDifferentLength) { EXPECT_FALSE(translates.MatchesTypes(translates2)); } -std::vector<scoped_ptr<TransformOperations>> GetIdentityOperations() { - std::vector<scoped_ptr<TransformOperations>> operations; - scoped_ptr<TransformOperations> to_add( - make_scoped_ptr(new TransformOperations())); +std::vector<std::unique_ptr<TransformOperations>> GetIdentityOperations() { + std::vector<std::unique_ptr<TransformOperations>> operations; + std::unique_ptr<TransformOperations> to_add( + base::WrapUnique(new TransformOperations())); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendTranslate(0, 0, 0); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendTranslate(0, 0, 0); to_add->AppendTranslate(0, 0, 0); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendScale(1, 1, 1); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendScale(1, 1, 1); to_add->AppendScale(1, 1, 1); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendSkew(0, 0); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendSkew(0, 0); to_add->AppendSkew(0, 0); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendRotate(0, 0, 1, 0); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendRotate(0, 0, 1, 0); to_add->AppendRotate(0, 0, 1, 0); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendMatrix(gfx::Transform()); operations.push_back(std::move(to_add)); - to_add = make_scoped_ptr(new TransformOperations()); + to_add = base::WrapUnique(new TransformOperations()); to_add->AppendMatrix(gfx::Transform()); to_add->AppendMatrix(gfx::Transform()); operations.push_back(std::move(to_add)); @@ -167,7 +169,7 @@ TEST(TransformOperationTest, MatchTypesOrder) { } TEST(TransformOperationTest, NoneAlwaysMatches) { - std::vector<scoped_ptr<TransformOperations>> operations = + std::vector<std::unique_ptr<TransformOperations>> operations = GetIdentityOperations(); TransformOperations none_operation; @@ -503,7 +505,7 @@ TEST(TransformOperationTest, RotationToZeroDegSameAxes) { } TEST(TransformOperationTest, BlendRotationFromIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { @@ -537,7 +539,7 @@ TEST(TransformOperationTest, BlendRotationFromIdentity) { } TEST(TransformOperationTest, BlendTranslationFromIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { @@ -571,7 +573,7 @@ TEST(TransformOperationTest, BlendTranslationFromIdentity) { } TEST(TransformOperationTest, BlendScaleFromIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { @@ -636,7 +638,7 @@ TEST(TransformOperationTest, BlendSkewFromEmpty) { } TEST(TransformOperationTest, BlendPerspectiveFromIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { @@ -654,7 +656,7 @@ TEST(TransformOperationTest, BlendPerspectiveFromIdentity) { } TEST(TransformOperationTest, BlendRotationToIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { @@ -672,7 +674,7 @@ TEST(TransformOperationTest, BlendRotationToIdentity) { } TEST(TransformOperationTest, BlendTranslationToIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { @@ -690,7 +692,7 @@ TEST(TransformOperationTest, BlendTranslationToIdentity) { } TEST(TransformOperationTest, BlendScaleToIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { @@ -723,7 +725,7 @@ TEST(TransformOperationTest, BlendSkewToEmpty) { } TEST(TransformOperationTest, BlendPerspectiveToIdentity) { - std::vector<scoped_ptr<TransformOperations>> identity_operations = + std::vector<std::unique_ptr<TransformOperations>> identity_operations = GetIdentityOperations(); for (size_t i = 0; i < identity_operations.size(); ++i) { diff --git a/chromium/cc/base/container_util.h b/chromium/cc/base/container_util.h index 65a9d31c1df..c9ebe6929ce 100644 --- a/chromium/cc/base/container_util.h +++ b/chromium/cc/base/container_util.h @@ -5,7 +5,6 @@ #ifndef CC_BASE_CONTAINER_UTIL_H_ #define CC_BASE_CONTAINER_UTIL_H_ -#include "base/memory/scoped_ptr.h" namespace cc { diff --git a/chromium/cc/base/contiguous_container.cc b/chromium/cc/base/contiguous_container.cc index b56b26baad9..d6280b43290 100644 --- a/chromium/cc/base/contiguous_container.cc +++ b/chromium/cc/base/contiguous_container.cc @@ -44,7 +44,7 @@ class ContiguousContainerBase::Buffer { const char* begin() const { return &data_[0]; } // begin() <= end_ <= begin() + capacity_ - scoped_ptr<char[]> data_; + std::unique_ptr<char[]> data_; char* end_; size_t capacity_; }; @@ -136,7 +136,7 @@ ContiguousContainerBase::Buffer* ContiguousContainerBase::AllocateNewBufferForNextAllocation( size_t buffer_size) { DCHECK(buffers_.empty() || end_index_ == buffers_.size() - 1); - scoped_ptr<Buffer> new_buffer(new Buffer(buffer_size)); + std::unique_ptr<Buffer> new_buffer(new Buffer(buffer_size)); Buffer* buffer_to_return = new_buffer.get(); buffers_.push_back(std::move(new_buffer)); end_index_ = buffers_.size() - 1; diff --git a/chromium/cc/base/contiguous_container.h b/chromium/cc/base/contiguous_container.h index 14f61c7401d..d032aa7f8c3 100644 --- a/chromium/cc/base/contiguous_container.h +++ b/chromium/cc/base/contiguous_container.h @@ -6,12 +6,13 @@ #define CC_BASE_CONTIGUOUS_CONTAINER_H_ #include <stddef.h> + +#include <memory> #include <utility> #include "base/compiler_specific.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/stl_util.h" #include "cc/base/cc_export.h" @@ -60,7 +61,7 @@ class CC_EXPORT ContiguousContainerBase { Buffer* AllocateNewBufferForNextAllocation(size_t buffer_size); - std::vector<scoped_ptr<Buffer>> buffers_; + std::vector<std::unique_ptr<Buffer>> buffers_; size_t end_index_; size_t max_object_size_; diff --git a/chromium/cc/base/list_container.h b/chromium/cc/base/list_container.h index 962f6f32a05..04c7f14a032 100644 --- a/chromium/cc/base/list_container.h +++ b/chromium/cc/base/list_container.h @@ -7,9 +7,10 @@ #include <stddef.h> +#include <memory> + #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/base/list_container_helper.h" diff --git a/chromium/cc/base/list_container_helper.cc b/chromium/cc/base/list_container_helper.cc index 7b249ac01f7..9d8a0293a03 100644 --- a/chromium/cc/base/list_container_helper.cc +++ b/chromium/cc/base/list_container_helper.cc @@ -29,7 +29,7 @@ class ListContainerHelper::CharAllocator { // This class holds the raw memory chunk, as well as information about its // size and availability. struct InnerList { - scoped_ptr<char[]> data; + std::unique_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. @@ -66,7 +66,7 @@ class ListContainerHelper::CharAllocator { capacity = size; // Allocate the new data and update the iterator's pointer. - scoped_ptr<char[]> new_data(new char[size * step]); + std::unique_ptr<char[]> new_data(new char[size * step]); size_t position_offset = *position - Begin(); *position = new_data.get() + position_offset; @@ -240,7 +240,7 @@ class ListContainerHelper::CharAllocator { private: void AllocateNewList(size_t list_size) { - scoped_ptr<InnerList> new_list(new InnerList); + std::unique_ptr<InnerList> new_list(new InnerList); new_list->capacity = list_size; new_list->size = 0; new_list->step = element_size_; @@ -248,7 +248,7 @@ class ListContainerHelper::CharAllocator { storage_.push_back(std::move(new_list)); } - std::vector<scoped_ptr<InnerList>> storage_; + std::vector<std::unique_ptr<InnerList>> storage_; const size_t element_size_; // The number of elements in the list. diff --git a/chromium/cc/base/list_container_helper.h b/chromium/cc/base/list_container_helper.h index 61ca25e8858..d4f5ead8ac7 100644 --- a/chromium/cc/base/list_container_helper.h +++ b/chromium/cc/base/list_container_helper.h @@ -7,8 +7,9 @@ #include <stddef.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" namespace cc { @@ -171,7 +172,7 @@ class CC_EXPORT ListContainerHelper final { // 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<CharAllocator> data_; + std::unique_ptr<CharAllocator> data_; DISALLOW_COPY_AND_ASSIGN(ListContainerHelper); }; diff --git a/chromium/cc/base/math_util.cc b/chromium/cc/base/math_util.cc index 147b4005e4e..d078fb6c8ef 100644 --- a/chromium/cc/base/math_util.cc +++ b/chromium/cc/base/math_util.cc @@ -705,15 +705,15 @@ gfx::Vector2dF MathUtil::ProjectVector(const gfx::Vector2dF& source, projected_length * destination.y()); } -scoped_ptr<base::Value> MathUtil::AsValue(const gfx::Size& s) { - scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); +std::unique_ptr<base::Value> MathUtil::AsValue(const gfx::Size& s) { + std::unique_ptr<base::DictionaryValue> res(new base::DictionaryValue()); res->SetDouble("width", s.width()); res->SetDouble("height", s.height()); return std::move(res); } -scoped_ptr<base::Value> MathUtil::AsValue(const gfx::Rect& r) { - scoped_ptr<base::ListValue> res(new base::ListValue()); +std::unique_ptr<base::Value> MathUtil::AsValue(const gfx::Rect& r) { + std::unique_ptr<base::ListValue> res(new base::ListValue()); res->AppendInteger(r.x()); res->AppendInteger(r.y()); res->AppendInteger(r.width()); @@ -742,8 +742,8 @@ bool MathUtil::FromValue(const base::Value* raw_value, gfx::Rect* out_rect) { return true; } -scoped_ptr<base::Value> MathUtil::AsValue(const gfx::PointF& pt) { - scoped_ptr<base::ListValue> res(new base::ListValue()); +std::unique_ptr<base::Value> MathUtil::AsValue(const gfx::PointF& pt) { + std::unique_ptr<base::ListValue> res(new base::ListValue()); res->AppendDouble(pt.x()); res->AppendDouble(pt.y()); return std::move(res); diff --git a/chromium/cc/base/math_util.h b/chromium/cc/base/math_util.h index c596348a0b7..4e3347e3935 100644 --- a/chromium/cc/base/math_util.h +++ b/chromium/cc/base/math_util.h @@ -7,10 +7,10 @@ #include <algorithm> #include <cmath> +#include <memory> #include <vector> #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "ui/gfx/geometry/box_f.h" #include "ui/gfx/geometry/point3_f.h" @@ -254,10 +254,10 @@ class CC_EXPORT MathUtil { const gfx::Vector2dF& destination); // Conversion to value. - static scoped_ptr<base::Value> AsValue(const gfx::Size& s); - static scoped_ptr<base::Value> AsValue(const gfx::Rect& r); + static std::unique_ptr<base::Value> AsValue(const gfx::Size& s); + static std::unique_ptr<base::Value> AsValue(const gfx::Rect& r); static bool FromValue(const base::Value*, gfx::Rect* out_rect); - static scoped_ptr<base::Value> AsValue(const gfx::PointF& q); + static std::unique_ptr<base::Value> AsValue(const gfx::PointF& q); static void AddToTracedValue(const char* name, const gfx::Size& s, diff --git a/chromium/cc/base/region.cc b/chromium/cc/base/region.cc index 8332f9ad67c..1a5823a7f03 100644 --- a/chromium/cc/base/region.cc +++ b/chromium/cc/base/region.cc @@ -120,8 +120,8 @@ std::string Region::ToString() const { return result; } -scoped_ptr<base::Value> Region::AsValue() const { - scoped_ptr<base::ListValue> result(new base::ListValue()); +std::unique_ptr<base::Value> Region::AsValue() const { + std::unique_ptr<base::ListValue> result(new base::ListValue()); for (Iterator it(*this); it.has_rect(); it.next()) { gfx::Rect rect(it.rect()); result->AppendInteger(rect.x()); diff --git a/chromium/cc/base/region.h b/chromium/cc/base/region.h index 583311e09fe..87d79737752 100644 --- a/chromium/cc/base/region.h +++ b/chromium/cc/base/region.h @@ -5,9 +5,9 @@ #ifndef CC_BASE_REGION_H_ #define CC_BASE_REGION_H_ +#include <memory> #include <string> -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "third_party/skia/include/core/SkRegion.h" #include "ui/gfx/geometry/rect.h" @@ -62,7 +62,7 @@ class CC_EXPORT Region { } std::string ToString() const; - scoped_ptr<base::Value> AsValue() const; + std::unique_ptr<base::Value> AsValue() const; void AsValueInto(base::trace_event::TracedValue* array) const; class CC_EXPORT Iterator { diff --git a/chromium/cc/base/switches.cc b/chromium/cc/base/switches.cc index dc79472e883..60a87d38e1e 100644 --- a/chromium/cc/base/switches.cc +++ b/chromium/cc/base/switches.cc @@ -85,9 +85,16 @@ const char kShowReplicaScreenSpaceRects[] = "show-replica-screenspace-rects"; const char kUIShowReplicaScreenSpaceRects[] = "ui-show-replica-screenspace-rects"; +// Switches cc machinery to use layer lists instead of layer trees +const char kEnableLayerLists[] = "enable-layer-lists"; +const char kUIEnableLayerLists[] = "ui-enable-layer-lists"; + // Prevents the layer tree unit tests from timing out. const char kCCLayerTreeTestNoTimeout[] = "cc-layer-tree-test-no-timeout"; +// Increases timeout for memory checkers. +const char kCCLayerTreeTestLongTimeout[] = "cc-layer-tree-test-long-timeout"; + // Makes pixel tests write their output instead of read it. const char kCCRebaselinePixeltests[] = "cc-rebaseline-pixeltests"; diff --git a/chromium/cc/base/switches.h b/chromium/cc/base/switches.h index 07130535092..9eb12df083c 100644 --- a/chromium/cc/base/switches.h +++ b/chromium/cc/base/switches.h @@ -46,9 +46,12 @@ CC_EXPORT extern const char kShowScreenSpaceRects[]; CC_EXPORT extern const char kUIShowScreenSpaceRects[]; CC_EXPORT extern const char kShowReplicaScreenSpaceRects[]; CC_EXPORT extern const char kUIShowReplicaScreenSpaceRects[]; +CC_EXPORT extern const char kEnableLayerLists[]; +CC_EXPORT extern const char kUIEnableLayerLists[]; // Unit test related. CC_EXPORT extern const char kCCLayerTreeTestNoTimeout[]; +CC_EXPORT extern const char kCCLayerTreeTestLongTimeout[]; CC_EXPORT extern const char kCCRebaselinePixeltests[]; } // namespace switches diff --git a/chromium/cc/base/synced_property.h b/chromium/cc/base/synced_property.h index 7d1e563343a..dfb33aa5ab2 100644 --- a/chromium/cc/base/synced_property.h +++ b/chromium/cc/base/synced_property.h @@ -57,45 +57,45 @@ class SyncedProperty : public base::RefCounted<SyncedProperty<T>> { // Returns the latest active tree delta and also makes a note that this value // was sent to the main thread. typename T::ValueType PullDeltaForMainThread() { - sent_delta_ = active_delta_; - return active_delta_.get(); + reflected_delta_in_main_tree_ = PendingDelta(); + return reflected_delta_in_main_tree_.get(); } // Push the latest value from the main thread onto pending tree-associated // state. Returns true if this had any effect. bool PushFromMainThread(typename T::ValueType main_thread_value) { - if (pending_base_.get() == main_thread_value) - return false; + bool changed = pending_base_.get() != main_thread_value; + reflected_delta_in_pending_tree_ = reflected_delta_in_main_tree_; + reflected_delta_in_main_tree_ = T::Identity(); pending_base_ = T(main_thread_value); - return true; + return changed; } // Push the value associated with the pending tree to be the active base - // value. As part of this, subtract the last sent value from the active tree - // delta (which will make the delta zero at steady state, or make it contain - // only the difference since the last send). + // value. As part of this, subtract the delta reflected in the pending tree + // from the active tree delta (which will make the delta zero at steady state, + // or make it contain only the difference since the last send). bool PushPendingToActive() { - if (active_base_.get() == pending_base_.get() && - sent_delta_.get() == T::Identity().get()) - return false; + bool changed = active_base_.get() != pending_base_.get() || + active_delta_.get() != PendingDelta().get(); active_base_ = pending_base_; active_delta_ = PendingDelta(); - sent_delta_ = T::Identity(); + reflected_delta_in_pending_tree_ = T::Identity(); clobber_active_value_ = false; - return true; + return changed; } // This simulates the consequences of the sent value getting committed and - // activated. The value sent to the main thread ends up combined with the - // active value, and the sent_delta is subtracted from the delta. + // activated. void AbortCommit() { - active_base_ = active_base_.Combine(sent_delta_); - active_delta_ = PendingDelta(); - sent_delta_ = T::Identity(); + pending_base_ = pending_base_.Combine(reflected_delta_in_main_tree_); + active_base_ = active_base_.Combine(reflected_delta_in_main_tree_); + active_delta_ = active_delta_.InverseCombine(reflected_delta_in_main_tree_); + reflected_delta_in_main_tree_ = T::Identity(); } // Values as last pushed to the pending or active tree respectively, with no @@ -104,12 +104,11 @@ class SyncedProperty : public base::RefCounted<SyncedProperty<T>> { typename T::ValueType ActiveBase() const { return active_base_.get(); } // The new delta we would use if we decide to activate now. This delta - // excludes the amount that we expect the main thread to reflect back at the - // impl thread during the commit. + // excludes the amount that we know is reflected in the pending tree. T PendingDelta() const { if (clobber_active_value_) return T::Identity(); - return active_delta_.InverseCombine(sent_delta_); + return active_delta_.InverseCombine(reflected_delta_in_pending_tree_); } void set_clobber_active_value() { clobber_active_value_ = true; } @@ -118,13 +117,17 @@ class SyncedProperty : public base::RefCounted<SyncedProperty<T>> { private: // Value last committed to the pending tree. T pending_base_; - // Value last committed to the active tree (on the last activation). + // Value last committed to the active tree on the last activation. T active_base_; - // The difference between the active_base_ and the user-perceived value. + // The difference between |active_base_| and the user-perceived value. T active_delta_; - // The value sent to the main thread (on the last BeginFrame); this is always - // identity outside of the BeginFrame-to-activation interval. - T sent_delta_; + // The value sent to the main thread on the last BeginMainFrame. This is + // always identity outside of the BeginMainFrame to (aborted)commit interval. + T reflected_delta_in_main_tree_; + // The value that was sent to the main thread for BeginMainFrame for the + // current pending tree. This is always identity outside of the + // BeginMainFrame to activation interval. + T reflected_delta_in_pending_tree_; // When true the pending delta is always identity so that it does not change // and will clobber the active value on push. bool clobber_active_value_; diff --git a/chromium/cc/base/unique_notifier_unittest.cc b/chromium/cc/base/unique_notifier_unittest.cc index b53b52a76fd..2c547588198 100644 --- a/chromium/cc/base/unique_notifier_unittest.cc +++ b/chromium/cc/base/unique_notifier_unittest.cc @@ -6,7 +6,7 @@ #include "base/bind_helpers.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/base/unique_notifier.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/cc/blink/BUILD.gn b/chromium/cc/blink/BUILD.gn index 8140a8d5d73..256b0f3575d 100644 --- a/chromium/cc/blink/BUILD.gn +++ b/chromium/cc/blink/BUILD.gn @@ -10,7 +10,6 @@ component("blink") { sources = [ "cc_blink_export.h", - "context_provider_web_context.h", "scrollbar_impl.cc", "scrollbar_impl.h", "web_compositor_support_impl.cc", @@ -51,29 +50,26 @@ component("blink") { } # GYP version: //cc/blink/cc_blink_tests.gyp:cc_blink_unittests -# TODO(GYP): make linking work on the mac. -if (!is_mac) { - test("cc_blink_unittests") { - sources = [ - "web_layer_impl_fixed_bounds_unittest.cc", +test("cc_blink_unittests") { + sources = [ + "web_layer_impl_fixed_bounds_unittest.cc", - # Setup. - "test/cc_blink_test_suite.cc", - "test/run_all_unittests.cc", - ] + # Setup. + "test/cc_blink_test_suite.cc", + "test/run_all_unittests.cc", + ] - deps = [ - ":blink", - "//base/test:test_support", - "//base/third_party/dynamic_annotations", - "//cc", - "//cc:test_support", - "//skia", - "//testing/gmock", - "//testing/gtest", - "//third_party/WebKit/public:blink_for_unittests", - "//ui/gfx:test_support", - "//ui/gfx/geometry", - ] - } + deps = [ + ":blink", + "//base/test:test_support", + "//base/third_party/dynamic_annotations", + "//cc", + "//cc:test_support", + "//skia", + "//testing/gmock", + "//testing/gtest", + "//third_party/WebKit/public:blink_for_unittests", + "//ui/gfx:test_support", + "//ui/gfx/geometry", + ] } diff --git a/chromium/cc/blink/context_provider_web_context.h b/chromium/cc/blink/context_provider_web_context.h deleted file mode 100644 index 21d1df380e2..00000000000 --- a/chromium/cc/blink/context_provider_web_context.h +++ /dev/null @@ -1,24 +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_BLINK_CONTEXT_PROVIDER_WEB_CONTEXT_H_ -#define CC_BLINK_CONTEXT_PROVIDER_WEB_CONTEXT_H_ - -#include "cc/output/context_provider.h" - -namespace blink { class WebGraphicsContext3D; } - -namespace cc_blink { - -class ContextProviderWebContext : public cc::ContextProvider { - public: - virtual blink::WebGraphicsContext3D* WebContext3D() = 0; - - protected: - ~ContextProviderWebContext() override {} -}; - -} // namespace cc_blink - -#endif // CC_BLINK_CONTEXT_PROVIDER_WEB_CONTEXT_H_ diff --git a/chromium/cc/blink/scrollbar_impl.cc b/chromium/cc/blink/scrollbar_impl.cc index 6f5fe31d12d..5df7cfe45ec 100644 --- a/chromium/cc/blink/scrollbar_impl.cc +++ b/chromium/cc/blink/scrollbar_impl.cc @@ -13,9 +13,9 @@ using blink::WebScrollbar; namespace cc_blink { ScrollbarImpl::ScrollbarImpl( - scoped_ptr<WebScrollbar> scrollbar, + std::unique_ptr<WebScrollbar> scrollbar, blink::WebScrollbarThemePainter painter, - scoped_ptr<blink::WebScrollbarThemeGeometry> geometry) + std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry) : scrollbar_(std::move(scrollbar)), painter_(painter), geometry_(std::move(geometry)) {} diff --git a/chromium/cc/blink/scrollbar_impl.h b/chromium/cc/blink/scrollbar_impl.h index 5f11a1b407e..4e4bdaedc25 100644 --- a/chromium/cc/blink/scrollbar_impl.h +++ b/chromium/cc/blink/scrollbar_impl.h @@ -5,8 +5,9 @@ #ifndef CC_BLINK_SCROLLBAR_IMPL_H_ #define CC_BLINK_SCROLLBAR_IMPL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/input/scrollbar.h" #include "third_party/WebKit/public/platform/WebScrollbarThemePainter.h" @@ -19,9 +20,9 @@ namespace cc_blink { class ScrollbarImpl : public cc::Scrollbar { public: - ScrollbarImpl(scoped_ptr<blink::WebScrollbar> scrollbar, + ScrollbarImpl(std::unique_ptr<blink::WebScrollbar> scrollbar, blink::WebScrollbarThemePainter painter, - scoped_ptr<blink::WebScrollbarThemeGeometry> geometry); + std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry); ~ScrollbarImpl() override; // cc::Scrollbar implementation. @@ -40,9 +41,9 @@ class ScrollbarImpl : public cc::Scrollbar { const gfx::Rect& content_rect) override; private: - scoped_ptr<blink::WebScrollbar> scrollbar_; + std::unique_ptr<blink::WebScrollbar> scrollbar_; blink::WebScrollbarThemePainter painter_; - scoped_ptr<blink::WebScrollbarThemeGeometry> geometry_; + std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry_; DISALLOW_COPY_AND_ASSIGN(ScrollbarImpl); }; diff --git a/chromium/cc/blink/web_compositor_support_impl.cc b/chromium/cc/blink/web_compositor_support_impl.cc index a4966e77878..2261c4478f2 100644 --- a/chromium/cc/blink/web_compositor_support_impl.cc +++ b/chromium/cc/blink/web_compositor_support_impl.cc @@ -4,7 +4,8 @@ #include "cc/blink/web_compositor_support_impl.h" -#include "base/memory/scoped_ptr.h" +#include <memory> + #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" diff --git a/chromium/cc/blink/web_compositor_support_impl.h b/chromium/cc/blink/web_compositor_support_impl.h index 9f12dc1d08a..16449437427 100644 --- a/chromium/cc/blink/web_compositor_support_impl.h +++ b/chromium/cc/blink/web_compositor_support_impl.h @@ -12,10 +12,6 @@ #include "third_party/WebKit/public/platform/WebContentLayerClient.h" #include "third_party/WebKit/public/platform/WebLayer.h" -namespace blink { -class WebGraphicsContext3D; -} - namespace cc_blink { class CC_BLINK_EXPORT WebCompositorSupportImpl diff --git a/chromium/cc/blink/web_content_layer_impl.cc b/chromium/cc/blink/web_content_layer_impl.cc index b7a855cd282..cf6e344d1d6 100644 --- a/chromium/cc/blink/web_content_layer_impl.cc +++ b/chromium/cc/blink/web_content_layer_impl.cc @@ -7,6 +7,7 @@ #include <stddef.h> #include "base/command_line.h" +#include "base/memory/ptr_util.h" #include "cc/base/switches.h" #include "cc/blink/web_display_item_list_impl.h" #include "cc/layers/picture_layer.h" @@ -16,7 +17,7 @@ #include "third_party/WebKit/public/platform/WebFloatRect.h" #include "third_party/WebKit/public/platform/WebRect.h" #include "third_party/WebKit/public/platform/WebSize.h" -#include "third_party/skia/include/utils/SkMatrix44.h" +#include "third_party/skia/include/core/SkMatrix44.h" using cc::PictureLayer; @@ -51,7 +52,7 @@ PaintingControlToWeb( WebContentLayerImpl::WebContentLayerImpl(blink::WebContentLayerClient* client) : client_(client) { - layer_ = make_scoped_ptr(new WebLayerImpl(PictureLayer::Create(this))); + layer_ = base::WrapUnique(new WebLayerImpl(PictureLayer::Create(this))); layer_->layer()->SetIsDrawable(true); } diff --git a/chromium/cc/blink/web_content_layer_impl.h b/chromium/cc/blink/web_content_layer_impl.h index 53fd83c0965..227225df997 100644 --- a/chromium/cc/blink/web_content_layer_impl.h +++ b/chromium/cc/blink/web_content_layer_impl.h @@ -7,8 +7,9 @@ #include <stddef.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/blink/cc_blink_export.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/content_layer_client.h" @@ -43,7 +44,7 @@ class WebContentLayerImpl : public blink::WebContentLayer, bool FillsBoundsCompletely() const override; size_t GetApproximateUnsharedMemoryUsage() const override; - scoped_ptr<WebLayerImpl> layer_; + std::unique_ptr<WebLayerImpl> layer_; blink::WebContentLayerClient* client_; private: diff --git a/chromium/cc/blink/web_display_item_list_impl.cc b/chromium/cc/blink/web_display_item_list_impl.cc index b7f050d1dd8..8a7a5746085 100644 --- a/chromium/cc/blink/web_display_item_list_impl.cc +++ b/chromium/cc/blink/web_display_item_list_impl.cc @@ -17,12 +17,11 @@ #include "cc/playback/filter_display_item.h" #include "cc/playback/float_clip_display_item.h" #include "cc/playback/transform_display_item.h" -#include "skia/ext/refptr.h" #include "third_party/WebKit/public/platform/WebFloatRect.h" #include "third_party/WebKit/public/platform/WebRect.h" #include "third_party/skia/include/core/SkColorFilter.h" +#include "third_party/skia/include/core/SkMatrix44.h" #include "third_party/skia/include/core/SkPicture.h" -#include "third_party/skia/include/utils/SkMatrix44.h" #include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/transform.h" @@ -230,6 +229,10 @@ void WebDisplayItemListImpl::appendEndScrollItem( appendEndTransformItem(visual_rect); } +void WebDisplayItemListImpl::setIsSuitableForGpuRasterization(bool isSuitable) { + display_item_list_->SetIsSuitableForGpuRasterization(isSuitable); +} + WebDisplayItemListImpl::~WebDisplayItemListImpl() { } diff --git a/chromium/cc/blink/web_display_item_list_impl.h b/chromium/cc/blink/web_display_item_list_impl.h index a54ac0e47f6..3e0ca83f3ff 100644 --- a/chromium/cc/blink/web_display_item_list_impl.h +++ b/chromium/cc/blink/web_display_item_list_impl.h @@ -75,6 +75,8 @@ class WebDisplayItemListImpl : public blink::WebDisplayItemList { ScrollContainerId) override; void appendEndScrollItem(const blink::WebRect& visual_rect) override; + void setIsSuitableForGpuRasterization(bool isSuitable) override; + private: scoped_refptr<cc::DisplayItemList> display_item_list_; diff --git a/chromium/cc/blink/web_external_bitmap_impl.h b/chromium/cc/blink/web_external_bitmap_impl.h index 20e27df5dcd..d054fd46b42 100644 --- a/chromium/cc/blink/web_external_bitmap_impl.h +++ b/chromium/cc/blink/web_external_bitmap_impl.h @@ -7,9 +7,10 @@ #include <stdint.h> +#include <memory> + #include "base/bind.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/blink/cc_blink_export.h" #include "third_party/WebKit/public/platform/WebExternalBitmap.h" @@ -19,7 +20,7 @@ class SharedBitmap; namespace cc_blink { -typedef scoped_ptr<cc::SharedBitmap>(*SharedBitmapAllocationFunction)( +typedef std::unique_ptr<cc::SharedBitmap> (*SharedBitmapAllocationFunction)( const gfx::Size& size); // Sets the function that this will use to allocate shared memory. @@ -39,7 +40,7 @@ class WebExternalBitmapImpl : public blink::WebExternalBitmap { cc::SharedBitmap* shared_bitmap() { return shared_bitmap_.get(); } private: - scoped_ptr<cc::SharedBitmap> shared_bitmap_; + std::unique_ptr<cc::SharedBitmap> shared_bitmap_; blink::WebSize size_; DISALLOW_COPY_AND_ASSIGN(WebExternalBitmapImpl); diff --git a/chromium/cc/blink/web_external_texture_layer_impl.cc b/chromium/cc/blink/web_external_texture_layer_impl.cc index e08f9e3657c..fabb571fd11 100644 --- a/chromium/cc/blink/web_external_texture_layer_impl.cc +++ b/chromium/cc/blink/web_external_texture_layer_impl.cc @@ -4,6 +4,7 @@ #include "cc/blink/web_external_texture_layer_impl.h" +#include "base/memory/ptr_util.h" #include "cc/blink/web_external_bitmap_impl.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/texture_layer.h" @@ -12,7 +13,6 @@ #include "third_party/WebKit/public/platform/WebExternalTextureLayerClient.h" #include "third_party/WebKit/public/platform/WebExternalTextureMailbox.h" #include "third_party/WebKit/public/platform/WebFloatRect.h" -#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" #include "third_party/WebKit/public/platform/WebSize.h" #include "third_party/khronos/GLES2/gl2.h" @@ -63,7 +63,7 @@ void WebExternalTextureLayerImpl::setNearestNeighbor(bool nearest_neighbor) { bool WebExternalTextureLayerImpl::PrepareTextureMailbox( cc::TextureMailbox* mailbox, - scoped_ptr<cc::SingleReleaseCallback>* release_callback, + std::unique_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) { blink::WebExternalTextureMailbox client_mailbox; WebExternalBitmapImpl* bitmap = nullptr; @@ -72,7 +72,7 @@ bool WebExternalTextureLayerImpl::PrepareTextureMailbox( bitmap = AllocateBitmap(); if (!client_->prepareMailbox(&client_mailbox, bitmap)) { if (bitmap) - free_bitmaps_.push_back(make_scoped_ptr(bitmap)); + free_bitmaps_.push_back(base::WrapUnique(bitmap)); return false; } gpu::Mailbox name; @@ -92,9 +92,10 @@ bool WebExternalTextureLayerImpl::PrepareTextureMailbox( client_mailbox.textureSize.height); } - *mailbox = - cc::TextureMailbox(name, sync_token, client_mailbox.textureTarget, size, - client_mailbox.allowOverlay, false); + *mailbox = cc::TextureMailbox( + name, sync_token, client_mailbox.textureTarget, size, + gfx::GpuMemoryBufferId(client_mailbox.gpuMemoryBufferId), + client_mailbox.allowOverlay, false); } mailbox->set_nearest_neighbor(client_mailbox.nearestNeighbor); @@ -134,7 +135,7 @@ void WebExternalTextureLayerImpl::DidReleaseMailbox( sizeof(sync_token)); available_mailbox.validSyncToken = sync_token.HasData(); if (bitmap) - layer->free_bitmaps_.push_back(make_scoped_ptr(bitmap)); + layer->free_bitmaps_.push_back(base::WrapUnique(bitmap)); layer->client_->mailboxReleased(available_mailbox, lost_resource); } diff --git a/chromium/cc/blink/web_external_texture_layer_impl.h b/chromium/cc/blink/web_external_texture_layer_impl.h index c85668f2e3a..cce8170080f 100644 --- a/chromium/cc/blink/web_external_texture_layer_impl.h +++ b/chromium/cc/blink/web_external_texture_layer_impl.h @@ -5,11 +5,11 @@ #ifndef CC_BLINK_WEB_EXTERNAL_TEXTURE_LAYER_IMPL_H_ #define CC_BLINK_WEB_EXTERNAL_TEXTURE_LAYER_IMPL_H_ +#include <memory> #include <vector> #include "base/bind.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/blink/cc_blink_export.h" #include "cc/layers/texture_layer_client.h" #include "third_party/WebKit/public/platform/WebExternalTextureLayer.h" @@ -50,7 +50,7 @@ class WebExternalTextureLayerImpl // TextureLayerClient implementation. bool PrepareTextureMailbox( cc::TextureMailbox* mailbox, - scoped_ptr<cc::SingleReleaseCallback>* release_callback, + std::unique_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) override; private: @@ -64,8 +64,8 @@ class WebExternalTextureLayerImpl WebExternalBitmapImpl* AllocateBitmap(); blink::WebExternalTextureLayerClient* client_; - scoped_ptr<WebLayerImpl> layer_; - std::vector<scoped_ptr<WebExternalBitmapImpl>> free_bitmaps_; + std::unique_ptr<WebLayerImpl> layer_; + std::vector<std::unique_ptr<WebExternalBitmapImpl>> free_bitmaps_; DISALLOW_COPY_AND_ASSIGN(WebExternalTextureLayerImpl); }; diff --git a/chromium/cc/blink/web_image_layer_impl.cc b/chromium/cc/blink/web_image_layer_impl.cc index 68f61985fea..32f753053b4 100644 --- a/chromium/cc/blink/web_image_layer_impl.cc +++ b/chromium/cc/blink/web_image_layer_impl.cc @@ -23,9 +23,8 @@ blink::WebLayer* WebImageLayerImpl::layer() { } void WebImageLayerImpl::setImage(const SkImage* image) { - skia::RefPtr<const SkImage> imageRef = skia::SharePtr(image); static_cast<cc::PictureImageLayer*>(layer_->layer()) - ->SetImage(std::move(imageRef)); + ->SetImage(sk_ref_sp(image)); static_cast<WebLayerImplFixedBounds*>(layer_.get()) ->SetFixedBounds(gfx::Size(image->width(), image->height())); } diff --git a/chromium/cc/blink/web_image_layer_impl.h b/chromium/cc/blink/web_image_layer_impl.h index d2775fb7e34..84433bd626d 100644 --- a/chromium/cc/blink/web_image_layer_impl.h +++ b/chromium/cc/blink/web_image_layer_impl.h @@ -5,8 +5,9 @@ #ifndef CC_BLINK_WEB_IMAGE_LAYER_IMPL_H_ #define CC_BLINK_WEB_IMAGE_LAYER_IMPL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/blink/cc_blink_export.h" #include "third_party/WebKit/public/platform/WebImageLayer.h" @@ -25,7 +26,7 @@ class WebImageLayerImpl : public blink::WebImageLayer { void setNearestNeighbor(bool nearest_neighbor) override; private: - scoped_ptr<WebLayerImpl> layer_; + std::unique_ptr<WebLayerImpl> layer_; DISALLOW_COPY_AND_ASSIGN(WebImageLayerImpl); }; diff --git a/chromium/cc/blink/web_layer_impl.cc b/chromium/cc/blink/web_layer_impl.cc index 845e9710b1d..abb6e501137 100644 --- a/chromium/cc/blink/web_layer_impl.cc +++ b/chromium/cc/blink/web_layer_impl.cc @@ -25,7 +25,7 @@ #include "third_party/WebKit/public/platform/WebLayerPositionConstraint.h" #include "third_party/WebKit/public/platform/WebLayerScrollClient.h" #include "third_party/WebKit/public/platform/WebSize.h" -#include "third_party/skia/include/utils/SkMatrix44.h" +#include "third_party/skia/include/core/SkMatrix44.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/vector2d_conversions.h" @@ -215,10 +215,6 @@ bool WebLayerImpl::hasActiveAnimationForTesting() { return layer_->HasActiveAnimationForTesting(); } -void WebLayerImpl::setForceRenderSurface(bool force_render_surface) { - layer_->SetForceRenderSurface(force_render_surface); -} - void WebLayerImpl::setScrollPositionDouble(blink::WebDoublePoint position) { layer_->SetScrollOffset(gfx::ScrollOffset(position.x, position.y)); } @@ -301,31 +297,6 @@ WebVector<WebRect> WebLayerImpl::nonFastScrollableRegion() const { return result; } -void WebLayerImpl::setFrameTimingRequests( - const WebVector<std::pair<int64_t, WebRect>>& requests) { - std::vector<cc::FrameTimingRequest> frame_timing_requests(requests.size()); - for (size_t i = 0; i < requests.size(); ++i) { - frame_timing_requests[i] = cc::FrameTimingRequest( - requests[i].first, gfx::Rect(requests[i].second)); - } - layer_->SetFrameTimingRequests(frame_timing_requests); -} - -WebVector<std::pair<int64_t, WebRect>> WebLayerImpl::frameTimingRequests() - const { - const std::vector<cc::FrameTimingRequest>& frame_timing_requests = - layer_->FrameTimingRequests(); - - size_t num_requests = frame_timing_requests.size(); - - WebVector<std::pair<int64_t, WebRect>> result(num_requests); - for (size_t i = 0; i < num_requests; ++i) { - result[i] = std::make_pair(frame_timing_requests[i].id(), - frame_timing_requests[i].rect()); - } - return result; -} - void WebLayerImpl::setTouchEventHandlerRegion(const WebVector<WebRect>& rects) { cc::Region region; for (size_t i = 0; i < rects.size(); ++i) @@ -446,4 +417,8 @@ void WebLayerImpl::SetContentsOpaqueIsFixed(bool fixed) { contents_opaque_is_fixed_ = fixed; } +void WebLayerImpl::setHasWillChangeTransformHint(bool has_will_change) { + layer_->SetHasWillChangeTransformHint(has_will_change); +} + } // namespace cc_blink diff --git a/chromium/cc/blink/web_layer_impl.h b/chromium/cc/blink/web_layer_impl.h index 14d49ab342a..9558e03f06e 100644 --- a/chromium/cc/blink/web_layer_impl.h +++ b/chromium/cc/blink/web_layer_impl.h @@ -8,12 +8,12 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> #include <utility> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/blink/cc_blink_export.h" #include "cc/layers/layer_client.h" #include "third_party/WebKit/public/platform/WebColor.h" @@ -25,7 +25,7 @@ #include "third_party/WebKit/public/platform/WebSize.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/skia/include/utils/SkMatrix44.h" +#include "third_party/skia/include/core/SkMatrix44.h" namespace blink { struct WebFloatRect; @@ -98,7 +98,6 @@ class WebLayerImpl : public blink::WebLayer { void setFilters(const cc::FilterOperations& filters) override; void setBackgroundFilters(const cc::FilterOperations& filters) override; bool hasActiveAnimationForTesting() override; - void setForceRenderSurface(bool force) override; void setScrollPositionDouble(blink::WebDoublePoint position) override; blink::WebDoublePoint scrollPositionDouble() const override; void setScrollClipLayer(blink::WebLayer* clip_layer) override; @@ -118,11 +117,6 @@ class WebLayerImpl : public blink::WebLayer { void setTouchEventHandlerRegion( const blink::WebVector<blink::WebRect>& region) override; blink::WebVector<blink::WebRect> touchEventHandlerRegion() const override; - void setFrameTimingRequests( - const blink::WebVector<std::pair<int64_t, blink::WebRect>>& requests) - override; - blink::WebVector<std::pair<int64_t, blink::WebRect>> frameTimingRequests() - const override; void setIsContainerForFixedPositionLayers(bool is_container) override; bool isContainerForFixedPositionLayers() const override; void setPositionConstraint( @@ -136,6 +130,7 @@ class WebLayerImpl : public blink::WebLayer { uint64_t elementId() const override; void setCompositorMutableProperties(uint32_t properties) override; uint32_t compositorMutableProperties() const override; + void setHasWillChangeTransformHint(bool has_will_change) override; void setScrollParent(blink::WebLayer* parent) override; void setClipParent(blink::WebLayer* parent) override; diff --git a/chromium/cc/blink/web_layer_impl_fixed_bounds.cc b/chromium/cc/blink/web_layer_impl_fixed_bounds.cc index e7ecb349073..ed4ba18d7ff 100644 --- a/chromium/cc/blink/web_layer_impl_fixed_bounds.cc +++ b/chromium/cc/blink/web_layer_impl_fixed_bounds.cc @@ -7,7 +7,7 @@ #include "cc/layers/layer.h" #include "third_party/WebKit/public/platform/WebFloatPoint.h" #include "third_party/WebKit/public/platform/WebSize.h" -#include "third_party/skia/include/utils/SkMatrix44.h" +#include "third_party/skia/include/core/SkMatrix44.h" using cc::Layer; 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 884cbdb257d..1fa6b8dd268 100644 --- a/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc +++ b/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc @@ -12,7 +12,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebFloatPoint.h" #include "third_party/WebKit/public/platform/WebSize.h" -#include "third_party/skia/include/utils/SkMatrix44.h" +#include "third_party/skia/include/core/SkMatrix44.h" #include "ui/gfx/geometry/point3_f.h" using blink::WebFloatPoint; @@ -22,7 +22,7 @@ namespace cc_blink { namespace { TEST(WebLayerImplFixedBoundsTest, IdentityBounds) { - scoped_ptr<WebLayerImplFixedBounds> layer(new WebLayerImplFixedBounds()); + std::unique_ptr<WebLayerImplFixedBounds> layer(new WebLayerImplFixedBounds()); layer->SetFixedBounds(gfx::Size(100, 100)); layer->setBounds(WebSize(100, 100)); EXPECT_EQ(WebSize(100, 100), layer->bounds()); @@ -59,7 +59,7 @@ void CheckBoundsScaleSimple(WebLayerImplFixedBounds* layer, } TEST(WebLayerImplFixedBoundsTest, BoundsScaleSimple) { - scoped_ptr<WebLayerImplFixedBounds> layer(new WebLayerImplFixedBounds()); + std::unique_ptr<WebLayerImplFixedBounds> layer(new WebLayerImplFixedBounds()); CheckBoundsScaleSimple(layer.get(), WebSize(100, 200), gfx::Size(150, 250)); // Change fixed_bounds. CheckBoundsScaleSimple(layer.get(), WebSize(100, 200), gfx::Size(75, 100)); @@ -87,7 +87,8 @@ void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point, WebFloatPoint position(20, 30); gfx::Size fixed_bounds(160, 70); - scoped_ptr<WebLayerImplFixedBounds> root_layer(new WebLayerImplFixedBounds()); + std::unique_ptr<WebLayerImplFixedBounds> root_layer( + new WebLayerImplFixedBounds()); WebLayerImplFixedBounds* fixed_bounds_layer = new WebLayerImplFixedBounds(cc::PictureImageLayer::Create()); @@ -106,7 +107,7 @@ void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point, cc::FakeLayerTreeHostClient client(cc::FakeLayerTreeHostClient::DIRECT_3D); cc::TestTaskGraphRunner task_graph_runner; - scoped_ptr<cc::FakeLayerTreeHost> host = + std::unique_ptr<cc::FakeLayerTreeHost> host = cc::FakeLayerTreeHost::Create(&client, &task_graph_runner); host->SetRootLayer(root_layer->layer()); diff --git a/chromium/cc/blink/web_scrollbar_layer_impl.cc b/chromium/cc/blink/web_scrollbar_layer_impl.cc index e31f5c6d59e..7011d5fc91e 100644 --- a/chromium/cc/blink/web_scrollbar_layer_impl.cc +++ b/chromium/cc/blink/web_scrollbar_layer_impl.cc @@ -4,6 +4,7 @@ #include "cc/blink/web_scrollbar_layer_impl.h" +#include "base/memory/ptr_util.h" #include "cc/blink/scrollbar_impl.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/layer.h" @@ -32,10 +33,10 @@ WebScrollbarLayerImpl::WebScrollbarLayerImpl( blink::WebScrollbarThemeGeometry* geometry) : layer_(new WebLayerImpl(PaintedScrollbarLayer::Create( - scoped_ptr<cc::Scrollbar>( - new ScrollbarImpl(make_scoped_ptr(scrollbar), + std::unique_ptr<cc::Scrollbar>( + new ScrollbarImpl(base::WrapUnique(scrollbar), painter, - make_scoped_ptr(geometry))), + base::WrapUnique(geometry))), 0))) {} WebScrollbarLayerImpl::WebScrollbarLayerImpl( diff --git a/chromium/cc/blink/web_scrollbar_layer_impl.h b/chromium/cc/blink/web_scrollbar_layer_impl.h index f9cd68cd6e3..0239b413d6f 100644 --- a/chromium/cc/blink/web_scrollbar_layer_impl.h +++ b/chromium/cc/blink/web_scrollbar_layer_impl.h @@ -5,8 +5,9 @@ #ifndef CC_BLINK_WEB_SCROLLBAR_LAYER_IMPL_H_ #define CC_BLINK_WEB_SCROLLBAR_LAYER_IMPL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/blink/cc_blink_export.h" #include "third_party/WebKit/public/platform/WebScrollbar.h" #include "third_party/WebKit/public/platform/WebScrollbarLayer.h" @@ -38,7 +39,7 @@ class WebScrollbarLayerImpl : public blink::WebScrollbarLayer { void setScrollLayer(blink::WebLayer* layer) override; private: - scoped_ptr<WebLayerImpl> layer_; + std::unique_ptr<WebLayerImpl> layer_; DISALLOW_COPY_AND_ASSIGN(WebScrollbarLayerImpl); }; diff --git a/chromium/cc/cc.gyp b/chromium/cc/cc.gyp index ca59ec2e126..cd88ff8ae43 100644 --- a/chromium/cc/cc.gyp +++ b/chromium/cc/cc.gyp @@ -48,21 +48,16 @@ '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', - 'animation/layer_animation_controller.h', - 'animation/layer_animation_event_observer.h', - 'animation/layer_animation_value_observer.h', - 'animation/layer_animation_value_provider.h', 'animation/scroll_offset_animation_curve.cc', 'animation/scroll_offset_animation_curve.h', + 'animation/scroll_offset_animations_impl.cc', + 'animation/scroll_offset_animations_impl.h', 'animation/target_property.cc', 'animation/target_property.h', 'animation/timing_function.cc', @@ -113,10 +108,6 @@ 'debug/devtools_instrumentation.h', 'debug/frame_rate_counter.cc', 'debug/frame_rate_counter.h', - 'debug/frame_timing_request.cc', - 'debug/frame_timing_request.h', - 'debug/frame_timing_tracker.cc', - 'debug/frame_timing_tracker.h', 'debug/frame_viewer_instrumentation.cc', 'debug/frame_viewer_instrumentation.h', 'debug/invalidation_benchmark.cc', @@ -185,16 +176,14 @@ 'layers/heads_up_display_layer.h', 'layers/heads_up_display_layer_impl.cc', 'layers/heads_up_display_layer_impl.h', - 'layers/io_surface_layer.cc', - 'layers/io_surface_layer.h', - 'layers/io_surface_layer_impl.cc', - 'layers/io_surface_layer_impl.h', 'layers/layer.cc', 'layers/layer_client.h', 'layers/layer_collections.h', 'layers/layer.h', 'layers/layer_impl.cc', 'layers/layer_impl.h', + "layers/layer_impl_test_properties.cc", + "layers/layer_impl_test_properties.h", 'layers/layer_iterator.h', 'layers/layer_list_iterator.cc', 'layers/layer_list_iterator.h', @@ -271,7 +260,6 @@ 'output/compositor_frame_ack.h', 'output/compositor_frame_metadata.cc', 'output/compositor_frame_metadata.h', - 'output/context_provider.cc', 'output/context_provider.h', 'output/copy_output_request.cc', 'output/copy_output_request.h', @@ -338,12 +326,16 @@ 'output/texture_mailbox_deleter.h', 'output/viewport_selection_bound.cc', 'output/viewport_selection_bound.h', + 'output/vulkan_context_provider.h', + 'output/vulkan_in_process_context_provider.h', + 'output/vulkan_in_process_context_provider.cc', 'playback/clip_display_item.cc', 'playback/clip_display_item.h', 'playback/clip_path_display_item.cc', 'playback/clip_path_display_item.h', 'playback/compositing_display_item.cc', 'playback/compositing_display_item.h', + 'playback/decoded_draw_image.cc', 'playback/decoded_draw_image.h', 'playback/discardable_image_map.cc', 'playback/discardable_image_map.h', @@ -396,8 +388,6 @@ 'quads/draw_polygon.h', 'quads/draw_quad.cc', 'quads/draw_quad.h', - 'quads/io_surface_draw_quad.cc', - 'quads/io_surface_draw_quad.h', 'quads/largest_draw_quad.cc', 'quads/largest_draw_quad.h', 'quads/picture_draw_quad.cc', @@ -422,16 +412,18 @@ 'quads/tile_draw_quad.h', 'quads/yuv_video_draw_quad.cc', 'quads/yuv_video_draw_quad.h', - 'raster/bitmap_tile_task_worker_pool.cc', - 'raster/bitmap_tile_task_worker_pool.h', + 'raster/bitmap_raster_buffer_provider.cc', + 'raster/bitmap_raster_buffer_provider.h', + 'raster/gpu_raster_buffer_provider.cc', + 'raster/gpu_raster_buffer_provider.h', 'raster/gpu_rasterizer.cc', 'raster/gpu_rasterizer.h', - 'raster/gpu_tile_task_worker_pool.cc', - 'raster/gpu_tile_task_worker_pool.h', - 'raster/one_copy_tile_task_worker_pool.cc', - 'raster/one_copy_tile_task_worker_pool.h', + 'raster/one_copy_raster_buffer_provider.cc', + 'raster/one_copy_raster_buffer_provider.h', 'raster/raster_buffer.cc', 'raster/raster_buffer.h', + 'raster/raster_buffer_provider.cc', + 'raster/raster_buffer_provider.h', 'raster/scoped_gpu_raster.cc', 'raster/scoped_gpu_raster.h', 'raster/single_thread_task_graph_runner.cc', @@ -440,8 +432,9 @@ 'raster/staging_buffer_pool.h', 'raster/synchronous_task_graph_runner.cc', 'raster/synchronous_task_graph_runner.h', + 'raster/task.cc', + 'raster/task.h', 'raster/task_category.h', - 'raster/task_graph_runner.cc', 'raster/task_graph_runner.h', 'raster/task_graph_work_queue.cc', 'raster/task_graph_work_queue.h', @@ -449,12 +442,10 @@ 'raster/texture_compressor.h', 'raster/texture_compressor_etc1.cc', 'raster/texture_compressor_etc1.h', - 'raster/tile_task_runner.cc', - 'raster/tile_task_runner.h', - 'raster/tile_task_worker_pool.cc', - 'raster/tile_task_worker_pool.h', - 'raster/zero_copy_tile_task_worker_pool.cc', - 'raster/zero_copy_tile_task_worker_pool.h', + 'raster/tile_task.cc', + 'raster/tile_task.h', + 'raster/zero_copy_raster_buffer_provider.cc', + 'raster/zero_copy_raster_buffer_provider.h', 'resources/memory_history.cc', 'resources/memory_history.h', 'resources/platform_color.h', @@ -535,6 +526,8 @@ 'tiles/tile_manager.h', 'tiles/tile_priority.cc', 'tiles/tile_priority.h', + 'tiles/tile_task_manager.cc', + 'tiles/tile_task_manager.h', 'tiles/tiling_set_eviction_queue.cc', 'tiles/tiling_set_eviction_queue.h', 'tiles/tiling_set_raster_queue_all.cc', diff --git a/chromium/cc/cc_tests.gyp b/chromium/cc/cc_tests.gyp index 785c560960f..041b5c489a7 100644 --- a/chromium/cc/cc_tests.gyp +++ b/chromium/cc/cc_tests.gyp @@ -12,7 +12,6 @@ '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', 'animation/transform_operations_unittest.cc', 'base/contiguous_container_unittest.cc', @@ -28,7 +27,6 @@ 'base/simple_enclosed_region_unittest.cc', 'base/tiling_data_unittest.cc', 'base/unique_notifier_unittest.cc', - 'debug/frame_timing_tracker_unittest.cc', 'debug/layer_tree_debug_state_unittest.cc', 'debug/micro_benchmark_controller_unittest.cc', 'debug/rendering_stats_unittest.cc', @@ -37,9 +35,9 @@ 'input/scrollbar_animation_controller_linear_fade_unittest.cc', 'input/scrollbar_animation_controller_thinning_unittest.cc', 'input/top_controls_manager_unittest.cc', + 'ipc/cc_param_traits_unittest.cc', 'layers/heads_up_display_layer_impl_unittest.cc', 'layers/heads_up_display_unittest.cc', - 'layers/io_surface_layer_impl_unittest.cc', 'layers/layer_impl_unittest.cc', 'layers/layer_iterator_unittest.cc', 'layers/layer_list_iterator_unittest.cc', @@ -97,11 +95,11 @@ 'quads/draw_polygon_unittest.cc', 'quads/draw_quad_unittest.cc', 'quads/render_pass_unittest.cc', + 'raster/raster_buffer_provider_unittest.cc', 'raster/scoped_gpu_raster_unittest.cc', 'raster/single_thread_task_graph_runner_unittest.cc', 'raster/synchronous_task_graph_runner_unittest.cc', 'raster/texture_compressor_etc1_unittest.cc', - 'raster/tile_task_worker_pool_unittest.cc', 'resources/platform_color_unittest.cc', 'resources/resource_pool_unittest.cc', 'resources/resource_provider_unittest.cc', @@ -119,6 +117,7 @@ 'test/mock_helper_unittest.cc', 'test/ordered_simple_task_runner_unittest.cc', 'test/test_web_graphics_context_3d_unittest.cc', + 'tiles/gpu_image_decode_controller_unittest.cc', 'tiles/picture_layer_tiling_set_unittest.cc', 'tiles/picture_layer_tiling_unittest.cc', 'tiles/software_image_decode_controller_unittest.cc', @@ -213,6 +212,8 @@ 'test/fake_picture_layer_tiling_client.h', 'test/fake_proxy.cc', 'test/fake_proxy.h', + 'test/fake_raster_buffer_provider.cc', + 'test/fake_raster_buffer_provider.h', 'test/fake_raster_source.cc', 'test/fake_raster_source.h', 'test/fake_recording_source.cc', @@ -229,6 +230,8 @@ 'test/fake_tile_manager.h', 'test/fake_tile_manager_client.cc', 'test/fake_tile_manager_client.h', + 'test/fake_tile_task_manager.cc', + 'test/fake_tile_task_manager.h', 'test/fake_ui_resource_layer_tree_host_impl.cc', 'test/fake_ui_resource_layer_tree_host_impl.h', 'test/fake_video_frame_provider.cc', @@ -245,6 +248,8 @@ 'test/layer_tree_pixel_resource_test.h', 'test/layer_tree_pixel_test.cc', 'test/layer_tree_pixel_test.h', + 'test/layer_tree_settings_for_testing.cc', + 'test/layer_tree_settings_for_testing.h', 'test/layer_tree_test.cc', 'test/layer_tree_test.h', 'test/mock_helper.h', @@ -301,6 +306,8 @@ 'test/test_image_factory.h', 'test/test_in_process_context_provider.cc', 'test/test_in_process_context_provider.h', + 'test/test_layer_tree_host_base.cc', + 'test/test_layer_tree_host_base.h', 'test/test_occlusion_tracker.h', 'test/test_shared_bitmap_manager.cc', 'test/test_shared_bitmap_manager.h', @@ -325,6 +332,7 @@ '../gpu/command_buffer/command_buffer.gyp:gles2_utils', '../gpu/gpu.gyp:gpu', '../gpu/gpu.gyp:gpu_unittest_utils', + '../ipc/ipc.gyp:ipc', '../media/media.gyp:media', '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', @@ -337,6 +345,7 @@ 'cc.gyp:cc_proto', 'cc.gyp:cc_surfaces', 'cc_test_support', + 'ipc/cc_ipc.gyp:cc_ipc', ], 'sources': [ 'test/cc_test_suite.cc', @@ -363,6 +372,7 @@ '../gpu/command_buffer/command_buffer.gyp:gles2_utils', '../gpu/gpu.gyp:gpu', '../gpu/gpu.gyp:gpu_unittest_utils', + '../ipc/ipc.gyp:ipc', '../media/media.gyp:media', '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', @@ -373,20 +383,21 @@ 'cc.gyp:cc', 'cc.gyp:cc_surfaces', 'cc_test_support', + 'ipc/cc_ipc.gyp:cc_ipc', ], 'sources': [ # Note: sources list duplicated in GN build. 'animation/animation_host_perftest.cc', + 'ipc/cc_param_traits_perftest.cc', 'layers/layer_perftest.cc', 'layers/picture_layer_impl_perftest.cc', 'quads/draw_quad_perftest.cc', + 'raster/raster_buffer_provider_perftest.cc', 'raster/task_graph_runner_perftest.cc', 'raster/texture_compressor_perftest.cc', - 'raster/tile_task_worker_pool_perftest.cc', 'surfaces/surface_aggregator_perftest.cc', 'test/cc_test_suite.cc', 'test/run_all_perftests.cc', - 'tiles/picture_layer_tiling_perftest.cc', 'tiles/tile_manager_perftest.cc', 'trees/layer_tree_host_common_perftest.cc', 'trees/layer_tree_host_perftest.cc', @@ -425,6 +436,7 @@ '../ui/gfx/gfx.gyp:gfx_test_support', '../ui/gl/gl.gyp:gl', '../ui/gl/gl.gyp:gl_test_support', + 'cc.gyp:cc', 'cc.gyp:cc_proto', ], 'sources': [ diff --git a/chromium/cc/debug/benchmark_instrumentation.cc b/chromium/cc/debug/benchmark_instrumentation.cc index ed8fe214fdf..c32565ee622 100644 --- a/chromium/cc/debug/benchmark_instrumentation.cc +++ b/chromium/cc/debug/benchmark_instrumentation.cc @@ -20,7 +20,7 @@ void IssueImplThreadRenderingStatsEvent(const RenderingStats& stats) { } void IssueDisplayRenderingStatsEvent() { - scoped_ptr<base::trace_event::TracedValue> record_data( + std::unique_ptr<base::trace_event::TracedValue> record_data( new base::trace_event::TracedValue()); record_data->SetInteger("frame_count", 1); TRACE_EVENT_INSTANT1( diff --git a/chromium/cc/debug/debug_rect_history.cc b/chromium/cc/debug/debug_rect_history.cc index cd3830317fe..53381cfd207 100644 --- a/chromium/cc/debug/debug_rect_history.cc +++ b/chromium/cc/debug/debug_rect_history.cc @@ -6,6 +6,7 @@ #include <stddef.h> +#include "base/memory/ptr_util.h" #include "cc/base/math_util.h" #include "cc/layers/layer_impl.h" #include "cc/layers/layer_iterator.h" @@ -21,8 +22,8 @@ namespace cc { // static -scoped_ptr<DebugRectHistory> DebugRectHistory::Create() { - return make_scoped_ptr(new DebugRectHistory()); +std::unique_ptr<DebugRectHistory> DebugRectHistory::Create() { + return base::WrapUnique(new DebugRectHistory()); } DebugRectHistory::DebugRectHistory() {} @@ -99,8 +100,7 @@ void DebugRectHistory::SavePropertyChangedRects( ++layer_index) { LayerImpl* layer = layer_list[layer_index]; - if (LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>( - layer, render_surface_layer->id())) + if (layer->render_surface() && layer->render_surface() != render_surface) continue; if (layer == hud_layer) @@ -160,8 +160,7 @@ void DebugRectHistory::SaveScreenSpaceRects( void DebugRectHistory::SaveTouchEventHandlerRects(LayerTreeImpl* tree_impl) { LayerTreeHostCommon::CallFunctionForEveryLayer( tree_impl, - [this](LayerImpl* layer) { SaveTouchEventHandlerRectsCallback(layer); }, - CallFunctionLayerType::ALL_LAYERS); + [this](LayerImpl* layer) { SaveTouchEventHandlerRectsCallback(layer); }); } void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) { @@ -200,8 +199,7 @@ void DebugRectHistory::SaveWheelEventHandlerRects(LayerImpl* root_layer) { void DebugRectHistory::SaveScrollEventHandlerRects(LayerTreeImpl* tree_impl) { LayerTreeHostCommon::CallFunctionForEveryLayer( tree_impl, - [this](LayerImpl* layer) { SaveScrollEventHandlerRectsCallback(layer); }, - CallFunctionLayerType::ALL_LAYERS); + [this](LayerImpl* layer) { SaveScrollEventHandlerRectsCallback(layer); }); } void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { @@ -217,8 +215,7 @@ void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { void DebugRectHistory::SaveNonFastScrollableRects(LayerTreeImpl* tree_impl) { LayerTreeHostCommon::CallFunctionForEveryLayer( tree_impl, - [this](LayerImpl* layer) { SaveNonFastScrollableRectsCallback(layer); }, - CallFunctionLayerType::ALL_LAYERS); + [this](LayerImpl* layer) { SaveNonFastScrollableRectsCallback(layer); }); } void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) { diff --git a/chromium/cc/debug/debug_rect_history.h b/chromium/cc/debug/debug_rect_history.h index b06dc58a2a8..4ffbd8ca826 100644 --- a/chromium/cc/debug/debug_rect_history.h +++ b/chromium/cc/debug/debug_rect_history.h @@ -5,9 +5,10 @@ #ifndef CC_DEBUG_DEBUG_RECT_HISTORY_H_ #define CC_DEBUG_DEBUG_RECT_HISTORY_H_ +#include <memory> #include <vector> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/layers/layer_collections.h" #include "ui/gfx/geometry/rect.h" @@ -61,7 +62,7 @@ struct DebugRect { // the appropriate LayerTreeSettings are enabled. class DebugRectHistory { public: - static scoped_ptr<DebugRectHistory> Create(); + static std::unique_ptr<DebugRectHistory> Create(); ~DebugRectHistory(); diff --git a/chromium/cc/debug/devtools_instrumentation.h b/chromium/cc/debug/devtools_instrumentation.h index 5794b8992ee..127c9a93c26 100644 --- a/chromium/cc/debug/devtools_instrumentation.h +++ b/chromium/cc/debug/devtools_instrumentation.h @@ -7,8 +7,9 @@ #include <stdint.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" @@ -148,9 +149,9 @@ inline void DidRequestMainThreadFrame(int layer_tree_host_id) { layer_tree_host_id); } -inline scoped_ptr<base::trace_event::ConvertableToTraceFormat> +inline std::unique_ptr<base::trace_event::ConvertableToTraceFormat> BeginMainThreadFrameData(int frame_id) { - scoped_ptr<base::trace_event::TracedValue> value( + std::unique_ptr<base::trace_event::TracedValue> value( new base::trace_event::TracedValue()); value->SetInteger("frameId", frame_id); return std::move(value); @@ -163,9 +164,9 @@ inline void WillBeginMainThreadFrame(int layer_tree_host_id, int frame_id) { internal::kData, BeginMainThreadFrameData(frame_id)); } -inline scoped_ptr<base::trace_event::ConvertableToTraceFormat> +inline std::unique_ptr<base::trace_event::ConvertableToTraceFormat> NeedsBeginFrameData(bool needs_begin_frame) { - scoped_ptr<base::trace_event::TracedValue> value( + std::unique_ptr<base::trace_event::TracedValue> value( new base::trace_event::TracedValue()); value->SetInteger("needsBeginFrame", needs_begin_frame); return std::move(value); diff --git a/chromium/cc/debug/frame_rate_counter.cc b/chromium/cc/debug/frame_rate_counter.cc index a6b4a44519b..928c27ce5f1 100644 --- a/chromium/cc/debug/frame_rate_counter.cc +++ b/chromium/cc/debug/frame_rate_counter.cc @@ -9,6 +9,7 @@ #include <algorithm> #include <limits> +#include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" #include "cc/trees/proxy.h" @@ -33,8 +34,9 @@ static const double kFrameTooSlow = 1.5; static const double kDroppedFrameTime = 1.0 / 50.0; // static -scoped_ptr<FrameRateCounter> FrameRateCounter::Create(bool has_impl_thread) { - return make_scoped_ptr(new FrameRateCounter(has_impl_thread)); +std::unique_ptr<FrameRateCounter> FrameRateCounter::Create( + bool has_impl_thread) { + return base::WrapUnique(new FrameRateCounter(has_impl_thread)); } base::TimeDelta FrameRateCounter::RecentFrameInterval(size_t n) const { diff --git a/chromium/cc/debug/frame_rate_counter.h b/chromium/cc/debug/frame_rate_counter.h index ad91598a9b8..ba2d122cf1d 100644 --- a/chromium/cc/debug/frame_rate_counter.h +++ b/chromium/cc/debug/frame_rate_counter.h @@ -7,8 +7,9 @@ #include <stddef.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/debug/ring_buffer.h" @@ -18,7 +19,7 @@ namespace cc { // intelligently compute average frames per second. class FrameRateCounter { public: - static scoped_ptr<FrameRateCounter> Create(bool has_impl_thread); + static std::unique_ptr<FrameRateCounter> Create(bool has_impl_thread); size_t current_frame_number() const { return ring_buffer_.CurrentIndex(); } int dropped_frame_count() const { return dropped_frame_count_; } diff --git a/chromium/cc/debug/frame_timing_request.cc b/chromium/cc/debug/frame_timing_request.cc deleted file mode 100644 index 211d57d51f2..00000000000 --- a/chromium/cc/debug/frame_timing_request.cc +++ /dev/null @@ -1,19 +0,0 @@ -// 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 <stdint.h> - -#include "cc/debug/frame_timing_request.h" - -namespace cc { - -FrameTimingRequest::FrameTimingRequest() : id_(0) { -} - -FrameTimingRequest::FrameTimingRequest(int64_t request_id, - const gfx::Rect& rect) - : id_(request_id), rect_(rect) { -} - -} // namespace cc diff --git a/chromium/cc/debug/frame_timing_request.h b/chromium/cc/debug/frame_timing_request.h deleted file mode 100644 index 6b2b57c5f5f..00000000000 --- a/chromium/cc/debug/frame_timing_request.h +++ /dev/null @@ -1,41 +0,0 @@ -// 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_FRAME_TIMING_REQUEST_H_ -#define CC_DEBUG_FRAME_TIMING_REQUEST_H_ - -#include <stdint.h> - -#include "cc/base/cc_export.h" -#include "ui/gfx/geometry/rect.h" - -namespace cc { - -// This class represents a request to record frame timing information about the -// given rect (in layer space) and an associated request id. When this request -// is propagated to the active LayerImpl, it will cause events to be saved in -// FrameTimingTracker, which in turn can be consumed by the requester. -class CC_EXPORT FrameTimingRequest { - public: - FrameTimingRequest(); - FrameTimingRequest(int64_t request_id, const gfx::Rect& rect); - - // Return the ID for the request. - int64_t id() const { return id_; } - - // 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_; -}; - -} // namespace cc - -#endif // CC_DEBUG_FRAME_TIMING_REQUEST_H_ diff --git a/chromium/cc/debug/frame_timing_tracker.cc b/chromium/cc/debug/frame_timing_tracker.cc deleted file mode 100644 index dda2e311e51..00000000000 --- a/chromium/cc/debug/frame_timing_tracker.cc +++ /dev/null @@ -1,118 +0,0 @@ -// 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/frame_timing_tracker.h" - -#include <stdint.h> - -#include <algorithm> -#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, - base::TimeTicks _timestamp) - : frame_id(_frame_id), timestamp(_timestamp) { -} - -FrameTimingTracker::CompositeTimingEvent::~CompositeTimingEvent() { -} - -FrameTimingTracker::MainFrameTimingEvent::MainFrameTimingEvent( - int frame_id, - base::TimeTicks timestamp, - base::TimeTicks end_time) - : frame_id(frame_id), timestamp(timestamp), end_time(end_time) { -} - -FrameTimingTracker::MainFrameTimingEvent::~MainFrameTimingEvent() { -} - -// static -scoped_ptr<FrameTimingTracker> FrameTimingTracker::Create( - LayerTreeHostImpl* layer_tree_host_impl) { - return make_scoped_ptr(new FrameTimingTracker(layer_tree_host_impl)); -} - -FrameTimingTracker::FrameTimingTracker(LayerTreeHostImpl* layer_tree_host_impl) - : layer_tree_host_impl_(layer_tree_host_impl), - post_events_notifier_( - layer_tree_host_impl_->GetTaskRunner(), - base::Bind(&FrameTimingTracker::PostEvents, base::Unretained(this)), - base::TimeDelta::FromMilliseconds(kSendTimingIntervalMS)) {} - -FrameTimingTracker::~FrameTimingTracker() { -} - -void FrameTimingTracker::SaveTimeStamps( - base::TimeTicks timestamp, - const std::vector<FrameAndRectIds>& frame_ids) { - if (!composite_events_) - composite_events_.reset(new CompositeTimingSet); - for (const auto& pair : frame_ids) { - (*composite_events_)[pair.second].push_back( - CompositeTimingEvent(pair.first, timestamp)); - } - if (!post_events_notifier_.HasPendingNotification()) - post_events_notifier_.Schedule(); -} - -void FrameTimingTracker::SaveMainFrameTimeStamps( - const std::vector<int64_t>& request_ids, - base::TimeTicks main_frame_time, - base::TimeTicks end_time, - int source_frame_number) { - if (!main_frame_events_) - main_frame_events_.reset(new MainFrameTimingSet); - for (const auto& request : request_ids) { - std::vector<MainFrameTimingEvent>& events = (*main_frame_events_)[request]; - 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> -FrameTimingTracker::GroupCompositeCountsByRectId() { - if (!composite_events_) - return make_scoped_ptr(new CompositeTimingSet); - for (auto& infos : *composite_events_) { - std::sort( - infos.second.begin(), infos.second.end(), - [](const CompositeTimingEvent& lhs, const CompositeTimingEvent& rhs) { - return lhs.timestamp < rhs.timestamp; - }); - } - return std::move(composite_events_); -} - -scoped_ptr<FrameTimingTracker::MainFrameTimingSet> -FrameTimingTracker::GroupMainFrameCountsByRectId() { - if (!main_frame_events_) - return make_scoped_ptr(new MainFrameTimingSet); - for (auto& infos : *main_frame_events_) { - std::sort( - infos.second.begin(), infos.second.end(), - [](const MainFrameTimingEvent& lhs, const MainFrameTimingEvent& rhs) { - return lhs.timestamp < rhs.timestamp; - }); - } - return std::move(main_frame_events_); -} - -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 deleted file mode 100644 index 117a1f9c9d9..00000000000 --- a/chromium/cc/debug/frame_timing_tracker.h +++ /dev/null @@ -1,98 +0,0 @@ -// 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_FRAME_TIMING_TRACKER_H_ -#define CC_DEBUG_FRAME_TIMING_TRACKER_H_ - -#include <stdint.h> - -#include <unordered_map> -#include <utility> -#include <vector> - -#include "base/macros.h" -#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 -class CC_EXPORT FrameTimingTracker { - public: - struct CC_EXPORT CompositeTimingEvent { - CompositeTimingEvent(int, base::TimeTicks); - ~CompositeTimingEvent(); - - int frame_id; - base::TimeTicks timestamp; - }; - - using CompositeTimingSet = - std::unordered_map<int64_t, std::vector<CompositeTimingEvent>>; - - struct CC_EXPORT MainFrameTimingEvent { - MainFrameTimingEvent(int frame_id, - base::TimeTicks timestamp, - base::TimeTicks end_time); - ~MainFrameTimingEvent(); - - int frame_id; - base::TimeTicks timestamp; - base::TimeTicks end_time; - }; - - using MainFrameTimingSet = - std::unordered_map<int64_t, std::vector<MainFrameTimingEvent>>; - - static scoped_ptr<FrameTimingTracker> Create( - LayerTreeHostImpl* layer_tree_host_impl); - - ~FrameTimingTracker(); - - // This routine takes all of the individual CompositeEvents stored in the - // tracker and collects them by "rect_id", as in the example below. - // [ {f_id1,r_id1,t1}, {f_id2,r_id1,t2}, {f_id3,r_id2,t3} ] - // ====> - // [ {r_id1,<{f_id1,t1},{f_id2,t2}>}, {r_id2,<{f_id3,t3}>} ] - scoped_ptr<CompositeTimingSet> GroupCompositeCountsByRectId(); - - // This routine takes all of the individual MainFrameEvents stored in the - // tracker and collects them by "rect_id", as in the example below. - scoped_ptr<MainFrameTimingSet> GroupMainFrameCountsByRectId(); - - // This routine takes a timestamp and an array of frame_id,rect_id pairs - // and generates CompositeTimingEvents (frame_id, timestamp) and adds them to - // internal hash_map keyed on rect_id - using FrameAndRectIds = std::pair<int, int64_t>; - void SaveTimeStamps(base::TimeTicks timestamp, - const std::vector<FrameAndRectIds>& frame_ids); - - void SaveMainFrameTimeStamps(const std::vector<int64_t>& request_ids, - base::TimeTicks main_frame_time, - base::TimeTicks end_time, - int source_frame_number); - - private: - 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); -}; - -} // namespace cc - -#endif // CC_DEBUG_FRAME_TIMING_TRACKER_H_ diff --git a/chromium/cc/debug/frame_timing_tracker_unittest.cc b/chromium/cc/debug/frame_timing_tracker_unittest.cc deleted file mode 100644 index 2bef6b451cf..00000000000 --- a/chromium/cc/debug/frame_timing_tracker_unittest.cc +++ /dev/null @@ -1,297 +0,0 @@ -// 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 <stdint.h> - -#include <set> -#include <string> - -#include "base/time/time.h" -#include "base/trace_event/trace_event_argument.h" -#include "base/values.h" -#include "cc/debug/frame_timing_tracker.h" -#include "cc/test/fake_impl_task_runner_provider.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 { -namespace { - -std::string CompositeToString( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> timingset) { - scoped_ptr<base::trace_event::TracedValue> value( - new base::trace_event::TracedValue()); - value->BeginArray("values"); - std::set<int> rect_ids; - for (const auto& pair : *timingset) - rect_ids.insert(pair.first); - - for (const auto& rect_id : rect_ids) { - auto& events = (*timingset)[rect_id]; - value->BeginDictionary(); - value->SetInteger("rect_id", rect_id); - value->BeginArray("events"); - for (const auto& event : events) { - value->BeginDictionary(); - value->SetInteger("frame_id", event.frame_id); - value->SetInteger("timestamp", event.timestamp.ToInternalValue()); - value->EndDictionary(); - } - value->EndArray(); - value->EndDictionary(); - } - value->EndArray(); - return value->ToString(); -} - -std::string MainFrameToString( - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> timingset) { - scoped_ptr<base::trace_event::TracedValue> value( - new base::trace_event::TracedValue()); - value->BeginArray("values"); - std::set<int> rect_ids; - for (const auto& pair : *timingset) - rect_ids.insert(pair.first); - - for (const auto& rect_id : rect_ids) { - auto& events = (*timingset)[rect_id]; - value->BeginDictionary(); - value->SetInteger("rect_id", rect_id); - value->BeginArray("events"); - for (const auto& event : events) { - value->BeginDictionary(); - value->SetInteger("end_time", event.end_time.ToInternalValue()); - value->SetInteger("frame_id", event.frame_id); - value->SetInteger("timestamp", event.timestamp.ToInternalValue()); - value->EndDictionary(); - } - value->EndArray(); - value->EndDictionary(); - } - value->EndArray(); - return value->ToString(); -} - -TEST(FrameTimingTrackerTest, DefaultTrackerIsEmpty) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); - - scoped_ptr<FrameTimingTracker> tracker( - FrameTimingTracker::Create(&host_impl)); - EXPECT_EQ("{\"values\":[]}", - CompositeToString(tracker->GroupCompositeCountsByRectId())); - EXPECT_EQ("{\"values\":[]}", - MainFrameToString(tracker->GroupMainFrameCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, NoFrameIdsIsEmpty) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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\":[]}", - CompositeToString(tracker->GroupCompositeCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, NoRectIdsYieldsNoMainFrameEvents) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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); - EXPECT_EQ("{\"values\":[]}", - MainFrameToString(tracker->GroupMainFrameCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, OneFrameId) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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); - EXPECT_EQ( - "{\"values\":[{\"events\":[" - "{\"frame_id\":1,\"timestamp\":100}],\"rect_id\":2}]}", - CompositeToString(tracker->GroupCompositeCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, OneMainFrameRect) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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, - base::TimeTicks::FromInternalValue(100), - base::TimeTicks::FromInternalValue(110), 2); - EXPECT_EQ( - "{\"values\":[{\"events\":[" - "{\"end_time\":110,\"frame_id\":2,\"timestamp\":100}],\"rect_id\":1}]}", - MainFrameToString(tracker->GroupMainFrameCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, UnsortedTimestampsIds) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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); - tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(400), ids); - tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids); - EXPECT_EQ( - "{\"values\":[{\"events\":[" - "{\"frame_id\":1,\"timestamp\":100}," - "{\"frame_id\":1,\"timestamp\":200}," - "{\"frame_id\":1,\"timestamp\":400}],\"rect_id\":2}]}", - CompositeToString(tracker->GroupCompositeCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, MainFrameUnsortedTimestamps) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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, - base::TimeTicks::FromInternalValue(200), - base::TimeTicks::FromInternalValue(280), 1); - tracker->SaveMainFrameTimeStamps(rect_ids, - base::TimeTicks::FromInternalValue(400), - base::TimeTicks::FromInternalValue(470), 1); - tracker->SaveMainFrameTimeStamps(rect_ids, - base::TimeTicks::FromInternalValue(100), - base::TimeTicks::FromInternalValue(160), 1); - EXPECT_EQ( - "{\"values\":[{\"events\":[" - "{\"end_time\":160,\"frame_id\":1,\"timestamp\":100}," - "{\"end_time\":280,\"frame_id\":1,\"timestamp\":200}," - "{\"end_time\":470,\"frame_id\":1,\"timestamp\":400}],\"rect_id\":2}]}", - MainFrameToString(tracker->GroupMainFrameCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, MultipleFrameIds) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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)); - ids200.push_back(std::make_pair(1, 3)); - tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(200), ids200); - - std::vector<std::pair<int, int64_t>> ids400; - ids400.push_back(std::make_pair(2, 2)); - tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(400), ids400); - - std::vector<std::pair<int, int64_t>> ids100; - ids100.push_back(std::make_pair(3, 2)); - ids100.push_back(std::make_pair(2, 3)); - ids100.push_back(std::make_pair(3, 4)); - tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids100); - - EXPECT_EQ( - "{\"values\":[{\"events\":[" - "{\"frame_id\":3,\"timestamp\":100}," - "{\"frame_id\":1,\"timestamp\":200}," - "{\"frame_id\":2,\"timestamp\":400}],\"rect_id\":2}," - "{\"events\":[" - "{\"frame_id\":2,\"timestamp\":100}," - "{\"frame_id\":1,\"timestamp\":200}],\"rect_id\":3}," - "{\"events\":[" - "{\"frame_id\":3,\"timestamp\":100}],\"rect_id\":4}" - "]}", - CompositeToString(tracker->GroupCompositeCountsByRectId())); -} - -TEST(FrameTimingTrackerTest, MultipleMainFrameEvents) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &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); - rect_ids200.push_back(3); - tracker->SaveMainFrameTimeStamps(rect_ids200, - base::TimeTicks::FromInternalValue(200), - base::TimeTicks::FromInternalValue(220), 1); - - std::vector<int64_t> rect_ids400; - rect_ids400.push_back(2); - tracker->SaveMainFrameTimeStamps(rect_ids400, - base::TimeTicks::FromInternalValue(400), - base::TimeTicks::FromInternalValue(440), 2); - - std::vector<int64_t> rect_ids100; - rect_ids100.push_back(2); - rect_ids100.push_back(3); - rect_ids100.push_back(4); - tracker->SaveMainFrameTimeStamps(rect_ids100, - base::TimeTicks::FromInternalValue(100), - base::TimeTicks::FromInternalValue(110), 3); - - EXPECT_EQ( - "{\"values\":[{\"events\":[" - "{\"end_time\":110,\"frame_id\":3,\"timestamp\":100}," - "{\"end_time\":220,\"frame_id\":1,\"timestamp\":200}," - "{\"end_time\":440,\"frame_id\":2,\"timestamp\":400}],\"rect_id\":2}," - "{\"events\":[" - "{\"end_time\":110,\"frame_id\":3,\"timestamp\":100}," - "{\"end_time\":220,\"frame_id\":1,\"timestamp\":200}],\"rect_id\":3}," - "{\"events\":[" - "{\"end_time\":110,\"frame_id\":3,\"timestamp\":100}],\"rect_id\":4}" - "]}", - MainFrameToString(tracker->GroupMainFrameCountsByRectId())); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/debug/frame_viewer_instrumentation.cc b/chromium/cc/debug/frame_viewer_instrumentation.cc index 5181aa89c91..d34907a8746 100644 --- a/chromium/cc/debug/frame_viewer_instrumentation.cc +++ b/chromium/cc/debug/frame_viewer_instrumentation.cc @@ -26,12 +26,12 @@ const char kSourceFrameNumber[] = "sourceFrameNumber"; const char kAnalyzeTask[] = "AnalyzeTask"; const char kRasterTask[] = "RasterTask"; -scoped_ptr<base::trace_event::ConvertableToTraceFormat> TileDataAsValue( +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TileDataAsValue( const void* tile_id, TileResolution tile_resolution, int source_frame_number, int layer_id) { - scoped_ptr<base::trace_event::TracedValue> res( + std::unique_ptr<base::trace_event::TracedValue> res( new base::trace_event::TracedValue()); TracedValue::SetIDRef(tile_id, res.get(), kTileId); res->SetString(kTileResolution, TileResolutionToString(tile_resolution)); diff --git a/chromium/cc/debug/invalidation_benchmark.cc b/chromium/cc/debug/invalidation_benchmark.cc index 5a5436ca588..681e29ef7cc 100644 --- a/chromium/cc/debug/invalidation_benchmark.cc +++ b/chromium/cc/debug/invalidation_benchmark.cc @@ -27,7 +27,7 @@ const char* kDefaultInvalidationMode = "viewport"; } // namespace InvalidationBenchmark::InvalidationBenchmark( - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback) : MicroBenchmark(callback), seed_(0) { base::DictionaryValue* settings = nullptr; @@ -65,8 +65,7 @@ InvalidationBenchmark::~InvalidationBenchmark() { void InvalidationBenchmark::DidUpdateLayers(LayerTreeHost* host) { LayerTreeHostCommon::CallFunctionForEveryLayer( - host, [this](Layer* layer) { layer->RunMicroBenchmark(this); }, - CallFunctionLayerType::ALL_LAYERS); + host, [this](Layer* layer) { layer->RunMicroBenchmark(this); }); } void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) { @@ -112,7 +111,7 @@ void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) { } } -bool InvalidationBenchmark::ProcessMessage(scoped_ptr<base::Value> value) { +bool InvalidationBenchmark::ProcessMessage(std::unique_ptr<base::Value> value) { base::DictionaryValue* message = nullptr; value->GetAsDictionary(&message); if (!message) diff --git a/chromium/cc/debug/invalidation_benchmark.h b/chromium/cc/debug/invalidation_benchmark.h index 9cd264376b8..668a7c948e9 100644 --- a/chromium/cc/debug/invalidation_benchmark.h +++ b/chromium/cc/debug/invalidation_benchmark.h @@ -21,14 +21,14 @@ class Layer; // measurement. class CC_EXPORT InvalidationBenchmark : public MicroBenchmark { public: - explicit InvalidationBenchmark(scoped_ptr<base::Value> value, + explicit InvalidationBenchmark(std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback); ~InvalidationBenchmark() override; // Implements MicroBenchmark interface. void DidUpdateLayers(LayerTreeHost* host) override; void RunOnLayer(PictureLayer* layer) override; - bool ProcessMessage(scoped_ptr<base::Value> value) override; + bool ProcessMessage(std::unique_ptr<base::Value> value) override; private: enum Mode { FIXED_SIZE, LAYER, VIEWPORT, RANDOM }; diff --git a/chromium/cc/debug/micro_benchmark.cc b/chromium/cc/debug/micro_benchmark.cc index 8077718c861..72d3c7dea31 100644 --- a/chromium/cc/debug/micro_benchmark.cc +++ b/chromium/cc/debug/micro_benchmark.cc @@ -4,9 +4,11 @@ #include "cc/debug/micro_benchmark.h" +#include <memory> + #include "base/callback.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/values.h" #include "cc/debug/micro_benchmark_impl.h" @@ -28,7 +30,7 @@ bool MicroBenchmark::IsDone() const { void MicroBenchmark::DidUpdateLayers(LayerTreeHost* host) {} -void MicroBenchmark::NotifyDone(scoped_ptr<base::Value> result) { +void MicroBenchmark::NotifyDone(std::unique_ptr<base::Value> result) { callback_.Run(std::move(result)); is_done_ = true; } @@ -37,7 +39,7 @@ void MicroBenchmark::RunOnLayer(Layer* layer) {} void MicroBenchmark::RunOnLayer(PictureLayer* layer) {} -bool MicroBenchmark::ProcessMessage(scoped_ptr<base::Value> value) { +bool MicroBenchmark::ProcessMessage(std::unique_ptr<base::Value> value) { return false; } @@ -45,16 +47,16 @@ bool MicroBenchmark::ProcessedForBenchmarkImpl() const { return processed_for_benchmark_impl_; } -scoped_ptr<MicroBenchmarkImpl> MicroBenchmark::GetBenchmarkImpl( +std::unique_ptr<MicroBenchmarkImpl> MicroBenchmark::GetBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner) { DCHECK(!processed_for_benchmark_impl_); processed_for_benchmark_impl_ = true; return CreateBenchmarkImpl(origin_task_runner); } -scoped_ptr<MicroBenchmarkImpl> MicroBenchmark::CreateBenchmarkImpl( +std::unique_ptr<MicroBenchmarkImpl> MicroBenchmark::CreateBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner) { - return make_scoped_ptr<MicroBenchmarkImpl>(nullptr); + return base::WrapUnique<MicroBenchmarkImpl>(nullptr); } } // namespace cc diff --git a/chromium/cc/debug/micro_benchmark.h b/chromium/cc/debug/micro_benchmark.h index c5bbd883164..d2247346453 100644 --- a/chromium/cc/debug/micro_benchmark.h +++ b/chromium/cc/debug/micro_benchmark.h @@ -5,8 +5,9 @@ #ifndef CC_DEBUG_MICRO_BENCHMARK_H_ #define CC_DEBUG_MICRO_BENCHMARK_H_ +#include <memory> + #include "base/callback.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" namespace base { @@ -22,7 +23,7 @@ class PictureLayer; class MicroBenchmarkImpl; class CC_EXPORT MicroBenchmark { public: - typedef base::Callback<void(scoped_ptr<base::Value>)> DoneCallback; + typedef base::Callback<void(std::unique_ptr<base::Value>)> DoneCallback; explicit MicroBenchmark(const DoneCallback& callback); virtual ~MicroBenchmark(); @@ -35,16 +36,16 @@ class CC_EXPORT MicroBenchmark { virtual void RunOnLayer(Layer* layer); virtual void RunOnLayer(PictureLayer* layer); - virtual bool ProcessMessage(scoped_ptr<base::Value> value); + virtual bool ProcessMessage(std::unique_ptr<base::Value> value); bool ProcessedForBenchmarkImpl() const; - scoped_ptr<MicroBenchmarkImpl> GetBenchmarkImpl( + std::unique_ptr<MicroBenchmarkImpl> GetBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner); protected: - void NotifyDone(scoped_ptr<base::Value> result); + void NotifyDone(std::unique_ptr<base::Value> result); - virtual scoped_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl( + virtual std::unique_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner); private: diff --git a/chromium/cc/debug/micro_benchmark_controller.cc b/chromium/cc/debug/micro_benchmark_controller.cc index 78fa5616656..0707563612d 100644 --- a/chromium/cc/debug/micro_benchmark_controller.cc +++ b/chromium/cc/debug/micro_benchmark_controller.cc @@ -8,7 +8,8 @@ #include <string> #include "base/callback.h" -#include "base/thread_task_runner_handle.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "cc/debug/invalidation_benchmark.h" #include "cc/debug/rasterize_and_record_benchmark.h" @@ -22,18 +23,18 @@ int MicroBenchmarkController::next_id_ = 1; namespace { -scoped_ptr<MicroBenchmark> CreateBenchmark( +std::unique_ptr<MicroBenchmark> CreateBenchmark( const std::string& name, - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback) { if (name == "invalidation_benchmark") { - return make_scoped_ptr( + return base::WrapUnique( new InvalidationBenchmark(std::move(value), callback)); } else if (name == "rasterize_and_record_benchmark") { - return make_scoped_ptr( + return base::WrapUnique( new RasterizeAndRecordBenchmark(std::move(value), callback)); } else if (name == "unittest_only_benchmark") { - return make_scoped_ptr( + return base::WrapUnique( new UnittestOnlyBenchmark(std::move(value), callback)); } return nullptr; @@ -53,9 +54,9 @@ MicroBenchmarkController::~MicroBenchmarkController() {} int MicroBenchmarkController::ScheduleRun( const std::string& micro_benchmark_name, - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback) { - scoped_ptr<MicroBenchmark> benchmark = + std::unique_ptr<MicroBenchmark> benchmark = CreateBenchmark(micro_benchmark_name, std::move(value), callback); if (benchmark.get()) { int id = GetNextIdAndIncrement(); @@ -76,11 +77,12 @@ int MicroBenchmarkController::GetNextIdAndIncrement() { } bool MicroBenchmarkController::SendMessage(int id, - scoped_ptr<base::Value> value) { - auto it = std::find_if(benchmarks_.begin(), benchmarks_.end(), - [id](const scoped_ptr<MicroBenchmark>& benchmark) { - return benchmark->id() == id; - }); + std::unique_ptr<base::Value> value) { + auto it = + std::find_if(benchmarks_.begin(), benchmarks_.end(), + [id](const std::unique_ptr<MicroBenchmark>& benchmark) { + return benchmark->id() == id; + }); if (it == benchmarks_.end()) return false; return (*it)->ProcessMessage(std::move(value)); @@ -89,7 +91,7 @@ bool MicroBenchmarkController::SendMessage(int id, void MicroBenchmarkController::ScheduleImplBenchmarks( LayerTreeHostImpl* host_impl) { for (const auto& benchmark : benchmarks_) { - scoped_ptr<MicroBenchmarkImpl> benchmark_impl; + std::unique_ptr<MicroBenchmarkImpl> benchmark_impl; if (!benchmark->ProcessedForBenchmarkImpl()) { benchmark_impl = benchmark->GetBenchmarkImpl(main_controller_task_runner_); @@ -112,7 +114,7 @@ void MicroBenchmarkController::DidUpdateLayers() { void MicroBenchmarkController::CleanUpFinishedBenchmarks() { benchmarks_.erase( std::remove_if(benchmarks_.begin(), benchmarks_.end(), - [](const scoped_ptr<MicroBenchmark>& benchmark) { + [](const std::unique_ptr<MicroBenchmark>& benchmark) { return benchmark->IsDone(); }), benchmarks_.end()); diff --git a/chromium/cc/debug/micro_benchmark_controller.h b/chromium/cc/debug/micro_benchmark_controller.h index 95000cbaafc..88ccc840ab5 100644 --- a/chromium/cc/debug/micro_benchmark_controller.h +++ b/chromium/cc/debug/micro_benchmark_controller.h @@ -30,10 +30,10 @@ class CC_EXPORT MicroBenchmarkController { // Returns the id of the benchmark on success, 0 otherwise. int ScheduleRun(const std::string& micro_benchmark_name, - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback); // Returns true if the message was successfully delivered and handled. - bool SendMessage(int id, scoped_ptr<base::Value> value); + bool SendMessage(int id, std::unique_ptr<base::Value> value); void ScheduleImplBenchmarks(LayerTreeHostImpl* host_impl); @@ -42,7 +42,7 @@ class CC_EXPORT MicroBenchmarkController { int GetNextIdAndIncrement(); LayerTreeHost* host_; - std::vector<scoped_ptr<MicroBenchmark>> benchmarks_; + std::vector<std::unique_ptr<MicroBenchmark>> benchmarks_; static int next_id_; scoped_refptr<base::SingleThreadTaskRunner> main_controller_task_runner_; diff --git a/chromium/cc/debug/micro_benchmark_controller_impl.cc b/chromium/cc/debug/micro_benchmark_controller_impl.cc index 8d917d71726..7c46aedab8f 100644 --- a/chromium/cc/debug/micro_benchmark_controller_impl.cc +++ b/chromium/cc/debug/micro_benchmark_controller_impl.cc @@ -21,7 +21,7 @@ MicroBenchmarkControllerImpl::MicroBenchmarkControllerImpl( MicroBenchmarkControllerImpl::~MicroBenchmarkControllerImpl() {} void MicroBenchmarkControllerImpl::ScheduleRun( - scoped_ptr<MicroBenchmarkImpl> benchmark) { + std::unique_ptr<MicroBenchmarkImpl> benchmark) { benchmarks_.push_back(std::move(benchmark)); } @@ -37,7 +37,7 @@ void MicroBenchmarkControllerImpl::DidCompleteCommit() { void MicroBenchmarkControllerImpl::CleanUpFinishedBenchmarks() { benchmarks_.erase( std::remove_if(benchmarks_.begin(), benchmarks_.end(), - [](const scoped_ptr<MicroBenchmarkImpl>& benchmark) { + [](const std::unique_ptr<MicroBenchmarkImpl>& benchmark) { return benchmark->IsDone(); }), benchmarks_.end()); diff --git a/chromium/cc/debug/micro_benchmark_controller_impl.h b/chromium/cc/debug/micro_benchmark_controller_impl.h index bcb4aa08305..67c8005059a 100644 --- a/chromium/cc/debug/micro_benchmark_controller_impl.h +++ b/chromium/cc/debug/micro_benchmark_controller_impl.h @@ -21,13 +21,13 @@ class CC_EXPORT MicroBenchmarkControllerImpl { void DidCompleteCommit(); - void ScheduleRun(scoped_ptr<MicroBenchmarkImpl> benchmark); + void ScheduleRun(std::unique_ptr<MicroBenchmarkImpl> benchmark); private: void CleanUpFinishedBenchmarks(); LayerTreeHostImpl* host_; - std::vector<scoped_ptr<MicroBenchmarkImpl>> benchmarks_; + std::vector<std::unique_ptr<MicroBenchmarkImpl>> benchmarks_; DISALLOW_COPY_AND_ASSIGN(MicroBenchmarkControllerImpl); }; diff --git a/chromium/cc/debug/micro_benchmark_controller_unittest.cc b/chromium/cc/debug/micro_benchmark_controller_unittest.cc index 5e4aa403978..4baeb8642e7 100644 --- a/chromium/cc/debug/micro_benchmark_controller_unittest.cc +++ b/chromium/cc/debug/micro_benchmark_controller_unittest.cc @@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/debug/micro_benchmark_controller.h" + +#include <memory> + #include "base/callback.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "cc/debug/micro_benchmark.h" -#include "cc/debug/micro_benchmark_controller.h" #include "cc/layers/layer.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host.h" @@ -24,8 +27,8 @@ class MicroBenchmarkControllerTest : public testing::Test { void SetUp() override { impl_task_runner_provider_ = - make_scoped_ptr(new FakeImplTaskRunnerProvider); - layer_tree_host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl( + base::WrapUnique(new FakeImplTaskRunnerProvider); + layer_tree_host_impl_ = base::WrapUnique(new FakeLayerTreeHostImpl( impl_task_runner_provider_.get(), &shared_bitmap_manager_, &task_graph_runner_)); @@ -34,7 +37,7 @@ class MicroBenchmarkControllerTest : public testing::Test { layer_tree_host_->SetRootLayer(Layer::Create()); layer_tree_host_->InitializeForTesting( TaskRunnerProvider::Create(nullptr, nullptr), - scoped_ptr<Proxy>(new FakeProxy), nullptr); + std::unique_ptr<Proxy>(new FakeProxy), nullptr); } void TearDown() override { @@ -46,15 +49,14 @@ 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<FakeLayerTreeHostImpl> layer_tree_host_impl_; - scoped_ptr<FakeImplTaskRunnerProvider> impl_task_runner_provider_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHostImpl> layer_tree_host_impl_; + std::unique_ptr<FakeImplTaskRunnerProvider> impl_task_runner_provider_; }; -void Noop(scoped_ptr<base::Value> value) { -} +void Noop(std::unique_ptr<base::Value> value) {} -void IncrementCallCount(int* count, scoped_ptr<base::Value> value) { +void IncrementCallCount(int* count, std::unique_ptr<base::Value> value) { ++(*count); } @@ -124,7 +126,7 @@ TEST_F(MicroBenchmarkControllerTest, MultipleBenchmarkRan) { TEST_F(MicroBenchmarkControllerTest, BenchmarkImplRan) { int run_count = 0; - scoped_ptr<base::DictionaryValue> settings(new base::DictionaryValue); + std::unique_ptr<base::DictionaryValue> settings(new base::DictionaryValue); settings->SetBoolean("run_benchmark_impl", true); // Schedule a main thread benchmark. @@ -148,7 +150,7 @@ TEST_F(MicroBenchmarkControllerTest, BenchmarkImplRan) { TEST_F(MicroBenchmarkControllerTest, SendMessage) { // Send valid message to invalid benchmark (id = 0) - scoped_ptr<base::DictionaryValue> message(new base::DictionaryValue); + std::unique_ptr<base::DictionaryValue> message(new base::DictionaryValue); message->SetBoolean("can_handle", true); bool message_handled = layer_tree_host_->SendMessageToMicroBenchmark(0, std::move(message)); @@ -163,14 +165,14 @@ TEST_F(MicroBenchmarkControllerTest, SendMessage) { EXPECT_GT(id, 0); // Send valid message to valid benchmark - message = make_scoped_ptr(new base::DictionaryValue); + message = base::WrapUnique(new base::DictionaryValue); message->SetBoolean("can_handle", true); message_handled = layer_tree_host_->SendMessageToMicroBenchmark(id, std::move(message)); EXPECT_TRUE(message_handled); // Send invalid message to valid benchmark - message = make_scoped_ptr(new base::DictionaryValue); + message = base::WrapUnique(new base::DictionaryValue); message->SetBoolean("can_handle", false); message_handled = layer_tree_host_->SendMessageToMicroBenchmark(id, std::move(message)); diff --git a/chromium/cc/debug/micro_benchmark_impl.cc b/chromium/cc/debug/micro_benchmark_impl.cc index b7d59ae360b..8f818fd16ea 100644 --- a/chromium/cc/debug/micro_benchmark_impl.cc +++ b/chromium/cc/debug/micro_benchmark_impl.cc @@ -4,10 +4,11 @@ #include "cc/debug/micro_benchmark_impl.h" +#include <memory> + #include "base/bind.h" #include "base/callback.h" #include "base/location.h" -#include "base/memory/scoped_ptr.h" #include "base/single_thread_task_runner.h" #include "base/values.h" @@ -16,7 +17,7 @@ namespace cc { namespace { void RunCallback(const MicroBenchmarkImpl::DoneCallback& callback, - scoped_ptr<base::Value> result) { + std::unique_ptr<base::Value> result) { callback.Run(std::move(result)); } @@ -38,7 +39,7 @@ bool MicroBenchmarkImpl::IsDone() const { void MicroBenchmarkImpl::DidCompleteCommit(LayerTreeHostImpl* host) {} -void MicroBenchmarkImpl::NotifyDone(scoped_ptr<base::Value> result) { +void MicroBenchmarkImpl::NotifyDone(std::unique_ptr<base::Value> result) { origin_task_runner_->PostTask( FROM_HERE, base::Bind(RunCallback, callback_, base::Passed(&result))); is_done_ = true; diff --git a/chromium/cc/debug/micro_benchmark_impl.h b/chromium/cc/debug/micro_benchmark_impl.h index ed968a39fbc..457eb4dbf4d 100644 --- a/chromium/cc/debug/micro_benchmark_impl.h +++ b/chromium/cc/debug/micro_benchmark_impl.h @@ -5,8 +5,9 @@ #ifndef CC_DEBUG_MICRO_BENCHMARK_IMPL_H_ #define CC_DEBUG_MICRO_BENCHMARK_IMPL_H_ +#include <memory> + #include "base/callback.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" namespace base { @@ -21,7 +22,7 @@ class LayerImpl; class PictureLayerImpl; class CC_EXPORT MicroBenchmarkImpl { public: - typedef base::Callback<void(scoped_ptr<base::Value>)> DoneCallback; + typedef base::Callback<void(std::unique_ptr<base::Value>)> DoneCallback; explicit MicroBenchmarkImpl( const DoneCallback& callback, @@ -35,7 +36,7 @@ class CC_EXPORT MicroBenchmarkImpl { virtual void RunOnLayer(PictureLayerImpl* layer); protected: - void NotifyDone(scoped_ptr<base::Value> result); + void NotifyDone(std::unique_ptr<base::Value> result); private: DoneCallback callback_; diff --git a/chromium/cc/debug/picture_debug_util.cc b/chromium/cc/debug/picture_debug_util.cc index dda4dce74a5..aef9ba8ae08 100644 --- a/chromium/cc/debug/picture_debug_util.cc +++ b/chromium/cc/debug/picture_debug_util.cc @@ -7,11 +7,11 @@ #include <stddef.h> #include <limits> +#include <memory> #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" #include "third_party/skia/include/core/SkImageInfo.h" @@ -71,7 +71,7 @@ void PictureDebugUtil::SerializeAsBase64(const SkPicture* picture, picture->serialize(&stream, &serializer); size_t serialized_size = stream.bytesWritten(); - scoped_ptr<char[]> serialized_picture(new char[serialized_size]); + std::unique_ptr<char[]> serialized_picture(new char[serialized_size]); stream.copyTo(serialized_picture.get()); base::Base64Encode( base::StringPiece(serialized_picture.get(), serialized_size), output); diff --git a/chromium/cc/debug/rasterize_and_record_benchmark.cc b/chromium/cc/debug/rasterize_and_record_benchmark.cc index 3c7058f0f09..5babc0edca6 100644 --- a/chromium/cc/debug/rasterize_and_record_benchmark.cc +++ b/chromium/cc/debug/rasterize_and_record_benchmark.cc @@ -10,6 +10,7 @@ #include <limits> #include <string> +#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "cc/debug/lap_timer.h" @@ -47,7 +48,7 @@ const char* kModeSuffixes[RecordingSource::RECORDING_MODE_COUNT] = { } // namespace RasterizeAndRecordBenchmark::RasterizeAndRecordBenchmark( - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback) : MicroBenchmark(callback), record_repeat_count_(kDefaultRecordRepeatCount), @@ -71,11 +72,10 @@ RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() { void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) { host_ = host; LayerTreeHostCommon::CallFunctionForEveryLayer( - host, [this](Layer* layer) { layer->RunMicroBenchmark(this); }, - CallFunctionLayerType::ALL_LAYERS); + host, [this](Layer* layer) { layer->RunMicroBenchmark(this); }); DCHECK(!results_.get()); - results_ = make_scoped_ptr(new base::DictionaryValue); + results_ = base::WrapUnique(new base::DictionaryValue); results_->SetInteger("pixels_recorded", record_results_.pixels_recorded); results_->SetInteger("picture_memory_usage", static_cast<int>(record_results_.bytes_used)); @@ -89,7 +89,7 @@ void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) { } void RasterizeAndRecordBenchmark::RecordRasterResults( - scoped_ptr<base::Value> results_value) { + std::unique_ptr<base::Value> results_value) { DCHECK(main_thread_benchmark_done_); base::DictionaryValue* results = nullptr; @@ -101,9 +101,10 @@ void RasterizeAndRecordBenchmark::RecordRasterResults( NotifyDone(std::move(results_)); } -scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl( +std::unique_ptr<MicroBenchmarkImpl> +RasterizeAndRecordBenchmark::CreateBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner) { - return make_scoped_ptr(new RasterizeAndRecordBenchmarkImpl( + return base::WrapUnique(new RasterizeAndRecordBenchmarkImpl( origin_task_runner, settings_.get(), base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults, weak_ptr_factory_.GetWeakPtr()))); diff --git a/chromium/cc/debug/rasterize_and_record_benchmark.h b/chromium/cc/debug/rasterize_and_record_benchmark.h index a049d38afd8..f68b566aa79 100644 --- a/chromium/cc/debug/rasterize_and_record_benchmark.h +++ b/chromium/cc/debug/rasterize_and_record_benchmark.h @@ -29,7 +29,7 @@ class Layer; class RasterizeAndRecordBenchmark : public MicroBenchmark { public: explicit RasterizeAndRecordBenchmark( - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback); ~RasterizeAndRecordBenchmark() override; @@ -37,11 +37,11 @@ class RasterizeAndRecordBenchmark : public MicroBenchmark { void DidUpdateLayers(LayerTreeHost* host) override; void RunOnLayer(PictureLayer* layer) override; - scoped_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl( + std::unique_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner) override; private: - void RecordRasterResults(scoped_ptr<base::Value> results); + void RecordRasterResults(std::unique_ptr<base::Value> results); struct RecordResults { RecordResults(); @@ -54,8 +54,8 @@ class RasterizeAndRecordBenchmark : public MicroBenchmark { RecordResults record_results_; int record_repeat_count_; - scoped_ptr<base::Value> settings_; - scoped_ptr<base::DictionaryValue> results_; + std::unique_ptr<base::Value> settings_; + std::unique_ptr<base::DictionaryValue> results_; // The following is used in DCHECKs. bool main_thread_benchmark_done_; diff --git a/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc b/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc index d4b4c110eb8..523051116b9 100644 --- a/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc +++ b/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc @@ -13,7 +13,7 @@ #include "cc/debug/lap_timer.h" #include "cc/layers/layer_impl.h" #include "cc/layers/picture_layer_impl.h" -#include "cc/raster/tile_task_worker_pool.h" +#include "cc/raster/raster_buffer_provider.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" @@ -126,14 +126,12 @@ RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {} void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit( LayerTreeHostImpl* host) { LayerTreeHostCommon::CallFunctionForEveryLayer( - host->active_tree(), - [this](LayerImpl* layer) { + host->active_tree(), [this](LayerImpl* layer) { rasterize_results_.total_layers++; layer->RunMicroBenchmark(this); - }, - CallFunctionLayerType::ALL_LAYERS); + }); - scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); result->SetDouble("rasterize_time_ms", rasterize_results_.total_best_time.InMillisecondsF()); result->SetDouble("total_pictures_in_pile_size", @@ -172,10 +170,11 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) { // it takes to rasterize content. As such, the actual settings used here don't // really matter. const LayerTreeSettings& settings = layer->layer_tree_impl()->settings(); - scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( - layer->GetTree(), &client, settings.tiling_interest_area_padding, - settings.skewport_target_time_in_seconds, - settings.skewport_extrapolation_limit_in_content_pixels); + std::unique_ptr<PictureLayerTilingSet> tiling_set = + PictureLayerTilingSet::Create( + layer->GetTree(), &client, settings.tiling_interest_area_padding, + settings.skewport_target_time_in_seconds, + settings.skewport_extrapolation_limit_in_screen_pixels); PictureLayerTiling* tiling = tiling_set->AddTiling(1.f, layer->GetRasterSource()); diff --git a/chromium/cc/debug/rendering_stats.cc b/chromium/cc/debug/rendering_stats.cc index f0d56aab4ad..bf31cc6c34d 100644 --- a/chromium/cc/debug/rendering_stats.cc +++ b/chromium/cc/debug/rendering_stats.cc @@ -50,9 +50,9 @@ RenderingStats::RenderingStats(const RenderingStats& other) = default; RenderingStats::~RenderingStats() { } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> RenderingStats::AsTraceableData() const { - scoped_ptr<base::trace_event::TracedValue> record_data( + std::unique_ptr<base::trace_event::TracedValue> record_data( new base::trace_event::TracedValue()); record_data->SetInteger("frame_count", frame_count); record_data->SetInteger("visible_content_area", visible_content_area); diff --git a/chromium/cc/debug/rendering_stats.h b/chromium/cc/debug/rendering_stats.h index a99d28d964a..f12d1235982 100644 --- a/chromium/cc/debug/rendering_stats.h +++ b/chromium/cc/debug/rendering_stats.h @@ -7,9 +7,9 @@ #include <stdint.h> +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "base/trace_event/trace_event_argument.h" #include "base/values.h" @@ -59,7 +59,7 @@ struct CC_EXPORT RenderingStats { TimeDeltaList commit_to_activate_duration; TimeDeltaList commit_to_activate_duration_estimate; - scoped_ptr<base::trace_event::ConvertableToTraceFormat> AsTraceableData() + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsTraceableData() const; void Add(const RenderingStats& other); }; diff --git a/chromium/cc/debug/rendering_stats_instrumentation.cc b/chromium/cc/debug/rendering_stats_instrumentation.cc index de7057e74f6..69fbd50240b 100644 --- a/chromium/cc/debug/rendering_stats_instrumentation.cc +++ b/chromium/cc/debug/rendering_stats_instrumentation.cc @@ -2,16 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/debug/rendering_stats_instrumentation.h" + #include <stdint.h> -#include "cc/debug/rendering_stats_instrumentation.h" +#include "base/memory/ptr_util.h" namespace cc { // static -scoped_ptr<RenderingStatsInstrumentation> - RenderingStatsInstrumentation::Create() { - return make_scoped_ptr(new RenderingStatsInstrumentation()); +std::unique_ptr<RenderingStatsInstrumentation> +RenderingStatsInstrumentation::Create() { + return base::WrapUnique(new RenderingStatsInstrumentation()); } RenderingStatsInstrumentation::RenderingStatsInstrumentation() diff --git a/chromium/cc/debug/rendering_stats_instrumentation.h b/chromium/cc/debug/rendering_stats_instrumentation.h index 9197fb6ac13..566a1218efe 100644 --- a/chromium/cc/debug/rendering_stats_instrumentation.h +++ b/chromium/cc/debug/rendering_stats_instrumentation.h @@ -7,8 +7,9 @@ #include <stdint.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" #include "cc/debug/rendering_stats.h" @@ -18,7 +19,7 @@ namespace cc { // recording of rendering stats into a private RenderingStats instance. class CC_EXPORT RenderingStatsInstrumentation { public: - static scoped_ptr<RenderingStatsInstrumentation> Create(); + static std::unique_ptr<RenderingStatsInstrumentation> Create(); virtual ~RenderingStatsInstrumentation(); // Return copy of current impl thread rendering stats. diff --git a/chromium/cc/debug/rendering_stats_unittest.cc b/chromium/cc/debug/rendering_stats_unittest.cc index b0695be79ba..2ba0d2bee8c 100644 --- a/chromium/cc/debug/rendering_stats_unittest.cc +++ b/chromium/cc/debug/rendering_stats_unittest.cc @@ -13,7 +13,7 @@ namespace cc { namespace { static std::string ToString(const RenderingStats::TimeDeltaList& list) { - scoped_ptr<base::trace_event::TracedValue> value( + std::unique_ptr<base::trace_event::TracedValue> value( new base::trace_event::TracedValue()); list.AddToTracedValue("list_value", value.get()); return value->ToString(); diff --git a/chromium/cc/debug/traced_display_item_list.cc b/chromium/cc/debug/traced_display_item_list.cc index 7da87b97fe9..b02446e9cd4 100644 --- a/chromium/cc/debug/traced_display_item_list.cc +++ b/chromium/cc/debug/traced_display_item_list.cc @@ -19,7 +19,7 @@ TracedDisplayItemList::~TracedDisplayItemList() { } void TracedDisplayItemList::AppendAsTraceFormat(std::string* out) const { - scoped_ptr<base::trace_event::ConvertableToTraceFormat> convertable( + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> convertable( display_item_list_->AsValue(include_items_)); convertable->AppendAsTraceFormat(out); } diff --git a/chromium/cc/debug/traced_display_item_list.h b/chromium/cc/debug/traced_display_item_list.h index 71cf66498be..50733485e6f 100644 --- a/chromium/cc/debug/traced_display_item_list.h +++ b/chromium/cc/debug/traced_display_item_list.h @@ -5,11 +5,11 @@ #ifndef CC_DEBUG_TRACED_DISPLAY_ITEM_LIST_H_ #define CC_DEBUG_TRACED_DISPLAY_ITEM_LIST_H_ +#include <memory> #include <string> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/trace_event/trace_event.h" #include "cc/debug/traced_value.h" @@ -20,10 +20,10 @@ class DisplayItemList; class TracedDisplayItemList : public base::trace_event::ConvertableToTraceFormat { public: - static scoped_ptr<ConvertableToTraceFormat> AsTraceableDisplayItemList( + static std::unique_ptr<ConvertableToTraceFormat> AsTraceableDisplayItemList( scoped_refptr<const DisplayItemList> list, bool include_items) { - return scoped_ptr<ConvertableToTraceFormat>( + return std::unique_ptr<ConvertableToTraceFormat>( new TracedDisplayItemList(list, include_items)); } void AppendAsTraceFormat(std::string* out) const override; diff --git a/chromium/cc/debug/unittest_only_benchmark.cc b/chromium/cc/debug/unittest_only_benchmark.cc index 657c0f618d5..251507bafe7 100644 --- a/chromium/cc/debug/unittest_only_benchmark.cc +++ b/chromium/cc/debug/unittest_only_benchmark.cc @@ -5,13 +5,14 @@ #include "cc/debug/unittest_only_benchmark.h" #include "base/bind.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/values.h" #include "cc/debug/unittest_only_benchmark_impl.h" namespace cc { -UnittestOnlyBenchmark::UnittestOnlyBenchmark(scoped_ptr<base::Value> value, +UnittestOnlyBenchmark::UnittestOnlyBenchmark(std::unique_ptr<base::Value> value, const DoneCallback& callback) : MicroBenchmark(callback), create_impl_benchmark_(false), @@ -36,7 +37,7 @@ void UnittestOnlyBenchmark::DidUpdateLayers(LayerTreeHost* host) { NotifyDone(nullptr); } -bool UnittestOnlyBenchmark::ProcessMessage(scoped_ptr<base::Value> value) { +bool UnittestOnlyBenchmark::ProcessMessage(std::unique_ptr<base::Value> value) { base::DictionaryValue* message = nullptr; value->GetAsDictionary(&message); bool can_handle; @@ -48,16 +49,17 @@ bool UnittestOnlyBenchmark::ProcessMessage(scoped_ptr<base::Value> value) { return false; } -void UnittestOnlyBenchmark::RecordImplResults(scoped_ptr<base::Value> results) { +void UnittestOnlyBenchmark::RecordImplResults( + std::unique_ptr<base::Value> results) { NotifyDone(std::move(results)); } -scoped_ptr<MicroBenchmarkImpl> UnittestOnlyBenchmark::CreateBenchmarkImpl( +std::unique_ptr<MicroBenchmarkImpl> UnittestOnlyBenchmark::CreateBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner) { if (!create_impl_benchmark_) - return make_scoped_ptr<MicroBenchmarkImpl>(nullptr); + return base::WrapUnique<MicroBenchmarkImpl>(nullptr); - return make_scoped_ptr(new UnittestOnlyBenchmarkImpl( + return base::WrapUnique(new UnittestOnlyBenchmarkImpl( origin_task_runner, nullptr, base::Bind(&UnittestOnlyBenchmark::RecordImplResults, weak_ptr_factory_.GetWeakPtr()))); diff --git a/chromium/cc/debug/unittest_only_benchmark.h b/chromium/cc/debug/unittest_only_benchmark.h index 4e74ec7912c..5a00c15e6a8 100644 --- a/chromium/cc/debug/unittest_only_benchmark.h +++ b/chromium/cc/debug/unittest_only_benchmark.h @@ -16,19 +16,19 @@ namespace cc { class CC_EXPORT UnittestOnlyBenchmark : public MicroBenchmark { public: - UnittestOnlyBenchmark(scoped_ptr<base::Value> value, + UnittestOnlyBenchmark(std::unique_ptr<base::Value> value, const DoneCallback& callback); ~UnittestOnlyBenchmark() override; void DidUpdateLayers(LayerTreeHost* host) override; - bool ProcessMessage(scoped_ptr<base::Value> value) override; + bool ProcessMessage(std::unique_ptr<base::Value> value) override; protected: - scoped_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl( + std::unique_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl( scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner) override; private: - void RecordImplResults(scoped_ptr<base::Value> results); + void RecordImplResults(std::unique_ptr<base::Value> results); bool create_impl_benchmark_; base::WeakPtrFactory<UnittestOnlyBenchmark> weak_ptr_factory_; diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h index 90870d9ba53..30ac88d4256 100644 --- a/chromium/cc/input/input_handler.h +++ b/chromium/cc/input/input_handler.h @@ -5,8 +5,9 @@ #ifndef CC_INPUT_INPUT_HANDLER_H_ #define CC_INPUT_INPUT_HANDLER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/input/event_listener_properties.h" @@ -99,12 +100,9 @@ class CC_EXPORT InputHandler { uint32_t main_thread_scrolling_reasons; }; - // TODO(ymalik): Remove ANIMATED_WHEEL once it is no longer special cased. - // see crbug.com/575019. enum ScrollInputType { TOUCHSCREEN, WHEEL, - ANIMATED_WHEEL, NON_BUBBLING_GESTURE }; @@ -196,8 +194,8 @@ class CC_EXPORT InputHandler { // LatencyInfoSwapPromiseMonitor, if SetNeedsRedraw() or SetNeedsRedrawRect() // is called on LayerTreeHostImpl, the original latency info will be turned // into a LatencyInfoSwapPromise. - virtual scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( - ui::LatencyInfo* latency) = 0; + virtual std::unique_ptr<SwapPromiseMonitor> + CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo* latency) = 0; virtual ScrollElasticityHelper* CreateScrollElasticityHelper() = 0; diff --git a/chromium/cc/input/main_thread_scrolling_reason.h b/chromium/cc/input/main_thread_scrolling_reason.h index 1f384ebfcee..ea94631c814 100644 --- a/chromium/cc/input/main_thread_scrolling_reason.h +++ b/chromium/cc/input/main_thread_scrolling_reason.h @@ -19,6 +19,7 @@ struct MainThreadScrollingReason { enum : uint32_t { kScrollbarScrolling = 1 << 3 }; enum : uint32_t { kPageOverlay = 1 << 4 }; enum : uint32_t { kAnimatingScrollOnMainThread = 1 << 13 }; + enum : uint32_t { kHasStickyPositionObjects = 1 << 14 }; // Transient scrolling reasons. These are computed for each scroll begin. enum : uint32_t { kNonFastScrollableRegion = 1 << 5 }; @@ -31,7 +32,7 @@ struct MainThreadScrollingReason { enum : uint32_t { kPageBasedScrolling = 1 << 12 }; // The number of flags in this struct (excluding itself). - enum : uint32_t { kMainThreadScrollingReasonCount = 15 }; + enum : uint32_t { kMainThreadScrollingReasonCount = 16 }; // Returns true if the given MainThreadScrollingReason can be set by the main // thread. @@ -39,7 +40,8 @@ struct MainThreadScrollingReason { uint32_t reasons_set_by_main_thread = kNotScrollingOnMain | kHasBackgroundAttachmentFixedObjects | kHasNonLayerViewportConstrainedObjects | kThreadedScrollingDisabled | - kScrollbarScrolling | kPageOverlay | kAnimatingScrollOnMainThread; + kScrollbarScrolling | kPageOverlay | kAnimatingScrollOnMainThread | + kHasStickyPositionObjects; return (reasons & reasons_set_by_main_thread) == reasons; } diff --git a/chromium/cc/input/page_scale_animation.cc b/chromium/cc/input/page_scale_animation.cc index d66f60a5301..96ebd9c1d20 100644 --- a/chromium/cc/input/page_scale_animation.cc +++ b/chromium/cc/input/page_scale_animation.cc @@ -7,6 +7,7 @@ #include <math.h> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "cc/animation/timing_function.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/rect_f.h" @@ -43,13 +44,13 @@ namespace cc { using base::TimeTicks; using base::TimeDelta; -scoped_ptr<PageScaleAnimation> PageScaleAnimation::Create( +std::unique_ptr<PageScaleAnimation> PageScaleAnimation::Create( const gfx::Vector2dF& start_scroll_offset, float start_page_scale_factor, const gfx::SizeF& viewport_size, const gfx::SizeF& root_layer_size, - scoped_ptr<TimingFunction> timing_function) { - return make_scoped_ptr(new PageScaleAnimation( + std::unique_ptr<TimingFunction> timing_function) { + return base::WrapUnique(new PageScaleAnimation( start_scroll_offset, start_page_scale_factor, viewport_size, root_layer_size, std::move(timing_function))); } @@ -59,7 +60,7 @@ PageScaleAnimation::PageScaleAnimation( float start_page_scale_factor, const gfx::SizeF& viewport_size, const gfx::SizeF& root_layer_size, - scoped_ptr<TimingFunction> timing_function) + std::unique_ptr<TimingFunction> timing_function) : start_page_scale_factor_(start_page_scale_factor), target_page_scale_factor_(0.f), start_scroll_offset_(start_scroll_offset), diff --git a/chromium/cc/input/page_scale_animation.h b/chromium/cc/input/page_scale_animation.h index dbe018b2f26..d7d10a2bfda 100644 --- a/chromium/cc/input/page_scale_animation.h +++ b/chromium/cc/input/page_scale_animation.h @@ -5,8 +5,9 @@ #ifndef CC_INPUT_PAGE_SCALE_ANIMATION_H_ #define CC_INPUT_PAGE_SCALE_ANIMATION_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/base/cc_export.h" #include "ui/gfx/geometry/size_f.h" @@ -46,12 +47,12 @@ struct PendingPageScaleAnimation { class CC_EXPORT PageScaleAnimation { public: // Construct with the state at the beginning of the animation. - static scoped_ptr<PageScaleAnimation> Create( + static std::unique_ptr<PageScaleAnimation> Create( const gfx::Vector2dF& start_scroll_offset, float start_page_scale_factor, const gfx::SizeF& viewport_size, const gfx::SizeF& root_layer_size, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); ~PageScaleAnimation(); @@ -95,7 +96,7 @@ class CC_EXPORT PageScaleAnimation { float start_page_scale_factor, const gfx::SizeF& viewport_size, const gfx::SizeF& root_layer_size, - scoped_ptr<TimingFunction> timing_function); + std::unique_ptr<TimingFunction> timing_function); private: void ClampTargetScrollOffset(); @@ -125,7 +126,7 @@ class CC_EXPORT PageScaleAnimation { base::TimeTicks start_time_; base::TimeDelta duration_; - scoped_ptr<TimingFunction> timing_function_; + std::unique_ptr<TimingFunction> timing_function_; DISALLOW_COPY_AND_ASSIGN(PageScaleAnimation); }; diff --git a/chromium/cc/input/scroll_state.h b/chromium/cc/input/scroll_state.h index 3e6f92cf972..86bc6581de3 100644 --- a/chromium/cc/input/scroll_state.h +++ b/chromium/cc/input/scroll_state.h @@ -6,8 +6,8 @@ #define CC_INPUT_SCROLL_STATE_H_ #include <list> +#include <memory> -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/input/scroll_state_data.h" #include "ui/gfx/geometry/point.h" @@ -30,14 +30,14 @@ class CC_EXPORT ScrollState { // Pops the first layer off of |scroll_chain_| and calls // |DistributeScroll| on it. void DistributeToScrollChainDescendant(); - // Positive when scrolling left. + // Positive when scrolling right. double delta_x() const { return data_.delta_x; } - // Positive when scrolling up. + // Positive when scrolling down. double delta_y() const { return data_.delta_y; } - // The location the scroll started at. For touch, the starting + // The location associated with this scroll update. For touch, this is the // position of the finger. For mouse, the location of the cursor. - int start_position_x() const { return data_.start_position_x; } - int start_position_y() const { return data_.start_position_y; } + int position_x() const { return data_.position_x; } + int position_y() const { return data_.position_y; } double velocity_x() const { return data_.velocity_x; } double velocity_y() const { return data_.velocity_y; } diff --git a/chromium/cc/input/scroll_state_data.cc b/chromium/cc/input/scroll_state_data.cc index 50e1269e1a4..a3b60322f09 100644 --- a/chromium/cc/input/scroll_state_data.cc +++ b/chromium/cc/input/scroll_state_data.cc @@ -9,8 +9,8 @@ namespace cc { ScrollStateData::ScrollStateData() : delta_x(0), delta_y(0), - start_position_x(0), - start_position_y(0), + position_x(0), + position_y(0), velocity_x(0), velocity_y(0), is_beginning(false), diff --git a/chromium/cc/input/scroll_state_data.h b/chromium/cc/input/scroll_state_data.h index 63fbe437ed1..f2b0b97fc5b 100644 --- a/chromium/cc/input/scroll_state_data.h +++ b/chromium/cc/input/scroll_state_data.h @@ -22,9 +22,9 @@ class CC_EXPORT ScrollStateData { // Scroll delta in viewport coordinates (DIP). double delta_x; double delta_y; - // Scroll position in viewport coordinates (DIP). - int start_position_x; - int start_position_y; + // Pointer (i.e. cursor/touch point) position in viewport coordinates (DIP). + int position_x; + int position_y; // Scroll velocity in DIP/seconds. double velocity_x; double velocity_y; diff --git a/chromium/cc/input/scroll_state_unittest.cc b/chromium/cc/input/scroll_state_unittest.cc index a996a1c021e..b7299007b02 100644 --- a/chromium/cc/input/scroll_state_unittest.cc +++ b/chromium/cc/input/scroll_state_unittest.cc @@ -67,7 +67,7 @@ TEST_F(ScrollStateTest, CurrentNativeScrollingScrollable) { FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); - scoped_ptr<LayerImpl> layer_impl = + std::unique_ptr<LayerImpl> layer_impl = LayerImpl::Create(host_impl.active_tree(), 1); ScrollNode* scroll_node = host_impl.active_tree()->property_trees()->scroll_tree.Node( diff --git a/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc b/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc index 079ac838f14..8ead32491a3 100644 --- a/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc +++ b/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc @@ -4,20 +4,21 @@ #include "cc/input/scrollbar_animation_controller_linear_fade.h" +#include "base/memory/ptr_util.h" #include "base/time/time.h" #include "cc/layers/layer_impl.h" #include "cc/layers/scrollbar_layer_impl_base.h" namespace cc { -scoped_ptr<ScrollbarAnimationControllerLinearFade> +std::unique_ptr<ScrollbarAnimationControllerLinearFade> ScrollbarAnimationControllerLinearFade::Create( int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, base::TimeDelta duration) { - return make_scoped_ptr(new ScrollbarAnimationControllerLinearFade( + return base::WrapUnique(new ScrollbarAnimationControllerLinearFade( scroll_layer_id, client, delay_before_starting, resize_delay_before_starting, duration)); } diff --git a/chromium/cc/input/scrollbar_animation_controller_linear_fade.h b/chromium/cc/input/scrollbar_animation_controller_linear_fade.h index 356c2cd5df7..f5993e7149a 100644 --- a/chromium/cc/input/scrollbar_animation_controller_linear_fade.h +++ b/chromium/cc/input/scrollbar_animation_controller_linear_fade.h @@ -5,8 +5,9 @@ #ifndef CC_INPUT_SCROLLBAR_ANIMATION_CONTROLLER_LINEAR_FADE_H_ #define CC_INPUT_SCROLLBAR_ANIMATION_CONTROLLER_LINEAR_FADE_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/input/scrollbar_animation_controller.h" @@ -16,7 +17,7 @@ class LayerImpl; class CC_EXPORT ScrollbarAnimationControllerLinearFade : public ScrollbarAnimationController { public: - static scoped_ptr<ScrollbarAnimationControllerLinearFade> Create( + static std::unique_ptr<ScrollbarAnimationControllerLinearFade> Create( int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, diff --git a/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc index 35eacb51027..7d7645b7ea9 100644 --- a/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc +++ b/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc @@ -49,7 +49,7 @@ class ScrollbarAnimationControllerLinearFadeTest const bool kIsLeftSideVerticalScrollbar = false; const bool kIsOverlayScrollbar = true; // Allow opacity animations. - scoped_ptr<LayerImpl> scroll_layer = + std::unique_ptr<LayerImpl> scroll_layer = LayerImpl::Create(host_impl_.active_tree(), 1); scrollbar_layer_ = SolidColorScrollbarLayerImpl::Create( host_impl_.active_tree(), 2, orientation(), kThumbThickness, @@ -74,9 +74,9 @@ class ScrollbarAnimationControllerLinearFadeTest TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; - scoped_ptr<ScrollbarAnimationControllerLinearFade> scrollbar_controller_; - scoped_ptr<LayerImpl> clip_layer_; - scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_; + std::unique_ptr<ScrollbarAnimationControllerLinearFade> scrollbar_controller_; + std::unique_ptr<LayerImpl> clip_layer_; + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_; base::Closure start_fade_; base::TimeDelta delay_; diff --git a/chromium/cc/input/scrollbar_animation_controller_thinning.cc b/chromium/cc/input/scrollbar_animation_controller_thinning.cc index 8b801ab9bc4..53e5895df73 100644 --- a/chromium/cc/input/scrollbar_animation_controller_thinning.cc +++ b/chromium/cc/input/scrollbar_animation_controller_thinning.cc @@ -4,6 +4,7 @@ #include "cc/input/scrollbar_animation_controller_thinning.h" +#include "base/memory/ptr_util.h" #include "base/time/time.h" #include "cc/layers/layer_impl.h" #include "cc/layers/scrollbar_layer_impl_base.h" @@ -17,14 +18,14 @@ const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f; namespace cc { -scoped_ptr<ScrollbarAnimationControllerThinning> +std::unique_ptr<ScrollbarAnimationControllerThinning> ScrollbarAnimationControllerThinning::Create( int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, base::TimeDelta duration) { - return make_scoped_ptr(new ScrollbarAnimationControllerThinning( + return base::WrapUnique(new ScrollbarAnimationControllerThinning( scroll_layer_id, client, delay_before_starting, resize_delay_before_starting, duration)); } diff --git a/chromium/cc/input/scrollbar_animation_controller_thinning.h b/chromium/cc/input/scrollbar_animation_controller_thinning.h index 0519d391e4b..d8be95f8481 100644 --- a/chromium/cc/input/scrollbar_animation_controller_thinning.h +++ b/chromium/cc/input/scrollbar_animation_controller_thinning.h @@ -5,8 +5,9 @@ #ifndef CC_INPUT_SCROLLBAR_ANIMATION_CONTROLLER_THINNING_H_ #define CC_INPUT_SCROLLBAR_ANIMATION_CONTROLLER_THINNING_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/input/scrollbar_animation_controller.h" @@ -18,7 +19,7 @@ class LayerImpl; class CC_EXPORT ScrollbarAnimationControllerThinning : public ScrollbarAnimationController { public: - static scoped_ptr<ScrollbarAnimationControllerThinning> Create( + static std::unique_ptr<ScrollbarAnimationControllerThinning> Create( int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, diff --git a/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc index da5d6256551..0dbe47d71ff 100644 --- a/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc +++ b/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc @@ -42,7 +42,7 @@ class ScrollbarAnimationControllerThinningTest protected: void SetUp() override { - scoped_ptr<LayerImpl> scroll_layer = + std::unique_ptr<LayerImpl> scroll_layer = LayerImpl::Create(host_impl_.active_tree(), 1); clip_layer_ = LayerImpl::Create(host_impl_.active_tree(), 3); scroll_layer->SetScrollClipLayer(clip_layer_->id()); @@ -71,9 +71,9 @@ class ScrollbarAnimationControllerThinningTest TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; - scoped_ptr<ScrollbarAnimationControllerThinning> scrollbar_controller_; - scoped_ptr<LayerImpl> clip_layer_; - scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_; + std::unique_ptr<ScrollbarAnimationControllerThinning> scrollbar_controller_; + std::unique_ptr<LayerImpl> clip_layer_; + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_; base::Closure start_fade_; base::TimeDelta delay_; diff --git a/chromium/cc/input/top_controls_manager.cc b/chromium/cc/input/top_controls_manager.cc index 44ed92049c8..e38076bc793 100644 --- a/chromium/cc/input/top_controls_manager.cc +++ b/chromium/cc/input/top_controls_manager.cc @@ -9,6 +9,7 @@ #include <algorithm> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "cc/animation/keyframed_animation_curve.h" #include "cc/animation/timing_function.h" #include "cc/input/top_controls_manager_client.h" @@ -25,13 +26,12 @@ const int64_t kShowHideMaxDurationMs = 200; } // static -scoped_ptr<TopControlsManager> TopControlsManager::Create( +std::unique_ptr<TopControlsManager> TopControlsManager::Create( TopControlsManagerClient* client, float top_controls_show_threshold, float top_controls_hide_threshold) { - return make_scoped_ptr(new TopControlsManager(client, - top_controls_show_threshold, - top_controls_hide_threshold)); + return base::WrapUnique(new TopControlsManager( + client, top_controls_show_threshold, top_controls_hide_threshold)); } TopControlsManager::TopControlsManager(TopControlsManagerClient* client, @@ -95,7 +95,9 @@ void TopControlsManager::UpdateTopControlsState(TopControlsState constraints, } void TopControlsManager::ScrollBegin() { - DCHECK(!pinch_gesture_active_); + if (pinch_gesture_active_) + return; + ResetAnimations(); ResetBaseline(); } @@ -132,7 +134,9 @@ gfx::Vector2dF TopControlsManager::ScrollBy( } void TopControlsManager::ScrollEnd() { - DCHECK(!pinch_gesture_active_); + if (pinch_gesture_active_) + return; + StartAnimationIfNecessary(); } diff --git a/chromium/cc/input/top_controls_manager.h b/chromium/cc/input/top_controls_manager.h index 995577db01b..69bb75dc704 100644 --- a/chromium/cc/input/top_controls_manager.h +++ b/chromium/cc/input/top_controls_manager.h @@ -5,8 +5,9 @@ #ifndef CC_INPUT_TOP_CONTROLS_MANAGER_H_ #define CC_INPUT_TOP_CONTROLS_MANAGER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "cc/input/top_controls_state.h" #include "cc/layers/layer_impl.h" @@ -33,7 +34,7 @@ class CC_EXPORT TopControlsManager HIDING_CONTROLS }; - static scoped_ptr<TopControlsManager> Create( + static std::unique_ptr<TopControlsManager> Create( TopControlsManagerClient* client, float top_controls_show_threshold, float top_controls_hide_threshold); @@ -79,7 +80,7 @@ class CC_EXPORT TopControlsManager TopControlsManagerClient* client_; // The client manages the lifecycle of // this. - scoped_ptr<KeyframedFloatAnimationCurve> top_controls_animation_; + std::unique_ptr<KeyframedFloatAnimationCurve> top_controls_animation_; AnimationDirection animation_direction_; TopControlsState permitted_state_; diff --git a/chromium/cc/input/top_controls_manager_unittest.cc b/chromium/cc/input/top_controls_manager_unittest.cc index b2ee9bf4727..60ea43b9e19 100644 --- a/chromium/cc/input/top_controls_manager_unittest.cc +++ b/chromium/cc/input/top_controls_manager_unittest.cc @@ -6,9 +6,9 @@ #include <algorithm> #include <cmath> +#include <memory> #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/input/top_controls_manager_client.h" #include "cc/layers/layer_impl.h" @@ -87,9 +87,9 @@ class MockTopControlsManagerClient : public TopControlsManagerClient { TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; - scoped_ptr<LayerTreeImpl> active_tree_; - scoped_ptr<LayerImpl> root_scroll_layer_; - scoped_ptr<TopControlsManager> manager_; + std::unique_ptr<LayerTreeImpl> active_tree_; + std::unique_ptr<LayerImpl> root_scroll_layer_; + std::unique_ptr<TopControlsManager> manager_; bool redraw_needed_; bool update_draw_properties_needed_; diff --git a/chromium/cc/ipc/BUILD.gn b/chromium/cc/ipc/BUILD.gn new file mode 100644 index 00000000000..ce2bd1d17ff --- /dev/null +++ b/chromium/cc/ipc/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright 2016 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. + +component("ipc") { + output_name = "cc_ipc" + + defines = [ "CC_IPC_IMPLEMENTATION" ] + + sources = [ + "cc_ipc_export.h", + "cc_param_traits.cc", + "cc_param_traits.h", + "cc_param_traits_macros.h", + ] + + public_deps = [ + "//cc", + "//cc/surfaces", + ] + + deps = [ + "//base", + "//gpu/ipc/common", + "//ipc", + "//skia", + "//ui/events/ipc", + "//ui/gfx", + "//ui/gfx/ipc", + "//ui/gfx/ipc/geometry", + "//ui/gfx/ipc/skia", + ] +} diff --git a/chromium/cc/ipc/DEPS b/chromium/cc/ipc/DEPS new file mode 100644 index 00000000000..3a74ce8ac51 --- /dev/null +++ b/chromium/cc/ipc/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+gpu/ipc/common", + "+ui/events/ipc", +] diff --git a/chromium/cc/ipc/OWNERS b/chromium/cc/ipc/OWNERS new file mode 100644 index 00000000000..aef66cf4d6c --- /dev/null +++ b/chromium/cc/ipc/OWNERS @@ -0,0 +1,8 @@ +per-file *param_traits*.*=set noparent +per-file *param_traits*.*=dcheng@chromium.org +per-file *param_traits*.*=inferno@chromium.org +per-file *param_traits*.*=jln@chromium.org +per-file *param_traits*.*=jschuh@chromium.org +per-file *param_traits*.*=kenrb@chromium.org +per-file *param_traits*.*=nasko@chromium.org +per-file *param_traits*.*=tsepez@chromium.org diff --git a/chromium/cc/ipc/cc_ipc.gyp b/chromium/cc/ipc/cc_ipc.gyp new file mode 100644 index 00000000000..9a7645d1e8c --- /dev/null +++ b/chromium/cc/ipc/cc_ipc.gyp @@ -0,0 +1,38 @@ +# 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. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + # GN version: //cc/ipc + 'target_name': 'cc_ipc', + 'type': '<(component)', + 'dependencies': [ + '../../base/base.gyp:base', + '../../cc/cc.gyp:cc', + '../../gpu/gpu.gyp:gpu_ipc_common', + '../../ipc/ipc.gyp:ipc', + '../../skia/skia.gyp:skia', + '../../ui/events/events.gyp:events_base', + '../../ui/events/events.gyp:events_ipc', + '../../ui/gfx/gfx.gyp:gfx', + '../../ui/gfx/gfx.gyp:gfx_geometry', + '../../ui/gfx/ipc/gfx_ipc.gyp:gfx_ipc', + '../../ui/gfx/ipc/geometry/gfx_ipc_geometry.gyp:gfx_ipc_geometry', + '../../ui/gfx/ipc/skia/gfx_ipc_skia.gyp:gfx_ipc_skia', + ], + 'defines': [ + 'CC_IPC_IMPLEMENTATION', + ], + 'sources': [ + 'cc_param_traits.cc', + 'cc_param_traits.h', + 'cc_param_traits_macros.h', + ], + }, + ], +} diff --git a/chromium/cc/ipc/cc_ipc_export.h b/chromium/cc/ipc/cc_ipc_export.h new file mode 100644 index 00000000000..4a3623e03d5 --- /dev/null +++ b/chromium/cc/ipc/cc_ipc_export.h @@ -0,0 +1,29 @@ +// Copyright 2016 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_IPC_CC_IPC_EXPORT_H_ +#define CC_IPC_CC_IPC_EXPORT_H_ + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(CC_IPC_IMPLEMENTATION) +#define CC_IPC_EXPORT __declspec(dllexport) +#else +#define CC_IPC_EXPORT __declspec(dllimport) +#endif // defined(CC_IPC_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(CC_IPC_IMPLEMENTATION) +#define CC_IPC_EXPORT __attribute__((visibility("default"))) +#else +#define CC_IPC_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define CC_IPC_EXPORT +#endif + +#endif // CC_IPC_CC_IPC_EXPORT_H_ diff --git a/chromium/cc/ipc/cc_param_traits.cc b/chromium/cc/ipc/cc_param_traits.cc new file mode 100644 index 00000000000..7c4406bf96f --- /dev/null +++ b/chromium/cc/ipc/cc_param_traits.cc @@ -0,0 +1,915 @@ +// Copyright (c) 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/ipc/cc_param_traits.h" + +#include <stddef.h> +#include <utility> + +#include "base/numerics/safe_conversions.h" +#include "base/time/time.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/filter_operations.h" +#include "cc/quads/debug_border_draw_quad.h" +#include "cc/quads/draw_quad.h" +#include "cc/quads/largest_draw_quad.h" +#include "cc/quads/render_pass_draw_quad.h" +#include "cc/quads/solid_color_draw_quad.h" +#include "cc/quads/surface_draw_quad.h" +#include "cc/quads/tile_draw_quad.h" +#include "cc/quads/yuv_video_draw_quad.h" +#include "third_party/skia/include/core/SkData.h" +#include "third_party/skia/include/core/SkFlattenableSerialization.h" +#include "third_party/skia/include/core/SkImageFilter.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "ui/gfx/ipc/geometry/gfx_param_traits.h" +#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h" + +namespace IPC { + +void ParamTraits<cc::FilterOperation>::GetSize(base::PickleSizer* s, + const param_type& p) { + GetParamSize(s, p.type()); + switch (p.type()) { + case cc::FilterOperation::GRAYSCALE: + case cc::FilterOperation::SEPIA: + case cc::FilterOperation::SATURATE: + case cc::FilterOperation::HUE_ROTATE: + case cc::FilterOperation::INVERT: + case cc::FilterOperation::BRIGHTNESS: + case cc::FilterOperation::SATURATING_BRIGHTNESS: + case cc::FilterOperation::CONTRAST: + case cc::FilterOperation::OPACITY: + case cc::FilterOperation::BLUR: + GetParamSize(s, p.amount()); + break; + case cc::FilterOperation::DROP_SHADOW: + GetParamSize(s, p.drop_shadow_offset()); + GetParamSize(s, p.amount()); + GetParamSize(s, p.drop_shadow_color()); + break; + case cc::FilterOperation::COLOR_MATRIX: + for (int i = 0; i < 20; ++i) + GetParamSize(s, p.matrix()[i]); + break; + case cc::FilterOperation::ZOOM: + GetParamSize(s, p.amount()); + GetParamSize(s, p.zoom_inset()); + break; + case cc::FilterOperation::REFERENCE: + GetParamSize(s, p.image_filter()); + break; + case cc::FilterOperation::ALPHA_THRESHOLD: + NOTREACHED(); + break; + } +} + +void ParamTraits<cc::FilterOperation>::Write(base::Pickle* m, + const param_type& p) { + WriteParam(m, p.type()); + switch (p.type()) { + case cc::FilterOperation::GRAYSCALE: + case cc::FilterOperation::SEPIA: + case cc::FilterOperation::SATURATE: + case cc::FilterOperation::HUE_ROTATE: + case cc::FilterOperation::INVERT: + case cc::FilterOperation::BRIGHTNESS: + case cc::FilterOperation::SATURATING_BRIGHTNESS: + case cc::FilterOperation::CONTRAST: + case cc::FilterOperation::OPACITY: + case cc::FilterOperation::BLUR: + WriteParam(m, p.amount()); + break; + case cc::FilterOperation::DROP_SHADOW: + WriteParam(m, p.drop_shadow_offset()); + WriteParam(m, p.amount()); + WriteParam(m, p.drop_shadow_color()); + break; + case cc::FilterOperation::COLOR_MATRIX: + for (int i = 0; i < 20; ++i) + WriteParam(m, p.matrix()[i]); + break; + case cc::FilterOperation::ZOOM: + WriteParam(m, p.amount()); + WriteParam(m, p.zoom_inset()); + break; + case cc::FilterOperation::REFERENCE: + WriteParam(m, p.image_filter()); + break; + case cc::FilterOperation::ALPHA_THRESHOLD: + NOTREACHED(); + break; + } +} + +bool ParamTraits<cc::FilterOperation>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r) { + cc::FilterOperation::FilterType type; + float amount; + gfx::Point drop_shadow_offset; + SkColor drop_shadow_color; + SkScalar matrix[20]; + int zoom_inset; + + if (!ReadParam(m, iter, &type)) + return false; + r->set_type(type); + + bool success = false; + switch (type) { + case cc::FilterOperation::GRAYSCALE: + case cc::FilterOperation::SEPIA: + case cc::FilterOperation::SATURATE: + case cc::FilterOperation::HUE_ROTATE: + case cc::FilterOperation::INVERT: + case cc::FilterOperation::BRIGHTNESS: + case cc::FilterOperation::SATURATING_BRIGHTNESS: + case cc::FilterOperation::CONTRAST: + case cc::FilterOperation::OPACITY: + case cc::FilterOperation::BLUR: + if (ReadParam(m, iter, &amount)) { + r->set_amount(amount); + success = true; + } + break; + case cc::FilterOperation::DROP_SHADOW: + if (ReadParam(m, iter, &drop_shadow_offset) && + ReadParam(m, iter, &amount) && + ReadParam(m, iter, &drop_shadow_color)) { + r->set_drop_shadow_offset(drop_shadow_offset); + r->set_amount(amount); + r->set_drop_shadow_color(drop_shadow_color); + success = true; + } + break; + case cc::FilterOperation::COLOR_MATRIX: { + int i; + for (i = 0; i < 20; ++i) { + if (!ReadParam(m, iter, &matrix[i])) + break; + } + if (i == 20) { + r->set_matrix(matrix); + success = true; + } + break; + } + case cc::FilterOperation::ZOOM: + if (ReadParam(m, iter, &amount) && ReadParam(m, iter, &zoom_inset) && + amount >= 0.f && zoom_inset >= 0) { + r->set_amount(amount); + r->set_zoom_inset(zoom_inset); + success = true; + } + break; + case cc::FilterOperation::REFERENCE: { + sk_sp<SkImageFilter> filter; + if (!ReadParam(m, iter, &filter)) { + success = false; + break; + } + r->set_image_filter(std::move(filter)); + success = true; + break; + } + case cc::FilterOperation::ALPHA_THRESHOLD: + break; + } + return success; +} + +void ParamTraits<cc::FilterOperation>::Log(const param_type& p, + std::string* l) { + l->append("("); + LogParam(static_cast<unsigned>(p.type()), l); + l->append(", "); + + switch (p.type()) { + case cc::FilterOperation::GRAYSCALE: + case cc::FilterOperation::SEPIA: + case cc::FilterOperation::SATURATE: + case cc::FilterOperation::HUE_ROTATE: + case cc::FilterOperation::INVERT: + case cc::FilterOperation::BRIGHTNESS: + case cc::FilterOperation::SATURATING_BRIGHTNESS: + case cc::FilterOperation::CONTRAST: + case cc::FilterOperation::OPACITY: + case cc::FilterOperation::BLUR: + LogParam(p.amount(), l); + break; + case cc::FilterOperation::DROP_SHADOW: + LogParam(p.drop_shadow_offset(), l); + l->append(", "); + LogParam(p.amount(), l); + l->append(", "); + LogParam(p.drop_shadow_color(), l); + break; + case cc::FilterOperation::COLOR_MATRIX: + for (int i = 0; i < 20; ++i) { + if (i) + l->append(", "); + LogParam(p.matrix()[i], l); + } + break; + case cc::FilterOperation::ZOOM: + LogParam(p.amount(), l); + l->append(", "); + LogParam(p.zoom_inset(), l); + break; + case cc::FilterOperation::REFERENCE: + LogParam(p.image_filter(), l); + break; + case cc::FilterOperation::ALPHA_THRESHOLD: + NOTREACHED(); + break; + } + l->append(")"); +} + +void ParamTraits<cc::FilterOperations>::GetSize(base::PickleSizer* s, + const param_type& p) { + GetParamSize(s, base::checked_cast<uint32_t>(p.size())); + for (std::size_t i = 0; i < p.size(); ++i) { + GetParamSize(s, p.at(i)); + } +} + +void ParamTraits<cc::FilterOperations>::Write(base::Pickle* m, + const param_type& p) { + WriteParam(m, base::checked_cast<uint32_t>(p.size())); + for (std::size_t i = 0; i < p.size(); ++i) { + WriteParam(m, p.at(i)); + } +} + +bool ParamTraits<cc::FilterOperations>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r) { + uint32_t count; + if (!ReadParam(m, iter, &count)) + return false; + + for (std::size_t i = 0; i < count; ++i) { + cc::FilterOperation op = cc::FilterOperation::CreateEmptyFilter(); + if (!ReadParam(m, iter, &op)) + return false; + r->Append(op); + } + return true; +} + +void ParamTraits<cc::FilterOperations>::Log(const param_type& p, + std::string* l) { + l->append("("); + for (std::size_t i = 0; i < p.size(); ++i) { + if (i) + l->append(", "); + LogParam(p.at(i), l); + } + l->append(")"); +} + +void ParamTraits<sk_sp<SkImageFilter>>::GetSize(base::PickleSizer* s, + const param_type& p) { + SkImageFilter* filter = p.get(); + if (filter) { + sk_sp<SkData> data(SkValidatingSerializeFlattenable(filter)); + s->AddData(base::checked_cast<int>(data->size())); + } else { + s->AddData(0); + } +} + +void ParamTraits<sk_sp<SkImageFilter>>::Write(base::Pickle* m, + const param_type& p) { + SkImageFilter* filter = p.get(); + if (filter) { + sk_sp<SkData> data(SkValidatingSerializeFlattenable(filter)); + m->WriteData(static_cast<const char*>(data->data()), + base::checked_cast<int>(data->size())); + } else { + m->WriteData(0, 0); + } +} + +bool ParamTraits<sk_sp<SkImageFilter>>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r) { + const char* data = 0; + int length = 0; + if (!iter->ReadData(&data, &length)) + return false; + if (length > 0) { + SkFlattenable* flattenable = SkValidatingDeserializeFlattenable( + data, length, SkImageFilter::GetFlattenableType()); + *r = sk_sp<SkImageFilter>(static_cast<SkImageFilter*>(flattenable)); + } else { + r->reset(); + } + return true; +} + +void ParamTraits<sk_sp<SkImageFilter>>::Log(const param_type& p, + std::string* l) { + l->append("("); + LogParam(p.get() ? p->countInputs() : 0, l); + l->append(")"); +} + +void ParamTraits<cc::RenderPass>::Write(base::Pickle* m, const param_type& p) { + WriteParam(m, p.id); + WriteParam(m, p.output_rect); + WriteParam(m, p.damage_rect); + WriteParam(m, p.transform_to_root_target); + WriteParam(m, p.has_transparent_background); + WriteParam(m, base::checked_cast<uint32_t>(p.quad_list.size())); + + cc::SharedQuadStateList::ConstIterator shared_quad_state_iter = + p.shared_quad_state_list.begin(); + cc::SharedQuadStateList::ConstIterator last_shared_quad_state_iter = + p.shared_quad_state_list.end(); + for (const auto& quad : p.quad_list) { + DCHECK(quad->rect.Contains(quad->visible_rect)) + << quad->material << " rect: " << quad->rect.ToString() + << " visible_rect: " << quad->visible_rect.ToString(); + DCHECK(quad->opaque_rect.IsEmpty() || + quad->rect.Contains(quad->opaque_rect)) + << quad->material << " rect: " << quad->rect.ToString() + << " opaque_rect: " << quad->opaque_rect.ToString(); + + switch (quad->material) { + case cc::DrawQuad::DEBUG_BORDER: + WriteParam(m, *cc::DebugBorderDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::PICTURE_CONTENT: + NOTREACHED(); + break; + case cc::DrawQuad::TEXTURE_CONTENT: + WriteParam(m, *cc::TextureDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::RENDER_PASS: + WriteParam(m, *cc::RenderPassDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::SOLID_COLOR: + WriteParam(m, *cc::SolidColorDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::SURFACE_CONTENT: + WriteParam(m, *cc::SurfaceDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::TILED_CONTENT: + WriteParam(m, *cc::TileDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::STREAM_VIDEO_CONTENT: + WriteParam(m, *cc::StreamVideoDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::YUV_VIDEO_CONTENT: + WriteParam(m, *cc::YUVVideoDrawQuad::MaterialCast(quad)); + break; + case cc::DrawQuad::INVALID: + break; + } + + // Null shared quad states should not occur. + DCHECK(quad->shared_quad_state); + + // SharedQuadStates should appear in the order they are used by DrawQuads. + // Find the SharedQuadState for this DrawQuad. + while (shared_quad_state_iter != p.shared_quad_state_list.end() && + quad->shared_quad_state != *shared_quad_state_iter) + ++shared_quad_state_iter; + + DCHECK(shared_quad_state_iter != p.shared_quad_state_list.end()); + + if (shared_quad_state_iter != last_shared_quad_state_iter) { + WriteParam(m, true); + WriteParam(m, **shared_quad_state_iter); + last_shared_quad_state_iter = shared_quad_state_iter; + } else { + WriteParam(m, false); + } + } +} + +static size_t ReserveSizeForRenderPassWrite(const cc::RenderPass& p) { + size_t to_reserve = sizeof(cc::RenderPass); + + // Whether the quad points to a new shared quad state for each quad. + to_reserve += p.quad_list.size() * sizeof(bool); + + // Shared quad state is only written when a quad contains a shared quad state + // that has not been written. + to_reserve += p.shared_quad_state_list.size() * sizeof(cc::SharedQuadState); + + // The largest quad type, verified by a unit test. + to_reserve += p.quad_list.size() * cc::LargestDrawQuadSize(); + return to_reserve; +} + +template <typename QuadType> +static cc::DrawQuad* ReadDrawQuad(const base::Pickle* m, + base::PickleIterator* iter, + cc::RenderPass* render_pass) { + QuadType* quad = render_pass->CreateAndAppendDrawQuad<QuadType>(); + if (!ReadParam(m, iter, quad)) + return NULL; + return quad; +} + +bool ParamTraits<cc::RenderPass>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + cc::RenderPassId id; + gfx::Rect output_rect; + gfx::Rect damage_rect; + gfx::Transform transform_to_root_target; + bool has_transparent_background; + uint32_t quad_list_size; + + if (!ReadParam(m, iter, &id) || !ReadParam(m, iter, &output_rect) || + !ReadParam(m, iter, &damage_rect) || + !ReadParam(m, iter, &transform_to_root_target) || + !ReadParam(m, iter, &has_transparent_background) || + !ReadParam(m, iter, &quad_list_size)) + return false; + + p->SetAll(id, output_rect, damage_rect, transform_to_root_target, + has_transparent_background); + + for (uint32_t i = 0; i < quad_list_size; ++i) { + cc::DrawQuad::Material material; + base::PickleIterator temp_iter = *iter; + if (!ReadParam(m, &temp_iter, &material)) + return false; + + cc::DrawQuad* draw_quad = NULL; + switch (material) { + case cc::DrawQuad::DEBUG_BORDER: + draw_quad = ReadDrawQuad<cc::DebugBorderDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::PICTURE_CONTENT: + NOTREACHED(); + return false; + case cc::DrawQuad::SURFACE_CONTENT: + draw_quad = ReadDrawQuad<cc::SurfaceDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::TEXTURE_CONTENT: + draw_quad = ReadDrawQuad<cc::TextureDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::RENDER_PASS: + draw_quad = ReadDrawQuad<cc::RenderPassDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::SOLID_COLOR: + draw_quad = ReadDrawQuad<cc::SolidColorDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::TILED_CONTENT: + draw_quad = ReadDrawQuad<cc::TileDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::STREAM_VIDEO_CONTENT: + draw_quad = ReadDrawQuad<cc::StreamVideoDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::YUV_VIDEO_CONTENT: + draw_quad = ReadDrawQuad<cc::YUVVideoDrawQuad>(m, iter, p); + break; + case cc::DrawQuad::INVALID: + break; + } + if (!draw_quad) + return false; + if (!draw_quad->rect.Contains(draw_quad->visible_rect)) { + LOG(ERROR) << "Quad with invalid visible rect " << draw_quad->material + << " rect: " << draw_quad->rect.ToString() + << " visible_rect: " << draw_quad->visible_rect.ToString(); + return false; + } + if (!draw_quad->opaque_rect.IsEmpty() && + !draw_quad->rect.Contains(draw_quad->opaque_rect)) { + LOG(ERROR) << "Quad with invalid opaque rect " << draw_quad->material + << " rect: " << draw_quad->rect.ToString() + << " opaque_rect: " << draw_quad->opaque_rect.ToString(); + return false; + } + + bool has_new_shared_quad_state; + if (!ReadParam(m, iter, &has_new_shared_quad_state)) + return false; + + // If the quad has a new shared quad state, read it in. + if (has_new_shared_quad_state) { + cc::SharedQuadState* state = p->CreateAndAppendSharedQuadState(); + if (!ReadParam(m, iter, state)) + return false; + } + + draw_quad->shared_quad_state = p->shared_quad_state_list.back(); + } + + return true; +} + +void ParamTraits<cc::RenderPass>::Log(const param_type& p, std::string* l) { + l->append("RenderPass(("); + LogParam(p.id, l); + l->append("), "); + LogParam(p.output_rect, l); + l->append(", "); + LogParam(p.damage_rect, l); + l->append(", "); + LogParam(p.transform_to_root_target, l); + l->append(", "); + LogParam(p.has_transparent_background, l); + l->append(", "); + + l->append("["); + for (const auto& shared_quad_state : p.shared_quad_state_list) { + if (shared_quad_state != p.shared_quad_state_list.front()) + l->append(", "); + LogParam(*shared_quad_state, l); + } + l->append("], ["); + for (const auto& quad : p.quad_list) { + if (quad != p.quad_list.front()) + l->append(", "); + switch (quad->material) { + case cc::DrawQuad::DEBUG_BORDER: + LogParam(*cc::DebugBorderDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::PICTURE_CONTENT: + NOTREACHED(); + break; + case cc::DrawQuad::TEXTURE_CONTENT: + LogParam(*cc::TextureDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::RENDER_PASS: + LogParam(*cc::RenderPassDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::SOLID_COLOR: + LogParam(*cc::SolidColorDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::SURFACE_CONTENT: + LogParam(*cc::SurfaceDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::TILED_CONTENT: + LogParam(*cc::TileDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::STREAM_VIDEO_CONTENT: + LogParam(*cc::StreamVideoDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::YUV_VIDEO_CONTENT: + LogParam(*cc::YUVVideoDrawQuad::MaterialCast(quad), l); + break; + case cc::DrawQuad::INVALID: + break; + } + } + l->append("])"); +} + +namespace { +enum CompositorFrameType { + NO_FRAME, + DELEGATED_FRAME, + GL_FRAME, +}; +} + +void ParamTraits<cc::CompositorFrame>::Write(base::Pickle* m, + const param_type& p) { + WriteParam(m, p.metadata); + if (p.delegated_frame_data) { + DCHECK(!p.gl_frame_data); + WriteParam(m, static_cast<int>(DELEGATED_FRAME)); + WriteParam(m, *p.delegated_frame_data); + } else if (p.gl_frame_data) { + WriteParam(m, static_cast<int>(GL_FRAME)); + WriteParam(m, *p.gl_frame_data); + } else { + WriteParam(m, static_cast<int>(NO_FRAME)); + } +} + +bool ParamTraits<cc::CompositorFrame>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + if (!ReadParam(m, iter, &p->metadata)) + return false; + + int compositor_frame_type; + if (!ReadParam(m, iter, &compositor_frame_type)) + return false; + + switch (compositor_frame_type) { + case DELEGATED_FRAME: + p->delegated_frame_data.reset(new cc::DelegatedFrameData()); + if (!ReadParam(m, iter, p->delegated_frame_data.get())) + return false; + break; + case GL_FRAME: + p->gl_frame_data.reset(new cc::GLFrameData()); + if (!ReadParam(m, iter, p->gl_frame_data.get())) + return false; + break; + case NO_FRAME: + break; + default: + return false; + } + return true; +} + +void ParamTraits<cc::CompositorFrame>::Log(const param_type& p, + std::string* l) { + l->append("CompositorFrame("); + LogParam(p.metadata, l); + l->append(", "); + if (p.delegated_frame_data) + LogParam(*p.delegated_frame_data, l); + else if (p.gl_frame_data) + LogParam(*p.gl_frame_data, l); + l->append(")"); +} + +void ParamTraits<cc::CompositorFrameAck>::Write(base::Pickle* m, + const param_type& p) { + WriteParam(m, p.resources); + if (p.gl_frame_data) { + WriteParam(m, static_cast<int>(GL_FRAME)); + WriteParam(m, *p.gl_frame_data); + } else { + WriteParam(m, static_cast<int>(NO_FRAME)); + } +} + +bool ParamTraits<cc::CompositorFrameAck>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + if (!ReadParam(m, iter, &p->resources)) + return false; + + int compositor_frame_type; + if (!ReadParam(m, iter, &compositor_frame_type)) + return false; + + switch (compositor_frame_type) { + case NO_FRAME: + break; + case GL_FRAME: + p->gl_frame_data.reset(new cc::GLFrameData()); + if (!ReadParam(m, iter, p->gl_frame_data.get())) + return false; + break; + default: + return false; + } + return true; +} + +void ParamTraits<cc::CompositorFrameAck>::Log(const param_type& p, + std::string* l) { + l->append("CompositorFrameAck("); + LogParam(p.resources, l); + l->append(", "); + if (p.gl_frame_data) + LogParam(*p.gl_frame_data, l); + l->append(")"); +} + +void ParamTraits<cc::DelegatedFrameData>::Write(base::Pickle* m, + const param_type& p) { + DCHECK_NE(0u, p.render_pass_list.size()); + + size_t to_reserve = sizeof(p.device_scale_factor); + to_reserve += p.resource_list.size() * sizeof(cc::TransferableResource); + for (const auto& pass : p.render_pass_list) { + to_reserve += sizeof(size_t) * 2; + to_reserve += ReserveSizeForRenderPassWrite(*pass); + } + m->Reserve(to_reserve); + + WriteParam(m, p.device_scale_factor); + WriteParam(m, p.resource_list); + WriteParam(m, base::checked_cast<uint32_t>(p.render_pass_list.size())); + for (const auto& pass : p.render_pass_list) { + WriteParam(m, base::checked_cast<uint32_t>(pass->quad_list.size())); + WriteParam( + m, base::checked_cast<uint32_t>(pass->shared_quad_state_list.size())); + WriteParam(m, *pass); + } +} + +bool ParamTraits<cc::DelegatedFrameData>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + const size_t kMaxRenderPasses = 10000; + const size_t kMaxSharedQuadStateListSize = 100000; + const size_t kMaxQuadListSize = 1000000; + + if (!ReadParam(m, iter, &p->device_scale_factor)) + return false; + + std::set<cc::RenderPassId> pass_set; + + uint32_t num_render_passes; + if (!ReadParam(m, iter, &p->resource_list) || + !ReadParam(m, iter, &num_render_passes) || + num_render_passes > kMaxRenderPasses || num_render_passes == 0) + return false; + for (uint32_t i = 0; i < num_render_passes; ++i) { + uint32_t quad_list_size; + uint32_t shared_quad_state_list_size; + if (!ReadParam(m, iter, &quad_list_size) || + !ReadParam(m, iter, &shared_quad_state_list_size) || + quad_list_size > kMaxQuadListSize || + shared_quad_state_list_size > kMaxSharedQuadStateListSize) + return false; + std::unique_ptr<cc::RenderPass> render_pass = + cc::RenderPass::Create(static_cast<size_t>(shared_quad_state_list_size), + static_cast<size_t>(quad_list_size)); + if (!ReadParam(m, iter, render_pass.get())) + return false; + // Validate that each RenderPassDrawQuad points at a valid RenderPass + // earlier in the frame. + for (const auto* quad : render_pass->quad_list) { + if (quad->material != cc::DrawQuad::RENDER_PASS) + continue; + const cc::RenderPassDrawQuad* rpdq = + cc::RenderPassDrawQuad::MaterialCast(quad); + if (!pass_set.count(rpdq->render_pass_id)) + return false; + } + pass_set.insert(render_pass->id); + p->render_pass_list.push_back(std::move(render_pass)); + } + return true; +} + +void ParamTraits<cc::DelegatedFrameData>::Log(const param_type& p, + std::string* l) { + l->append("DelegatedFrameData("); + LogParam(p.device_scale_factor, l); + LogParam(p.resource_list, l); + l->append(", ["); + for (size_t i = 0; i < p.render_pass_list.size(); ++i) { + if (i) + l->append(", "); + LogParam(*p.render_pass_list[i], l); + } + l->append("])"); +} + +void ParamTraits<cc::DrawQuad::Resources>::GetSize(base::PickleSizer* s, + const param_type& p) { + GetParamSize(s, p.count); + for (size_t i = 0; i < p.count; ++i) + GetParamSize(s, p.ids[i]); +} + +void ParamTraits<cc::DrawQuad::Resources>::Write(base::Pickle* m, + const param_type& p) { + DCHECK_LE(p.count, cc::DrawQuad::Resources::kMaxResourceIdCount); + WriteParam(m, p.count); + for (size_t i = 0; i < p.count; ++i) + WriteParam(m, p.ids[i]); +} + +bool ParamTraits<cc::DrawQuad::Resources>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + if (!ReadParam(m, iter, &p->count)) + return false; + if (p->count > cc::DrawQuad::Resources::kMaxResourceIdCount) + return false; + for (size_t i = 0; i < p->count; ++i) { + if (!ReadParam(m, iter, &p->ids[i])) + return false; + } + return true; +} + +void ParamTraits<cc::DrawQuad::Resources>::Log(const param_type& p, + std::string* l) { + l->append("DrawQuad::Resources("); + LogParam(p.count, l); + l->append(", ["); + if (p.count > cc::DrawQuad::Resources::kMaxResourceIdCount) { + l->append("])"); + return; + } + + for (size_t i = 0; i < p.count; ++i) { + LogParam(p.ids[i], l); + if (i < (p.count - 1)) + l->append(", "); + } + l->append("])"); +} + +void ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::GetSize( + base::PickleSizer* s, + const param_type& p) { + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + GetParamSize(s, p.size_in_pixels[i]); + } +} + +void ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::Write( + base::Pickle* m, + const param_type& p) { + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + WriteParam(m, p.size_in_pixels[i]); + } +} + +bool ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::Read( + const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + if (!ReadParam(m, iter, &p->size_in_pixels[i])) + return false; + } + return true; +} + +void ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::Log( + const param_type& p, + std::string* l) { + l->append("StreamVideoDrawQuad::OverlayResources(["); + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + LogParam(p.size_in_pixels[i], l); + if (i < (cc::DrawQuad::Resources::kMaxResourceIdCount - 1)) + l->append(", "); + } + l->append("])"); +} + +void ParamTraits<cc::TextureDrawQuad::OverlayResources>::GetSize( + base::PickleSizer* s, + const param_type& p) { + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + GetParamSize(s, p.size_in_pixels[i]); + } +} + +void ParamTraits<cc::TextureDrawQuad::OverlayResources>::Write( + base::Pickle* m, + const param_type& p) { + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + WriteParam(m, p.size_in_pixels[i]); + } +} + +bool ParamTraits<cc::TextureDrawQuad::OverlayResources>::Read( + const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + if (!ReadParam(m, iter, &p->size_in_pixels[i])) + return false; + } + return true; +} + +void ParamTraits<cc::TextureDrawQuad::OverlayResources>::Log( + const param_type& p, + std::string* l) { + l->append("TextureDrawQuad::OverlayResources(["); + for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) { + LogParam(p.size_in_pixels[i], l); + if (i < (cc::DrawQuad::Resources::kMaxResourceIdCount - 1)) + l->append(", "); + } + l->append("])"); +} + +} // namespace IPC + +// Generate param traits size methods. +#include "ipc/param_traits_size_macros.h" +namespace IPC { +#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_ +#include "cc/ipc/cc_param_traits_macros.h" +} + +// Generate param traits write methods. +#include "ipc/param_traits_write_macros.h" +namespace IPC { +#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_ +#include "cc/ipc/cc_param_traits_macros.h" +} // namespace IPC + +// Generate param traits read methods. +#include "ipc/param_traits_read_macros.h" +namespace IPC { +#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_ +#include "cc/ipc/cc_param_traits_macros.h" +} // namespace IPC + +// Generate param traits log methods. +#include "ipc/param_traits_log_macros.h" +namespace IPC { +#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_ +#include "cc/ipc/cc_param_traits_macros.h" +} // namespace IPC diff --git a/chromium/cc/ipc/cc_param_traits.h b/chromium/cc/ipc/cc_param_traits.h new file mode 100644 index 00000000000..310b3f0b72a --- /dev/null +++ b/chromium/cc/ipc/cc_param_traits.h @@ -0,0 +1,140 @@ +// Copyright (c) 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. +// +// IPC Messages sent between compositor instances. + +#ifndef CC_IPC_CC_PARAM_TRAITS_H_ +#define CC_IPC_CC_PARAM_TRAITS_H_ + +#include "cc/ipc/cc_ipc_export.h" +#include "cc/ipc/cc_param_traits_macros.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/compositor_frame_ack.h" +#include "cc/output/filter_operation.h" +#include "cc/output/viewport_selection_bound.h" +#include "cc/quads/draw_quad.h" +#include "cc/quads/stream_video_draw_quad.h" +#include "cc/quads/texture_draw_quad.h" +#include "gpu/ipc/common/gpu_command_buffer_traits.h" +#include "ipc/ipc_message_macros.h" + +namespace gfx { +class Transform; +} + +namespace cc { +class FilterOperations; +} + +namespace IPC { + +template <> +struct ParamTraits<cc::FilterOperation> { + typedef cc::FilterOperation param_type; + static void GetSize(base::PickleSizer* s, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct ParamTraits<cc::FilterOperations> { + typedef cc::FilterOperations param_type; + static void GetSize(base::PickleSizer* s, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct ParamTraits<sk_sp<SkImageFilter>> { + typedef sk_sp<SkImageFilter> param_type; + static void GetSize(base::PickleSizer* s, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct CC_IPC_EXPORT ParamTraits<cc::RenderPass> { + typedef cc::RenderPass param_type; + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct CC_IPC_EXPORT ParamTraits<cc::CompositorFrame> { + typedef cc::CompositorFrame param_type; + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct CC_IPC_EXPORT ParamTraits<cc::CompositorFrameAck> { + typedef cc::CompositorFrameAck param_type; + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct CC_IPC_EXPORT ParamTraits<cc::DelegatedFrameData> { + typedef cc::DelegatedFrameData param_type; + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct CC_IPC_EXPORT ParamTraits<cc::DrawQuad::Resources> { + typedef cc::DrawQuad::Resources param_type; + static void GetSize(base::PickleSizer* s, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct CC_IPC_EXPORT ParamTraits<cc::StreamVideoDrawQuad::OverlayResources> { + typedef cc::StreamVideoDrawQuad::OverlayResources param_type; + static void GetSize(base::PickleSizer* s, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct CC_IPC_EXPORT ParamTraits<cc::TextureDrawQuad::OverlayResources> { + typedef cc::TextureDrawQuad::OverlayResources param_type; + static void GetSize(base::PickleSizer* s, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +} // namespace IPC + +#endif // CC_IPC_CC_PARAM_TRAITS_H_ diff --git a/chromium/cc/ipc/cc_param_traits_macros.h b/chromium/cc/ipc/cc_param_traits_macros.h new file mode 100644 index 00000000000..6450b00087f --- /dev/null +++ b/chromium/cc/ipc/cc_param_traits_macros.h @@ -0,0 +1,217 @@ +// Copyright 2016 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_IPC_CC_PARAM_TRAITS_MACROS_H_ +#define CC_IPC_CC_PARAM_TRAITS_MACROS_H_ + +#include "cc/input/selection_bound_type.h" +#include "cc/output/begin_frame_args.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/filter_operation.h" +#include "cc/quads/debug_border_draw_quad.h" +#include "cc/quads/draw_quad.h" +#include "cc/quads/render_pass.h" +#include "cc/quads/render_pass_id.h" +#include "cc/quads/shared_quad_state.h" +#include "cc/quads/solid_color_draw_quad.h" +#include "cc/quads/stream_video_draw_quad.h" +#include "cc/quads/surface_draw_quad.h" +#include "cc/quads/texture_draw_quad.h" +#include "cc/quads/tile_draw_quad.h" +#include "cc/quads/yuv_video_draw_quad.h" +#include "cc/resources/resource_format.h" +#include "cc/resources/returned_resource.h" +#include "cc/resources/transferable_resource.h" +#include "cc/surfaces/surface_id.h" +#include "cc/surfaces/surface_sequence.h" +#include "ui/events/ipc/latency_info_param_traits.h" +#include "ui/gfx/ipc/gfx_param_traits.h" +#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h" + +#undef IPC_MESSAGE_EXPORT +#define IPC_MESSAGE_EXPORT CC_IPC_EXPORT + +IPC_ENUM_TRAITS_MAX_VALUE(cc::DrawQuad::Material, cc::DrawQuad::MATERIAL_LAST) +IPC_ENUM_TRAITS_MAX_VALUE(cc::FilterOperation::FilterType, + cc::FilterOperation::FILTER_TYPE_LAST) +IPC_ENUM_TRAITS_MAX_VALUE(cc::ResourceFormat, cc::RESOURCE_FORMAT_MAX) +IPC_ENUM_TRAITS_MAX_VALUE(cc::SelectionBoundType, cc::SELECTION_BOUND_TYPE_LAST) + +// TODO(fsamuel): This trait belongs with skia code. +IPC_ENUM_TRAITS_MAX_VALUE(SkXfermode::Mode, SkXfermode::kLastMode) +IPC_ENUM_TRAITS_MAX_VALUE(cc::YUVVideoDrawQuad::ColorSpace, + cc::YUVVideoDrawQuad::COLOR_SPACE_LAST) + +IPC_STRUCT_TRAITS_BEGIN(cc::RenderPassId) + IPC_STRUCT_TRAITS_MEMBER(layer_id) + IPC_STRUCT_TRAITS_MEMBER(index) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::SurfaceId) + IPC_STRUCT_TRAITS_MEMBER(id) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::SurfaceSequence) + IPC_STRUCT_TRAITS_MEMBER(id_namespace) + IPC_STRUCT_TRAITS_MEMBER(sequence) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(material) + IPC_STRUCT_TRAITS_MEMBER(rect) + IPC_STRUCT_TRAITS_MEMBER(opaque_rect) + IPC_STRUCT_TRAITS_MEMBER(visible_rect) + IPC_STRUCT_TRAITS_MEMBER(needs_blending) + IPC_STRUCT_TRAITS_MEMBER(resources) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::DebugBorderDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(color) + IPC_STRUCT_TRAITS_MEMBER(width) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::RenderPassDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(render_pass_id) + IPC_STRUCT_TRAITS_MEMBER(mask_uv_scale) + IPC_STRUCT_TRAITS_MEMBER(mask_texture_size) + IPC_STRUCT_TRAITS_MEMBER(filters) + IPC_STRUCT_TRAITS_MEMBER(filters_scale) + IPC_STRUCT_TRAITS_MEMBER(background_filters) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::SolidColorDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(color) + IPC_STRUCT_TRAITS_MEMBER(force_anti_aliasing_off) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::StreamVideoDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(overlay_resources) + IPC_STRUCT_TRAITS_MEMBER(matrix) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::SurfaceDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(surface_id) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::TextureDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(overlay_resources) + IPC_STRUCT_TRAITS_MEMBER(premultiplied_alpha) + IPC_STRUCT_TRAITS_MEMBER(uv_top_left) + IPC_STRUCT_TRAITS_MEMBER(uv_bottom_right) + IPC_STRUCT_TRAITS_MEMBER(background_color) + IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[0]) + IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[1]) + IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[2]) + IPC_STRUCT_TRAITS_MEMBER(vertex_opacity[3]) + IPC_STRUCT_TRAITS_MEMBER(y_flipped) + IPC_STRUCT_TRAITS_MEMBER(nearest_neighbor) + IPC_STRUCT_TRAITS_MEMBER(secure_output_only) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::TileDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(tex_coord_rect) + IPC_STRUCT_TRAITS_MEMBER(texture_size) + IPC_STRUCT_TRAITS_MEMBER(swizzle_contents) + IPC_STRUCT_TRAITS_MEMBER(nearest_neighbor) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::YUVVideoDrawQuad) + IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad) + IPC_STRUCT_TRAITS_MEMBER(ya_tex_coord_rect) + IPC_STRUCT_TRAITS_MEMBER(uv_tex_coord_rect) + IPC_STRUCT_TRAITS_MEMBER(ya_tex_size) + IPC_STRUCT_TRAITS_MEMBER(uv_tex_size) + IPC_STRUCT_TRAITS_MEMBER(color_space) + IPC_STRUCT_TRAITS_MEMBER(resource_offset) + IPC_STRUCT_TRAITS_MEMBER(resource_multiplier) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::SharedQuadState) + IPC_STRUCT_TRAITS_MEMBER(quad_to_target_transform) + IPC_STRUCT_TRAITS_MEMBER(quad_layer_bounds) + IPC_STRUCT_TRAITS_MEMBER(visible_quad_layer_rect) + IPC_STRUCT_TRAITS_MEMBER(clip_rect) + IPC_STRUCT_TRAITS_MEMBER(is_clipped) + IPC_STRUCT_TRAITS_MEMBER(opacity) + IPC_STRUCT_TRAITS_MEMBER(blend_mode) + IPC_STRUCT_TRAITS_MEMBER(sorting_context_id) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::TransferableResource) + IPC_STRUCT_TRAITS_MEMBER(id) + IPC_STRUCT_TRAITS_MEMBER(format) + IPC_STRUCT_TRAITS_MEMBER(filter) + IPC_STRUCT_TRAITS_MEMBER(size) + IPC_STRUCT_TRAITS_MEMBER(mailbox_holder) + IPC_STRUCT_TRAITS_MEMBER(read_lock_fences_enabled) + IPC_STRUCT_TRAITS_MEMBER(is_software) + IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_id) + IPC_STRUCT_TRAITS_MEMBER(is_overlay_candidate) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::ReturnedResource) + IPC_STRUCT_TRAITS_MEMBER(id) + IPC_STRUCT_TRAITS_MEMBER(sync_token) + IPC_STRUCT_TRAITS_MEMBER(count) + IPC_STRUCT_TRAITS_MEMBER(lost) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::ViewportSelectionBound) + IPC_STRUCT_TRAITS_MEMBER(type) + IPC_STRUCT_TRAITS_MEMBER(edge_top) + IPC_STRUCT_TRAITS_MEMBER(edge_bottom) + IPC_STRUCT_TRAITS_MEMBER(visible) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::ViewportSelection) + IPC_STRUCT_TRAITS_MEMBER(start) + IPC_STRUCT_TRAITS_MEMBER(end) + IPC_STRUCT_TRAITS_MEMBER(is_editable) + IPC_STRUCT_TRAITS_MEMBER(is_empty_text_form_control) +IPC_STRUCT_TRAITS_END() + +IPC_ENUM_TRAITS_MAX_VALUE(cc::BeginFrameArgs::BeginFrameArgsType, + cc::BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX - 1) + +IPC_STRUCT_TRAITS_BEGIN(cc::BeginFrameArgs) + IPC_STRUCT_TRAITS_MEMBER(frame_time) + IPC_STRUCT_TRAITS_MEMBER(deadline) + IPC_STRUCT_TRAITS_MEMBER(interval) + IPC_STRUCT_TRAITS_MEMBER(type) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::CompositorFrameMetadata) + IPC_STRUCT_TRAITS_MEMBER(device_scale_factor) + IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset) + IPC_STRUCT_TRAITS_MEMBER(page_scale_factor) + IPC_STRUCT_TRAITS_MEMBER(scrollable_viewport_size) + IPC_STRUCT_TRAITS_MEMBER(root_layer_size) + IPC_STRUCT_TRAITS_MEMBER(min_page_scale_factor) + IPC_STRUCT_TRAITS_MEMBER(max_page_scale_factor) + IPC_STRUCT_TRAITS_MEMBER(root_overflow_x_hidden) + IPC_STRUCT_TRAITS_MEMBER(root_overflow_y_hidden) + IPC_STRUCT_TRAITS_MEMBER(location_bar_offset) + IPC_STRUCT_TRAITS_MEMBER(location_bar_content_translation) + IPC_STRUCT_TRAITS_MEMBER(root_background_color) + IPC_STRUCT_TRAITS_MEMBER(selection) + IPC_STRUCT_TRAITS_MEMBER(latency_info) + IPC_STRUCT_TRAITS_MEMBER(satisfies_sequences) + IPC_STRUCT_TRAITS_MEMBER(referenced_surfaces) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(cc::GLFrameData) + IPC_STRUCT_TRAITS_MEMBER(mailbox) + IPC_STRUCT_TRAITS_MEMBER(sync_token) + IPC_STRUCT_TRAITS_MEMBER(size) + IPC_STRUCT_TRAITS_MEMBER(sub_buffer_rect) +IPC_STRUCT_TRAITS_END() + +#endif // CC_IPC_CC_PARAM_TRAITS_MACROS_H_ diff --git a/chromium/cc/ipc/cc_param_traits_perftest.cc b/chromium/cc/ipc/cc_param_traits_perftest.cc new file mode 100644 index 00000000000..1cf40f1a3a3 --- /dev/null +++ b/chromium/cc/ipc/cc_param_traits_perftest.cc @@ -0,0 +1,155 @@ +// 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 <utility> + +#include "base/test/launcher/unit_test_launcher.h" +#include "base/test/test_suite.h" +#include "cc/ipc/cc_param_traits.h" +#include "cc/output/compositor_frame.h" +#include "cc/quads/picture_draw_quad.h" +#include "ipc/ipc_message.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/perf/perf_test.h" + +using cc::CompositorFrame; +using cc::DelegatedFrameData; +using cc::DrawQuad; +using cc::PictureDrawQuad; +using cc::RenderPass; +using cc::SharedQuadState; + +namespace content { +namespace { + +static const int kTimeLimitMillis = 2000; +static const int kNumWarmupRuns = 20; +static const int kTimeCheckInterval = 10; + +class CCParamTraitsPerfTest : public testing::Test { + protected: + static void RunTest(const std::string& test_name, + const CompositorFrame& frame) { + for (int i = 0; i < kNumWarmupRuns; ++i) { + IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); + IPC::ParamTraits<CompositorFrame>::Write(&msg, frame); + } + + base::TimeTicks start = base::TimeTicks::Now(); + base::TimeTicks end = + start + base::TimeDelta::FromMilliseconds(kTimeLimitMillis); + base::TimeDelta min_time; + int count = 0; + while (start < end) { + for (int i = 0; i < kTimeCheckInterval; ++i) { + IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); + IPC::ParamTraits<CompositorFrame>::Write(&msg, frame); + ++count; + } + + base::TimeTicks now = base::TimeTicks::Now(); + if (now - start < min_time || min_time.is_zero()) + min_time = now - start; + start = base::TimeTicks::Now(); + } + + perf_test::PrintResult( + "min_frame_serialization_time", "", test_name, + min_time.InMillisecondsF() / kTimeCheckInterval * 1000, "us", true); + } +}; + +TEST_F(CCParamTraitsPerfTest, DelegatedFrame_ManyQuads_1_4000) { + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); + + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); + render_pass->CreateAndAppendSharedQuadState(); + for (int i = 0; i < 4000; ++i) { + PictureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); + quad->shared_quad_state = render_pass->shared_quad_state_list.back(); + } + + frame->delegated_frame_data.reset(new DelegatedFrameData); + frame->delegated_frame_data->render_pass_list.push_back( + std::move(render_pass)); + + RunTest("DelegatedFrame_ManyQuads_1_4000", *frame); +} + +TEST_F(CCParamTraitsPerfTest, DelegatedFrame_ManyQuads_1_100000) { + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); + + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); + render_pass->CreateAndAppendSharedQuadState(); + for (int i = 0; i < 100000; ++i) { + PictureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); + quad->shared_quad_state = render_pass->shared_quad_state_list.back(); + } + + frame->delegated_frame_data.reset(new DelegatedFrameData); + frame->delegated_frame_data->render_pass_list.push_back( + std::move(render_pass)); + + RunTest("DelegatedFrame_ManyQuads_1_100000", *frame); +} + +TEST_F(CCParamTraitsPerfTest, DelegatedFrame_ManyQuads_4000_4000) { + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); + + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); + for (int i = 0; i < 4000; ++i) { + render_pass->CreateAndAppendSharedQuadState(); + PictureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); + quad->shared_quad_state = render_pass->shared_quad_state_list.back(); + } + + frame->delegated_frame_data.reset(new DelegatedFrameData); + frame->delegated_frame_data->render_pass_list.push_back( + std::move(render_pass)); + + RunTest("DelegatedFrame_ManyQuads_4000_4000", *frame); +} + +TEST_F(CCParamTraitsPerfTest, DelegatedFrame_ManyQuads_100000_100000) { + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); + + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); + for (int i = 0; i < 100000; ++i) { + render_pass->CreateAndAppendSharedQuadState(); + PictureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); + quad->shared_quad_state = render_pass->shared_quad_state_list.back(); + } + + frame->delegated_frame_data.reset(new DelegatedFrameData); + frame->delegated_frame_data->render_pass_list.push_back( + std::move(render_pass)); + + RunTest("DelegatedFrame_ManyQuads_100000_100000", *frame); +} + +TEST_F(CCParamTraitsPerfTest, DelegatedFrame_ManyRenderPasses_10000_100) { + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); + frame->delegated_frame_data.reset(new DelegatedFrameData); + + for (int i = 0; i < 1000; ++i) { + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); + for (int j = 0; j < 100; ++j) { + render_pass->CreateAndAppendSharedQuadState(); + PictureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); + quad->shared_quad_state = render_pass->shared_quad_state_list.back(); + } + frame->delegated_frame_data->render_pass_list.push_back( + std::move(render_pass)); + } + + RunTest("DelegatedFrame_ManyRenderPasses_10000_100", *frame); +} + +} // namespace +} // namespace content diff --git a/chromium/cc/ipc/cc_param_traits_unittest.cc b/chromium/cc/ipc/cc_param_traits_unittest.cc new file mode 100644 index 00000000000..1def13d87e3 --- /dev/null +++ b/chromium/cc/ipc/cc_param_traits_unittest.cc @@ -0,0 +1,609 @@ +// Copyright (c) 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 <stddef.h> +#include <string.h> +#include <algorithm> +#include <utility> + +#include "base/macros.h" +#include "build/build_config.h" +#include "cc/ipc/cc_param_traits.h" +#include "cc/output/compositor_frame.h" +#include "cc/quads/picture_draw_quad.h" +#include "cc/quads/render_pass_draw_quad.h" +#include "ipc/ipc_message.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/effects/SkBlurImageFilter.h" + +#if defined(OS_POSIX) +#include "base/file_descriptor_posix.h" +#endif + +using cc::DelegatedFrameData; +using cc::DebugBorderDrawQuad; +using cc::DrawQuad; +using cc::FilterOperation; +using cc::FilterOperations; +using cc::PictureDrawQuad; +using cc::RenderPass; +using cc::RenderPassId; +using cc::RenderPassDrawQuad; +using cc::ResourceId; +using cc::ResourceProvider; +using cc::SharedQuadState; +using cc::SolidColorDrawQuad; +using cc::SurfaceDrawQuad; +using cc::TextureDrawQuad; +using cc::TileDrawQuad; +using cc::TransferableResource; +using cc::StreamVideoDrawQuad; +using cc::YUVVideoDrawQuad; +using gfx::Transform; + +namespace content { +namespace { + +class CCParamTraitsTest : public testing::Test { + protected: + void Compare(const RenderPass* a, const RenderPass* b) { + EXPECT_EQ(a->id, b->id); + EXPECT_EQ(a->output_rect.ToString(), b->output_rect.ToString()); + EXPECT_EQ(a->damage_rect.ToString(), b->damage_rect.ToString()); + EXPECT_EQ(a->transform_to_root_target, b->transform_to_root_target); + EXPECT_EQ(a->has_transparent_background, b->has_transparent_background); + } + + void Compare(const SharedQuadState* a, const SharedQuadState* b) { + EXPECT_EQ(a->quad_to_target_transform, b->quad_to_target_transform); + EXPECT_EQ(a->quad_layer_bounds, b->quad_layer_bounds); + EXPECT_EQ(a->visible_quad_layer_rect, b->visible_quad_layer_rect); + EXPECT_EQ(a->clip_rect, b->clip_rect); + EXPECT_EQ(a->is_clipped, b->is_clipped); + EXPECT_EQ(a->opacity, b->opacity); + EXPECT_EQ(a->blend_mode, b->blend_mode); + EXPECT_EQ(a->sorting_context_id, b->sorting_context_id); + } + + void Compare(const DrawQuad* a, const DrawQuad* b) { + ASSERT_NE(DrawQuad::INVALID, a->material); + ASSERT_EQ(a->material, b->material); + EXPECT_EQ(a->rect.ToString(), b->rect.ToString()); + EXPECT_EQ(a->opaque_rect.ToString(), b->opaque_rect.ToString()); + EXPECT_EQ(a->visible_rect.ToString(), b->visible_rect.ToString()); + EXPECT_EQ(a->needs_blending, b->needs_blending); + + Compare(a->shared_quad_state, b->shared_quad_state); + + switch (a->material) { + case DrawQuad::DEBUG_BORDER: + Compare(DebugBorderDrawQuad::MaterialCast(a), + DebugBorderDrawQuad::MaterialCast(b)); + break; + case DrawQuad::PICTURE_CONTENT: + Compare(PictureDrawQuad::MaterialCast(a), + PictureDrawQuad::MaterialCast(b)); + break; + case DrawQuad::RENDER_PASS: + Compare(RenderPassDrawQuad::MaterialCast(a), + RenderPassDrawQuad::MaterialCast(b)); + break; + case DrawQuad::TEXTURE_CONTENT: + Compare(TextureDrawQuad::MaterialCast(a), + TextureDrawQuad::MaterialCast(b)); + break; + case DrawQuad::TILED_CONTENT: + Compare(TileDrawQuad::MaterialCast(a), TileDrawQuad::MaterialCast(b)); + break; + case DrawQuad::SOLID_COLOR: + Compare(SolidColorDrawQuad::MaterialCast(a), + SolidColorDrawQuad::MaterialCast(b)); + break; + case DrawQuad::STREAM_VIDEO_CONTENT: + Compare(StreamVideoDrawQuad::MaterialCast(a), + StreamVideoDrawQuad::MaterialCast(b)); + break; + case DrawQuad::SURFACE_CONTENT: + Compare(SurfaceDrawQuad::MaterialCast(a), + SurfaceDrawQuad::MaterialCast(b)); + break; + case DrawQuad::YUV_VIDEO_CONTENT: + Compare(YUVVideoDrawQuad::MaterialCast(a), + YUVVideoDrawQuad::MaterialCast(b)); + break; + case DrawQuad::INVALID: + break; + } + } + + void Compare(const DebugBorderDrawQuad* a, const DebugBorderDrawQuad* b) { + EXPECT_EQ(a->color, b->color); + EXPECT_EQ(a->width, b->width); + } + + void Compare(const RenderPassDrawQuad* a, const RenderPassDrawQuad* b) { + EXPECT_EQ(a->render_pass_id, b->render_pass_id); + EXPECT_EQ(a->mask_resource_id(), b->mask_resource_id()); + EXPECT_EQ(a->mask_uv_scale.ToString(), b->mask_uv_scale.ToString()); + EXPECT_EQ(a->mask_texture_size.ToString(), b->mask_texture_size.ToString()); + EXPECT_EQ(a->filters.size(), b->filters.size()); + for (size_t i = 0; i < a->filters.size(); ++i) { + if (a->filters.at(i).type() != cc::FilterOperation::REFERENCE) { + EXPECT_EQ(a->filters.at(i), b->filters.at(i)); + } else { + EXPECT_EQ(b->filters.at(i).type(), cc::FilterOperation::REFERENCE); + EXPECT_EQ(a->filters.at(i).image_filter()->countInputs(), + b->filters.at(i).image_filter()->countInputs()); + } + } + EXPECT_EQ(a->filters_scale, b->filters_scale); + EXPECT_EQ(a->background_filters, b->background_filters); + } + + void Compare(const SolidColorDrawQuad* a, const SolidColorDrawQuad* b) { + EXPECT_EQ(a->color, b->color); + EXPECT_EQ(a->force_anti_aliasing_off, b->force_anti_aliasing_off); + } + + void Compare(const StreamVideoDrawQuad* a, const StreamVideoDrawQuad* b) { + EXPECT_EQ(a->resource_id(), b->resource_id()); + EXPECT_EQ(a->resource_size_in_pixels(), b->resource_size_in_pixels()); + EXPECT_EQ(a->matrix, b->matrix); + } + + void Compare(const SurfaceDrawQuad* a, const SurfaceDrawQuad* b) { + EXPECT_EQ(a->surface_id, b->surface_id); + } + + void Compare(const TextureDrawQuad* a, const TextureDrawQuad* b) { + EXPECT_EQ(a->resource_id(), b->resource_id()); + EXPECT_EQ(a->resource_size_in_pixels(), b->resource_size_in_pixels()); + EXPECT_EQ(a->premultiplied_alpha, b->premultiplied_alpha); + EXPECT_EQ(a->uv_top_left, b->uv_top_left); + EXPECT_EQ(a->uv_bottom_right, b->uv_bottom_right); + EXPECT_EQ(a->background_color, b->background_color); + EXPECT_EQ(a->vertex_opacity[0], b->vertex_opacity[0]); + EXPECT_EQ(a->vertex_opacity[1], b->vertex_opacity[1]); + EXPECT_EQ(a->vertex_opacity[2], b->vertex_opacity[2]); + EXPECT_EQ(a->vertex_opacity[3], b->vertex_opacity[3]); + EXPECT_EQ(a->y_flipped, b->y_flipped); + EXPECT_EQ(a->nearest_neighbor, b->nearest_neighbor); + EXPECT_EQ(a->secure_output_only, b->secure_output_only); + } + + void Compare(const TileDrawQuad* a, const TileDrawQuad* b) { + EXPECT_EQ(a->resource_id(), b->resource_id()); + EXPECT_EQ(a->tex_coord_rect, b->tex_coord_rect); + EXPECT_EQ(a->texture_size, b->texture_size); + EXPECT_EQ(a->swizzle_contents, b->swizzle_contents); + EXPECT_EQ(a->nearest_neighbor, b->nearest_neighbor); + } + + void Compare(const YUVVideoDrawQuad* a, const YUVVideoDrawQuad* b) { + EXPECT_EQ(a->ya_tex_coord_rect, b->ya_tex_coord_rect); + EXPECT_EQ(a->uv_tex_coord_rect, b->uv_tex_coord_rect); + EXPECT_EQ(a->ya_tex_size, b->ya_tex_size); + EXPECT_EQ(a->uv_tex_size, b->uv_tex_size); + EXPECT_EQ(a->y_plane_resource_id(), b->y_plane_resource_id()); + EXPECT_EQ(a->u_plane_resource_id(), b->u_plane_resource_id()); + EXPECT_EQ(a->v_plane_resource_id(), b->v_plane_resource_id()); + EXPECT_EQ(a->a_plane_resource_id(), b->a_plane_resource_id()); + EXPECT_EQ(a->color_space, b->color_space); + } + + void Compare(const TransferableResource& a, const TransferableResource& b) { + EXPECT_EQ(a.id, b.id); + EXPECT_EQ(a.format, b.format); + EXPECT_EQ(a.filter, b.filter); + EXPECT_EQ(a.size.ToString(), b.size.ToString()); + for (size_t i = 0; i < arraysize(a.mailbox_holder.mailbox.name); ++i) { + EXPECT_EQ(a.mailbox_holder.mailbox.name[i], + b.mailbox_holder.mailbox.name[i]); + } + EXPECT_EQ(a.mailbox_holder.texture_target, b.mailbox_holder.texture_target); + EXPECT_EQ(a.mailbox_holder.sync_token, b.mailbox_holder.sync_token); + EXPECT_EQ(a.is_overlay_candidate, b.is_overlay_candidate); + } +}; + +TEST_F(CCParamTraitsTest, AllQuads) { + IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); + + Transform arbitrary_matrix1; + arbitrary_matrix1.Scale(3, 3); + arbitrary_matrix1.Translate(-5, 20); + arbitrary_matrix1.Rotate(15); + Transform arbitrary_matrix2; + arbitrary_matrix2.Scale(10, -1); + arbitrary_matrix2.Translate(20, 3); + arbitrary_matrix2.Rotate(24); + gfx::Rect arbitrary_rect1(-5, 9, 3, 15); + gfx::Rect arbitrary_rect1_inside_rect1(-4, 12, 2, 8); + gfx::Rect arbitrary_rect2_inside_rect1(-5, 11, 1, 2); + gfx::Rect arbitrary_rect2(40, 23, 11, 7); + gfx::Rect arbitrary_rect1_inside_rect2(44, 23, 4, 2); + gfx::Rect arbitrary_rect2_inside_rect2(41, 25, 3, 5); + gfx::Rect arbitrary_rect3(7, -53, 22, 19); + gfx::Rect arbitrary_rect1_inside_rect3(10, -40, 6, 3); + gfx::Rect arbitrary_rect2_inside_rect3(12, -51, 5, 12); + gfx::Size arbitrary_size1(15, 19); + gfx::Size arbitrary_size2(3, 99); + gfx::Size arbitrary_size3(75, 1281); + gfx::RectF arbitrary_rectf1(4.2f, -922.1f, 15.6f, 29.5f); + gfx::RectF arbitrary_rectf2(2.1f, -411.05f, 7.8f, 14.75f); + gfx::SizeF arbitrary_sizef1(15.2f, 104.6f); + gfx::PointF arbitrary_pointf1(31.4f, 15.9f); + gfx::PointF arbitrary_pointf2(26.5f, -35.8f); + gfx::Vector2dF arbitrary_vector2df1(16.2f, -85.1f); + gfx::Vector2dF arbitrary_vector2df2(-8.3f, 0.47f); + float arbitrary_float1 = 0.7f; + float arbitrary_float2 = 0.3f; + float arbitrary_float3 = 0.9f; + float arbitrary_float_array[4] = {3.5f, 6.2f, 9.3f, 12.3f}; + bool arbitrary_bool1 = true; + bool arbitrary_bool2 = false; + bool arbitrary_bool3 = true; + bool arbitrary_bool4 = true; + bool arbitrary_bool5 = false; + bool arbitrary_bool6 = true; + int arbitrary_context_id1 = 12; + int arbitrary_context_id2 = 57; + int arbitrary_context_id3 = -503; + int arbitrary_int = 5; + SkColor arbitrary_color = SkColorSetARGB(25, 36, 47, 58); + SkXfermode::Mode arbitrary_blend_mode1 = SkXfermode::kScreen_Mode; + SkXfermode::Mode arbitrary_blend_mode2 = SkXfermode::kLighten_Mode; + SkXfermode::Mode arbitrary_blend_mode3 = SkXfermode::kOverlay_Mode; + ResourceId arbitrary_resourceid1 = 55; + ResourceId arbitrary_resourceid2 = 47; + ResourceId arbitrary_resourceid3 = 23; + ResourceId arbitrary_resourceid4 = 16; + SkScalar arbitrary_sigma = SkFloatToScalar(2.0f); + YUVVideoDrawQuad::ColorSpace arbitrary_color_space = + YUVVideoDrawQuad::REC_601; + + RenderPassId child_id(30, 5); + RenderPassId root_id(10, 14); + + FilterOperations arbitrary_filters1; + arbitrary_filters1.Append( + FilterOperation::CreateGrayscaleFilter(arbitrary_float1)); + arbitrary_filters1.Append(cc::FilterOperation::CreateReferenceFilter( + SkBlurImageFilter::Make(arbitrary_sigma, arbitrary_sigma, nullptr))); + + FilterOperations arbitrary_filters2; + arbitrary_filters2.Append( + FilterOperation::CreateBrightnessFilter(arbitrary_float2)); + + std::unique_ptr<RenderPass> child_pass_in = RenderPass::Create(); + child_pass_in->SetAll(child_id, arbitrary_rect2, arbitrary_rect3, + arbitrary_matrix2, arbitrary_bool2); + + std::unique_ptr<RenderPass> child_pass_cmp = RenderPass::Create(); + child_pass_cmp->SetAll(child_id, arbitrary_rect2, arbitrary_rect3, + arbitrary_matrix2, arbitrary_bool2); + + std::unique_ptr<RenderPass> pass_in = RenderPass::Create(); + pass_in->SetAll(root_id, arbitrary_rect1, arbitrary_rect2, arbitrary_matrix1, + arbitrary_bool1); + + SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state1_in->SetAll(arbitrary_matrix1, arbitrary_size1, arbitrary_rect1, + arbitrary_rect2, arbitrary_bool1, arbitrary_float1, + arbitrary_blend_mode1, arbitrary_context_id1); + + std::unique_ptr<RenderPass> pass_cmp = RenderPass::Create(); + pass_cmp->SetAll(root_id, arbitrary_rect1, arbitrary_rect2, arbitrary_matrix1, + arbitrary_bool1); + + SharedQuadState* shared_state1_cmp = + pass_cmp->CreateAndAppendSharedQuadState(); + shared_state1_cmp->CopyFrom(shared_state1_in); + + DebugBorderDrawQuad* debugborder_in = + pass_in->CreateAndAppendDrawQuad<DebugBorderDrawQuad>(); + debugborder_in->SetAll(shared_state1_in, arbitrary_rect3, + arbitrary_rect1_inside_rect3, + arbitrary_rect2_inside_rect3, arbitrary_bool1, + arbitrary_color, arbitrary_int); + pass_cmp->CopyFromAndAppendDrawQuad(debugborder_in, + debugborder_in->shared_quad_state); + + SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state2_in->SetAll(arbitrary_matrix2, arbitrary_size2, arbitrary_rect2, + arbitrary_rect3, arbitrary_bool1, arbitrary_float2, + arbitrary_blend_mode2, arbitrary_context_id2); + SharedQuadState* shared_state2_cmp = + pass_cmp->CreateAndAppendSharedQuadState(); + shared_state2_cmp->CopyFrom(shared_state2_in); + + RenderPassDrawQuad* renderpass_in = + pass_in->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + renderpass_in->SetAll( + shared_state2_in, arbitrary_rect1, arbitrary_rect2_inside_rect1, + arbitrary_rect1_inside_rect1, arbitrary_bool1, child_id, + arbitrary_resourceid2, arbitrary_vector2df1, arbitrary_size1, + arbitrary_filters1, arbitrary_vector2df2, arbitrary_filters2); + pass_cmp->CopyFromAndAppendRenderPassDrawQuad( + renderpass_in, renderpass_in->shared_quad_state, + renderpass_in->render_pass_id); + + SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state3_in->SetAll(arbitrary_matrix1, arbitrary_size3, arbitrary_rect3, + arbitrary_rect1, arbitrary_bool1, arbitrary_float3, + arbitrary_blend_mode3, arbitrary_context_id3); + SharedQuadState* shared_state3_cmp = + pass_cmp->CreateAndAppendSharedQuadState(); + shared_state3_cmp->CopyFrom(shared_state3_in); + + SolidColorDrawQuad* solidcolor_in = + pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + solidcolor_in->SetAll(shared_state3_in, arbitrary_rect3, + arbitrary_rect1_inside_rect3, + arbitrary_rect2_inside_rect3, arbitrary_bool1, + arbitrary_color, arbitrary_bool2); + pass_cmp->CopyFromAndAppendDrawQuad(solidcolor_in, + solidcolor_in->shared_quad_state); + + StreamVideoDrawQuad* streamvideo_in = + pass_in->CreateAndAppendDrawQuad<StreamVideoDrawQuad>(); + streamvideo_in->SetAll( + shared_state3_in, arbitrary_rect2, arbitrary_rect2_inside_rect2, + arbitrary_rect1_inside_rect2, arbitrary_bool1, arbitrary_resourceid2, + arbitrary_size1, arbitrary_matrix1); + pass_cmp->CopyFromAndAppendDrawQuad(streamvideo_in, + streamvideo_in->shared_quad_state); + + cc::SurfaceId arbitrary_surface_id(3); + SurfaceDrawQuad* surface_in = + pass_in->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); + surface_in->SetAll(shared_state3_in, arbitrary_rect2, + arbitrary_rect2_inside_rect2, arbitrary_rect1_inside_rect2, + arbitrary_bool1, arbitrary_surface_id); + pass_cmp->CopyFromAndAppendDrawQuad(surface_in, + surface_in->shared_quad_state); + + TextureDrawQuad* texture_in = + pass_in->CreateAndAppendDrawQuad<TextureDrawQuad>(); + texture_in->SetAll(shared_state3_in, arbitrary_rect2, + arbitrary_rect2_inside_rect2, arbitrary_rect1_inside_rect2, + arbitrary_bool1, arbitrary_resourceid1, arbitrary_size1, + arbitrary_bool2, arbitrary_pointf1, arbitrary_pointf2, + arbitrary_color, arbitrary_float_array, arbitrary_bool4, + arbitrary_bool5, arbitrary_bool6); + pass_cmp->CopyFromAndAppendDrawQuad(texture_in, + texture_in->shared_quad_state); + + TileDrawQuad* tile_in = pass_in->CreateAndAppendDrawQuad<TileDrawQuad>(); + tile_in->SetAll(shared_state3_in, arbitrary_rect2, + arbitrary_rect2_inside_rect2, arbitrary_rect1_inside_rect2, + arbitrary_bool1, arbitrary_resourceid3, arbitrary_rectf1, + arbitrary_size1, arbitrary_bool2, arbitrary_bool3); + pass_cmp->CopyFromAndAppendDrawQuad(tile_in, tile_in->shared_quad_state); + + YUVVideoDrawQuad* yuvvideo_in = + pass_in->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); + yuvvideo_in->SetAll( + shared_state3_in, arbitrary_rect1, arbitrary_rect2_inside_rect1, + arbitrary_rect1_inside_rect1, arbitrary_bool1, arbitrary_rectf1, + arbitrary_rectf2, arbitrary_size1, arbitrary_size2, arbitrary_resourceid1, + arbitrary_resourceid2, arbitrary_resourceid3, arbitrary_resourceid4, + arbitrary_color_space, arbitrary_float1, arbitrary_float2); + pass_cmp->CopyFromAndAppendDrawQuad(yuvvideo_in, + yuvvideo_in->shared_quad_state); + + // Make sure the in and cmp RenderPasses match. + Compare(child_pass_cmp.get(), child_pass_in.get()); + ASSERT_EQ(0u, child_pass_in->shared_quad_state_list.size()); + ASSERT_EQ(0u, child_pass_in->quad_list.size()); + Compare(pass_cmp.get(), pass_in.get()); + ASSERT_EQ(3u, pass_in->shared_quad_state_list.size()); + ASSERT_EQ(8u, pass_in->quad_list.size()); + for (cc::SharedQuadStateList::ConstIterator + cmp_iterator = pass_cmp->shared_quad_state_list.begin(), + in_iterator = pass_in->shared_quad_state_list.begin(); + in_iterator != pass_in->shared_quad_state_list.end(); + ++cmp_iterator, ++in_iterator) { + Compare(*cmp_iterator, *in_iterator); + } + for (auto in_iter = pass_in->quad_list.cbegin(), + cmp_iter = pass_cmp->quad_list.cbegin(); + in_iter != pass_in->quad_list.cend(); ++in_iter, ++cmp_iter) + Compare(*cmp_iter, *in_iter); + + for (size_t i = 1; i < pass_in->quad_list.size(); ++i) { + bool same_shared_quad_state_cmp = + pass_cmp->quad_list.ElementAt(i)->shared_quad_state == + pass_cmp->quad_list.ElementAt(i - 1)->shared_quad_state; + bool same_shared_quad_state_in = + pass_in->quad_list.ElementAt(i)->shared_quad_state == + pass_in->quad_list.ElementAt(i - 1)->shared_quad_state; + EXPECT_EQ(same_shared_quad_state_cmp, same_shared_quad_state_in); + } + + DelegatedFrameData frame_in; + frame_in.render_pass_list.push_back(std::move(child_pass_in)); + frame_in.render_pass_list.push_back(std::move(pass_in)); + + IPC::ParamTraits<DelegatedFrameData>::Write(&msg, frame_in); + + DelegatedFrameData frame_out; + base::PickleIterator iter(msg); + EXPECT_TRUE( + IPC::ParamTraits<DelegatedFrameData>::Read(&msg, &iter, &frame_out)); + + // Make sure the out and cmp RenderPasses match. + std::unique_ptr<RenderPass> child_pass_out = + std::move(frame_out.render_pass_list[0]); + Compare(child_pass_cmp.get(), child_pass_out.get()); + ASSERT_EQ(0u, child_pass_out->shared_quad_state_list.size()); + ASSERT_EQ(0u, child_pass_out->quad_list.size()); + std::unique_ptr<RenderPass> pass_out = + std::move(frame_out.render_pass_list[1]); + Compare(pass_cmp.get(), pass_out.get()); + ASSERT_EQ(3u, pass_out->shared_quad_state_list.size()); + ASSERT_EQ(8u, pass_out->quad_list.size()); + for (cc::SharedQuadStateList::ConstIterator + cmp_iterator = pass_cmp->shared_quad_state_list.begin(), + out_iterator = pass_out->shared_quad_state_list.begin(); + out_iterator != pass_out->shared_quad_state_list.end(); + ++cmp_iterator, ++out_iterator) { + Compare(*cmp_iterator, *out_iterator); + } + for (auto out_iter = pass_out->quad_list.cbegin(), + cmp_iter = pass_cmp->quad_list.cbegin(); + out_iter != pass_out->quad_list.cend(); ++out_iter, ++cmp_iter) + Compare(*cmp_iter, *out_iter); + + for (size_t i = 1; i < pass_out->quad_list.size(); ++i) { + bool same_shared_quad_state_cmp = + pass_cmp->quad_list.ElementAt(i)->shared_quad_state == + pass_cmp->quad_list.ElementAt(i - 1)->shared_quad_state; + bool same_shared_quad_state_out = + pass_out->quad_list.ElementAt(i)->shared_quad_state == + pass_out->quad_list.ElementAt(i - 1)->shared_quad_state; + EXPECT_EQ(same_shared_quad_state_cmp, same_shared_quad_state_out); + } +} + +TEST_F(CCParamTraitsTest, UnusedSharedQuadStates) { + std::unique_ptr<RenderPass> pass_in = RenderPass::Create(); + pass_in->SetAll(RenderPassId(1, 1), gfx::Rect(100, 100), gfx::Rect(), + gfx::Transform(), false); + + // The first SharedQuadState is used. + SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state1_in->SetAll(gfx::Transform(), gfx::Size(1, 1), gfx::Rect(), + gfx::Rect(), false, 1.f, SkXfermode::kSrcOver_Mode, + 0); + + SolidColorDrawQuad* quad1 = + pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + quad1->SetAll(shared_state1_in, gfx::Rect(10, 10), gfx::Rect(10, 10), + gfx::Rect(10, 10), false, SK_ColorRED, false); + + // The second and third SharedQuadStates are not used. + SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state2_in->SetAll(gfx::Transform(), gfx::Size(2, 2), gfx::Rect(), + gfx::Rect(), false, 1.f, SkXfermode::kSrcOver_Mode, + 0); + + SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state3_in->SetAll(gfx::Transform(), gfx::Size(3, 3), gfx::Rect(), + gfx::Rect(), false, 1.f, SkXfermode::kSrcOver_Mode, + 0); + + // The fourth SharedQuadState is used. + SharedQuadState* shared_state4_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state4_in->SetAll(gfx::Transform(), gfx::Size(4, 4), gfx::Rect(), + gfx::Rect(), false, 1.f, SkXfermode::kSrcOver_Mode, + 0); + + SolidColorDrawQuad* quad2 = + pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + quad2->SetAll(shared_state4_in, gfx::Rect(10, 10), gfx::Rect(10, 10), + gfx::Rect(10, 10), false, SK_ColorRED, false); + + // The fifth is not used again. + SharedQuadState* shared_state5_in = pass_in->CreateAndAppendSharedQuadState(); + shared_state5_in->SetAll(gfx::Transform(), gfx::Size(5, 5), gfx::Rect(), + gfx::Rect(), false, 1.f, SkXfermode::kSrcOver_Mode, + 0); + + // 5 SharedQuadStates go in. + ASSERT_EQ(5u, pass_in->shared_quad_state_list.size()); + ASSERT_EQ(2u, pass_in->quad_list.size()); + + DelegatedFrameData frame_in; + frame_in.render_pass_list.push_back(std::move(pass_in)); + + IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); + IPC::ParamTraits<DelegatedFrameData>::Write(&msg, frame_in); + + DelegatedFrameData frame_out; + base::PickleIterator iter(msg); + EXPECT_TRUE( + IPC::ParamTraits<DelegatedFrameData>::Read(&msg, &iter, &frame_out)); + + std::unique_ptr<RenderPass> pass_out = + std::move(frame_out.render_pass_list[0]); + + // 2 SharedQuadStates come out. The first and fourth SharedQuadStates were + // used by quads, and so serialized. Others were not. + ASSERT_EQ(2u, pass_out->shared_quad_state_list.size()); + ASSERT_EQ(2u, pass_out->quad_list.size()); + + EXPECT_EQ(gfx::Size(1, 1).ToString(), + pass_out->shared_quad_state_list.ElementAt(0) + ->quad_layer_bounds.ToString()); + EXPECT_EQ(gfx::Size(4, 4).ToString(), + pass_out->shared_quad_state_list.ElementAt(1) + ->quad_layer_bounds.ToString()); +} + +TEST_F(CCParamTraitsTest, Resources) { + IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); + gfx::Size arbitrary_size(757, 1281); + gpu::SyncToken arbitrary_token1(gpu::CommandBufferNamespace::GPU_IO, 0, + gpu::CommandBufferId::FromUnsafeValue(0x123), + 71234838); + arbitrary_token1.SetVerifyFlush(); + gpu::SyncToken arbitrary_token2(gpu::CommandBufferNamespace::GPU_IO, 0, + gpu::CommandBufferId::FromUnsafeValue(0x123), + 53589793); + arbitrary_token2.SetVerifyFlush(); + + GLbyte arbitrary_mailbox1[GL_MAILBOX_SIZE_CHROMIUM] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4}; + + GLbyte arbitrary_mailbox2[GL_MAILBOX_SIZE_CHROMIUM] = { + 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, + 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7, + 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7}; + + TransferableResource arbitrary_resource1; + arbitrary_resource1.id = 2178312; + arbitrary_resource1.format = cc::RGBA_8888; + arbitrary_resource1.filter = 53; + arbitrary_resource1.size = gfx::Size(37189, 123123); + arbitrary_resource1.mailbox_holder.mailbox.SetName(arbitrary_mailbox1); + arbitrary_resource1.mailbox_holder.texture_target = GL_TEXTURE_2D; + arbitrary_resource1.mailbox_holder.sync_token = arbitrary_token1; + arbitrary_resource1.is_overlay_candidate = true; + + TransferableResource arbitrary_resource2; + arbitrary_resource2.id = 789132; + arbitrary_resource2.format = cc::RGBA_4444; + arbitrary_resource2.filter = 47; + arbitrary_resource2.size = gfx::Size(89123, 23789); + arbitrary_resource2.mailbox_holder.mailbox.SetName(arbitrary_mailbox2); + arbitrary_resource2.mailbox_holder.texture_target = GL_TEXTURE_EXTERNAL_OES; + arbitrary_resource2.mailbox_holder.sync_token = arbitrary_token2; + arbitrary_resource2.is_overlay_candidate = false; + + std::unique_ptr<RenderPass> renderpass_in = RenderPass::Create(); + renderpass_in->SetNew(RenderPassId(1, 1), gfx::Rect(), gfx::Rect(), + gfx::Transform()); + + DelegatedFrameData frame_in; + frame_in.resource_list.push_back(arbitrary_resource1); + frame_in.resource_list.push_back(arbitrary_resource2); + frame_in.render_pass_list.push_back(std::move(renderpass_in)); + + IPC::ParamTraits<DelegatedFrameData>::Write(&msg, frame_in); + + DelegatedFrameData frame_out; + base::PickleIterator iter(msg); + EXPECT_TRUE( + IPC::ParamTraits<DelegatedFrameData>::Read(&msg, &iter, &frame_out)); + + ASSERT_EQ(2u, frame_out.resource_list.size()); + Compare(arbitrary_resource1, frame_out.resource_list[0]); + Compare(arbitrary_resource2, frame_out.resource_list[1]); +} + +} // namespace +} // namespace content diff --git a/chromium/cc/layers/draw_properties.cc b/chromium/cc/layers/draw_properties.cc index c87fece7774..718295f082f 100644 --- a/chromium/cc/layers/draw_properties.cc +++ b/chromium/cc/layers/draw_properties.cc @@ -11,9 +11,6 @@ DrawProperties::DrawProperties() screen_space_transform_is_animating(false), can_use_lcd_text(false), is_clipped(false), - render_target(nullptr), - num_unclipped_descendants(0), - last_drawn_render_surface_layer_list_id(0), maximum_animation_contents_scale(0.f), starting_animation_contents_scale(0.f) {} diff --git a/chromium/cc/layers/draw_properties.h b/chromium/cc/layers/draw_properties.h index 2f3ce5d5012..071c853b2b9 100644 --- a/chromium/cc/layers/draw_properties.h +++ b/chromium/cc/layers/draw_properties.h @@ -7,14 +7,13 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/trees/occlusion.h" -#include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/transform.h" namespace cc { -class LayerImpl; // Container for properties that layers need to compute before they can be // drawn. @@ -49,11 +48,6 @@ struct CC_EXPORT DrawProperties { // True if the layer needs to be clipped by clip_rect. bool is_clipped; - // The layer whose coordinate space this layer draws into. This can be - // either the same layer (draw_properties_.render_target == this) or an - // ancestor of this layer. - LayerImpl* render_target; - // 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; @@ -66,19 +60,6 @@ struct CC_EXPORT DrawProperties { // value is used to avoid unnecessarily changing GL scissor state. gfx::Rect clip_rect; - // 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. - size_t num_unclipped_descendants; - - // Each time we generate a new render surface layer list, an ID is used to - // identify it. |last_drawn_render_surface_layer_list_id| is set to the ID - // that marked the render surface layer list generation which last updated - // these draw properties and determined that this layer will draw itself. - // If these draw properties are not a part of the render surface layer list, - // or the layer doesn't contribute anything, then this ID will be either out - // of date or 0. - int last_drawn_render_surface_layer_list_id; - // The maximum scale during the layers current animation at which content // should be rastered at to be crisp. float maximum_animation_contents_scale; diff --git a/chromium/cc/layers/empty_content_layer_client.h b/chromium/cc/layers/empty_content_layer_client.h index 2554b8afbc6..0d831b6e6d6 100644 --- a/chromium/cc/layers/empty_content_layer_client.h +++ b/chromium/cc/layers/empty_content_layer_client.h @@ -5,9 +5,10 @@ #ifndef CC_LAYERS_EMPTY_CONTENT_LAYER_CLIENT_H_ #define CC_LAYERS_EMPTY_CONTENT_LAYER_CLIENT_H_ +#include <memory> + #include "base/lazy_instance.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/layers/content_layer_client.h" #include "ui/gfx/geometry/rect.h" diff --git a/chromium/cc/layers/heads_up_display_layer.cc b/chromium/cc/layers/heads_up_display_layer.cc index 8d581dc4d8b..26344ff5919 100644 --- a/chromium/cc/layers/heads_up_display_layer.cc +++ b/chromium/cc/layers/heads_up_display_layer.cc @@ -18,10 +18,10 @@ scoped_refptr<HeadsUpDisplayLayer> HeadsUpDisplayLayer::Create() { } HeadsUpDisplayLayer::HeadsUpDisplayLayer() - : typeface_(skia::AdoptRef( - SkTypeface::CreateFromName("times new roman", SkTypeface::kNormal))) { + : typeface_( + SkTypeface::CreateFromName("times new roman", SkTypeface::kNormal)) { if (!typeface_) { - typeface_ = skia::AdoptRef( + typeface_ = sk_sp<SkTypeface>( SkTypeface::CreateFromName("monospace", SkTypeface::kBold)); } DCHECK(typeface_.get()); @@ -62,7 +62,7 @@ bool HeadsUpDisplayLayer::HasDrawableContent() const { return true; } -scoped_ptr<LayerImpl> HeadsUpDisplayLayer::CreateLayerImpl( +std::unique_ptr<LayerImpl> HeadsUpDisplayLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return HeadsUpDisplayLayerImpl::Create(tree_impl, layer_id_); } diff --git a/chromium/cc/layers/heads_up_display_layer.h b/chromium/cc/layers/heads_up_display_layer.h index 5d416c26866..da8f05a0bc5 100644 --- a/chromium/cc/layers/heads_up_display_layer.h +++ b/chromium/cc/layers/heads_up_display_layer.h @@ -5,12 +5,13 @@ #ifndef CC_LAYERS_HEADS_UP_DISPLAY_LAYER_H_ #define CC_LAYERS_HEADS_UP_DISPLAY_LAYER_H_ +#include <memory> #include <string> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/layers/layer.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkTypeface.h" namespace cc { @@ -26,7 +27,7 @@ class CC_EXPORT HeadsUpDisplayLayer : public Layer { void PrepareForCalculateDrawProperties( const gfx::Size& device_viewport, float device_scale_factor); - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void SetTypeForProtoSerialization(proto::LayerNode* proto) const override; @@ -40,7 +41,7 @@ class CC_EXPORT HeadsUpDisplayLayer : public Layer { private: ~HeadsUpDisplayLayer() override; - skia::RefPtr<SkTypeface> typeface_; + sk_sp<SkTypeface> typeface_; DISALLOW_COPY_AND_ASSIGN(HeadsUpDisplayLayer); }; diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc index 610be60ebb0..1b62f084770 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl.cc +++ b/chromium/cc/layers/heads_up_display_layer_impl.cc @@ -80,7 +80,7 @@ HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* tree_impl, HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() {} -scoped_ptr<LayerImpl> HeadsUpDisplayLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> HeadsUpDisplayLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return HeadsUpDisplayLayerImpl::Create(tree_impl, id()); } @@ -94,7 +94,7 @@ void HeadsUpDisplayLayerImpl::AcquireResource( } } - scoped_ptr<ScopedResource> resource = + std::unique_ptr<ScopedResource> resource = ScopedResource::Create(resource_provider); resource->Allocate(internal_content_bounds_, ResourceProvider::TEXTURE_HINT_IMMUTABLE, @@ -106,7 +106,7 @@ void HeadsUpDisplayLayerImpl::ReleaseUnmatchedSizeResources( ResourceProvider* resource_provider) { auto it_erase = std::remove_if(resources_.begin(), resources_.end(), - [this](const scoped_ptr<ScopedResource>& resource) { + [this](const std::unique_ptr<ScopedResource>& resource) { return internal_content_bounds_ != resource->size(); }); resources_.erase(it_erase, resources_.end()); @@ -147,18 +147,10 @@ void HeadsUpDisplayLayerImpl::AppendQuads( bool nearest_neighbor = false; TextureDrawQuad* quad = render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); - quad->SetNew(shared_quad_state, - quad_rect, - opaque_rect, - visible_quad_rect, - resources_.back()->id(), - premultiplied_alpha, - uv_top_left, - uv_bottom_right, - SK_ColorTRANSPARENT, - vertex_opacity, - flipped, - nearest_neighbor); + quad->SetNew(shared_quad_state, quad_rect, opaque_rect, visible_quad_rect, + resources_.back()->id(), premultiplied_alpha, uv_top_left, + uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, flipped, + nearest_neighbor, false); ValidateQuadResources(quad); } @@ -198,13 +190,12 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture( } TRACE_EVENT0("cc", "UploadHudTexture"); - SkImageInfo info; - size_t row_bytes = 0; - const void* pixels = hud_surface_->peekPixels(&info, &row_bytes); - DCHECK(pixels); - DCHECK(info.colorType() == kN32_SkColorType); + SkPixmap pixmap; + hud_surface_->peekPixels(&pixmap); + DCHECK(pixmap.addr()); + DCHECK(pixmap.info().colorType() == kN32_SkColorType); resource_provider->CopyToResource(resources_.back()->id(), - static_cast<const uint8_t*>(pixels), + static_cast<const uint8_t*>(pixmap.addr()), internal_content_bounds_); resource_provider->GenerateSyncTokenForResource(resources_.back()->id()); } @@ -218,13 +209,12 @@ gfx::Rect HeadsUpDisplayLayerImpl::GetEnclosingRectInTargetSpace() const { return GetScaledEnclosingRectInTargetSpace(internal_contents_scale_); } -void HeadsUpDisplayLayerImpl::SetHUDTypeface( - const skia::RefPtr<SkTypeface>& typeface) { +void HeadsUpDisplayLayerImpl::SetHUDTypeface(sk_sp<SkTypeface> typeface) { if (typeface_ == typeface) return; DCHECK(typeface_.get() == nullptr); - typeface_ = typeface; + typeface_ = std::move(typeface); NoteLayerPropertyChanged(); } @@ -292,7 +282,7 @@ int HeadsUpDisplayLayerImpl::MeasureText(SkPaint* paint, const bool anti_alias = paint->isAntiAlias(); paint->setAntiAlias(true); paint->setTextSize(size); - paint->setTypeface(typeface_.get()); + paint->setTypeface(typeface_); SkScalar text_width = paint->measureText(text.c_str(), text.length()); paint->setAntiAlias(anti_alias); @@ -311,7 +301,7 @@ void HeadsUpDisplayLayerImpl::DrawText(SkCanvas* canvas, paint->setTextSize(size); paint->setTextAlign(align); - paint->setTypeface(typeface_.get()); + paint->setTypeface(typeface_); canvas->drawText(text.c_str(), text.length(), x, y, *paint); paint->setAntiAlias(anti_alias); @@ -686,7 +676,7 @@ void HeadsUpDisplayLayerImpl::DrawDebugRect( SkPaint label_paint = CreatePaint(); label_paint.setTextSize(kFontHeight); - label_paint.setTypeface(typeface_.get()); + label_paint.setTypeface(typeface_); label_paint.setColor(stroke_color); const SkScalar label_text_width = diff --git a/chromium/cc/layers/heads_up_display_layer_impl.h b/chromium/cc/layers/heads_up_display_layer_impl.h index b97eb141027..174d1bfda7e 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl.h +++ b/chromium/cc/layers/heads_up_display_layer_impl.h @@ -5,17 +5,19 @@ #ifndef CC_LAYERS_HEADS_UP_DISPLAY_LAYER_IMPL_H_ #define CC_LAYERS_HEADS_UP_DISPLAY_LAYER_IMPL_H_ +#include <memory> #include <string> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/debug/debug_rect_history.h" #include "cc/layers/layer_impl.h" #include "cc/resources/memory_history.h" #include "cc/resources/scoped_resource.h" +#include "third_party/skia/include/core/SkRefCnt.h" class SkCanvas; class SkPaint; @@ -29,13 +31,14 @@ class PaintTimeCounter; class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl { public: - static scoped_ptr<HeadsUpDisplayLayerImpl> Create(LayerTreeImpl* tree_impl, - int id) { - return make_scoped_ptr(new HeadsUpDisplayLayerImpl(tree_impl, id)); + static std::unique_ptr<HeadsUpDisplayLayerImpl> Create( + LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new HeadsUpDisplayLayerImpl(tree_impl, id)); } ~HeadsUpDisplayLayerImpl() override; - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; bool WillDraw(DrawMode draw_mode, ResourceProvider* resource_provider) override; @@ -50,7 +53,7 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl { bool IsAnimatingHUDContents() const { return fade_step_ > 0; } - void SetHUDTypeface(const skia::RefPtr<SkTypeface>& typeface); + void SetHUDTypeface(sk_sp<SkTypeface> typeface); // LayerImpl overrides. void PushPropertiesTo(LayerImpl* layer) override; @@ -129,10 +132,10 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl { void AcquireResource(ResourceProvider* resource_provider); void ReleaseUnmatchedSizeResources(ResourceProvider* resource_provider); - std::vector<scoped_ptr<ScopedResource>> resources_; + std::vector<std::unique_ptr<ScopedResource>> resources_; sk_sp<SkSurface> hud_surface_; - skia::RefPtr<SkTypeface> typeface_; + sk_sp<SkTypeface> typeface_; float internal_contents_scale_; gfx::Size internal_content_bounds_; 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 cb69b1b8f12..9f7649f9b0d 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc +++ b/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc @@ -20,7 +20,7 @@ namespace { void CheckDrawLayer(HeadsUpDisplayLayerImpl* layer, ResourceProvider* resource_provider, DrawMode draw_mode) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; bool will_draw = layer->WillDraw(draw_mode, resource_provider); if (will_draw) @@ -37,13 +37,13 @@ TEST(HeadsUpDisplayLayerImplTest, ResourcelessSoftwareDrawAfterResourceLoss) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.CreatePendingTree(); host_impl.SetVisible(true); host_impl.InitializeRenderer(output_surface.get()); - scoped_ptr<HeadsUpDisplayLayerImpl> layer_ptr = + std::unique_ptr<HeadsUpDisplayLayerImpl> layer_ptr = HeadsUpDisplayLayerImpl::Create(host_impl.pending_tree(), 1); layer_ptr->SetBounds(gfx::Size(100, 100)); diff --git a/chromium/cc/layers/io_surface_layer.cc b/chromium/cc/layers/io_surface_layer.cc deleted file mode 100644 index 0934f1e0767..00000000000 --- a/chromium/cc/layers/io_surface_layer.cc +++ /dev/null @@ -1,53 +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/io_surface_layer.h" - -#include <stdint.h> - -#include "cc/layers/io_surface_layer_impl.h" - -namespace cc { - -scoped_refptr<IOSurfaceLayer> IOSurfaceLayer::Create() { - return make_scoped_refptr(new IOSurfaceLayer()); -} - -IOSurfaceLayer::IOSurfaceLayer() : io_surface_id_(0) {} - -IOSurfaceLayer::~IOSurfaceLayer() {} - -void IOSurfaceLayer::SetIOSurfaceProperties(uint32_t io_surface_id, - const gfx::Size& size) { - io_surface_id_ = io_surface_id; - io_surface_size_ = size; - UpdateDrawsContent(HasDrawableContent()); - SetNeedsCommit(); -} - -scoped_ptr<LayerImpl> IOSurfaceLayer::CreateLayerImpl( - LayerTreeImpl* tree_impl) { - return IOSurfaceLayerImpl::Create(tree_impl, layer_id_); -} - -bool IOSurfaceLayer::HasDrawableContent() const { - return io_surface_id_ && Layer::HasDrawableContent(); -} - -void IOSurfaceLayer::PushPropertiesTo(LayerImpl* layer) { - Layer::PushPropertiesTo(layer); - - IOSurfaceLayerImpl* io_surface_layer = - static_cast<IOSurfaceLayerImpl*>(layer); - io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); -} - -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(); -} - -} // namespace cc diff --git a/chromium/cc/layers/io_surface_layer.h b/chromium/cc/layers/io_surface_layer.h deleted file mode 100644 index c0883094f44..00000000000 --- a/chromium/cc/layers/io_surface_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_IO_SURFACE_LAYER_H_ -#define CC_LAYERS_IO_SURFACE_LAYER_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "cc/base/cc_export.h" -#include "cc/layers/layer.h" - -namespace cc { - -class CC_EXPORT IOSurfaceLayer : public Layer { - public: - static scoped_refptr<IOSurfaceLayer> Create(); - - 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() override; - - protected: - bool HasDrawableContent() const override; - IOSurfaceLayer(); - - private: - ~IOSurfaceLayer() override; - - uint32_t io_surface_id_; - gfx::Size io_surface_size_; - - DISALLOW_COPY_AND_ASSIGN(IOSurfaceLayer); -}; - -} // namespace cc -#endif // CC_LAYERS_IO_SURFACE_LAYER_H_ diff --git a/chromium/cc/layers/io_surface_layer_impl.cc b/chromium/cc/layers/io_surface_layer_impl.cc deleted file mode 100644 index d7c6cda1875..00000000000 --- a/chromium/cc/layers/io_surface_layer_impl.cc +++ /dev/null @@ -1,108 +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/io_surface_layer_impl.h" - -#include "base/strings/stringprintf.h" -#include "cc/output/output_surface.h" -#include "cc/quads/io_surface_draw_quad.h" -#include "cc/trees/layer_tree_impl.h" -#include "cc/trees/occlusion.h" - -namespace cc { - -IOSurfaceLayerImpl::IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id) - : LayerImpl(tree_impl, id), - io_surface_id_(0), - io_surface_changed_(false), - io_surface_resource_id_(0) {} - -IOSurfaceLayerImpl::~IOSurfaceLayerImpl() { - DestroyResource(); -} - -void IOSurfaceLayerImpl::DestroyResource() { - if (io_surface_resource_id_) { - ResourceProvider* resource_provider = - layer_tree_impl()->resource_provider(); - resource_provider->DeleteResource(io_surface_resource_id_); - io_surface_resource_id_ = 0; - } -} - -scoped_ptr<LayerImpl> IOSurfaceLayerImpl::CreateLayerImpl( - LayerTreeImpl* tree_impl) { - return IOSurfaceLayerImpl::Create(tree_impl, id()); -} - -void IOSurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) { - LayerImpl::PushPropertiesTo(layer); - - IOSurfaceLayerImpl* io_surface_layer = - static_cast<IOSurfaceLayerImpl*>(layer); - io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); -} - -bool IOSurfaceLayerImpl::WillDraw(DrawMode draw_mode, - ResourceProvider* resource_provider) { - if (draw_mode != DRAW_MODE_HARDWARE) - return false; - - if (io_surface_changed_) { - DestroyResource(); - io_surface_resource_id_ = resource_provider->CreateResourceFromIOSurface( - io_surface_size_, io_surface_id_); - io_surface_changed_ = false; - } - - return LayerImpl::WillDraw(draw_mode, resource_provider); -} - -void IOSurfaceLayerImpl::AppendQuads( - RenderPass* render_pass, - AppendQuadsData* append_quads_data) { - SharedQuadState* shared_quad_state = - render_pass->CreateAndAppendSharedQuadState(); - PopulateSharedQuadState(shared_quad_state); - - AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state, - append_quads_data); - - 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( - quad_rect); - if (visible_quad_rect.IsEmpty()) - return; - - IOSurfaceDrawQuad* quad = - render_pass->CreateAndAppendDrawQuad<IOSurfaceDrawQuad>(); - quad->SetNew(shared_quad_state, quad_rect, opaque_rect, visible_quad_rect, - io_surface_size_, io_surface_resource_id_, - IOSurfaceDrawQuad::FLIPPED); - ValidateQuadResources(quad); -} - -void IOSurfaceLayerImpl::ReleaseResources() { - // We don't have a valid resource ID in the new context; however, - // the IOSurface is still valid. - DestroyResource(); - io_surface_changed_ = true; -} - -void IOSurfaceLayerImpl::SetIOSurfaceProperties(unsigned io_surface_id, - const gfx::Size& size) { - if (io_surface_id_ != io_surface_id) - io_surface_changed_ = true; - - io_surface_id_ = io_surface_id; - io_surface_size_ = size; -} - -const char* IOSurfaceLayerImpl::LayerTypeAsString() const { - return "cc::IOSurfaceLayerImpl"; -} - -} // namespace cc diff --git a/chromium/cc/layers/io_surface_layer_impl.h b/chromium/cc/layers/io_surface_layer_impl.h deleted file mode 100644 index 29e9973ed42..00000000000 --- a/chromium/cc/layers/io_surface_layer_impl.h +++ /dev/null @@ -1,54 +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_IO_SURFACE_LAYER_IMPL_H_ -#define CC_LAYERS_IO_SURFACE_LAYER_IMPL_H_ - -#include <string> - -#include "base/macros.h" -#include "cc/base/cc_export.h" -#include "cc/layers/layer_impl.h" -#include "ui/gfx/geometry/size.h" - -namespace cc { - -class CC_EXPORT IOSurfaceLayerImpl : public LayerImpl { - public: - static scoped_ptr<IOSurfaceLayerImpl> Create(LayerTreeImpl* tree_impl, - int id) { - return make_scoped_ptr(new IOSurfaceLayerImpl(tree_impl, id)); - } - ~IOSurfaceLayerImpl() override; - - void SetIOSurfaceProperties(unsigned io_surface_id, const gfx::Size& size); - - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; - void PushPropertiesTo(LayerImpl* layer_tree_impl) override; - - void AppendQuads(RenderPass* render_pass, - AppendQuadsData* append_quads_data) override; - - bool WillDraw(DrawMode draw_mode, - ResourceProvider* resource_provider) override; - void ReleaseResources() override; - - private: - IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id); - - void DestroyResource(); - - const char* LayerTypeAsString() const override; - - unsigned io_surface_id_; - gfx::Size io_surface_size_; - bool io_surface_changed_; - unsigned io_surface_resource_id_; - - DISALLOW_COPY_AND_ASSIGN(IOSurfaceLayerImpl); -}; - -} // namespace cc - -#endif // CC_LAYERS_IO_SURFACE_LAYER_IMPL_H_ diff --git a/chromium/cc/layers/io_surface_layer_impl_unittest.cc b/chromium/cc/layers/io_surface_layer_impl_unittest.cc deleted file mode 100644 index ff3e79e0a18..00000000000 --- a/chromium/cc/layers/io_surface_layer_impl_unittest.cc +++ /dev/null @@ -1,66 +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/layers/io_surface_layer_impl.h" - -#include <stddef.h> - -#include "cc/test/layer_test_common.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -TEST(IOSurfaceLayerImplTest, Occlusion) { - gfx::Size layer_size(1000, 1000); - gfx::Size viewport_size(1000, 1000); - - LayerTestCommon::LayerImplTest impl; - - IOSurfaceLayerImpl* io_surface_layer_impl = - impl.AddChildToRoot<IOSurfaceLayerImpl>(); - io_surface_layer_impl->SetBounds(layer_size); - io_surface_layer_impl->SetDrawsContent(true); - - io_surface_layer_impl->SetIOSurfaceProperties(1, gfx::Size(1, 1)); - io_surface_layer_impl->WillDraw(DRAW_MODE_HARDWARE, impl.resource_provider()); - io_surface_layer_impl->DidDraw(impl.resource_provider()); - - impl.CalcDrawProps(viewport_size); - - { - SCOPED_TRACE("No occlusion"); - gfx::Rect occluded; - impl.AppendQuadsWithOcclusion(io_surface_layer_impl, occluded); - - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); - EXPECT_EQ(1u, impl.quad_list().size()); - } - - { - SCOPED_TRACE("Full occlusion"); - gfx::Rect occluded(io_surface_layer_impl->visible_layer_rect()); - impl.AppendQuadsWithOcclusion(io_surface_layer_impl, occluded); - - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); - EXPECT_EQ(impl.quad_list().size(), 0u); - } - - { - SCOPED_TRACE("Partial occlusion"); - gfx::Rect occluded(200, 0, 800, 1000); - impl.AppendQuadsWithOcclusion(io_surface_layer_impl, 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(1u, impl.quad_list().size()); - EXPECT_EQ(1u, partially_occluded_count); - } -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc index 94155248e1d..006c8efe964 100644 --- a/chromium/cc/layers/layer.cc +++ b/chromium/cc/layers/layer.cc @@ -77,10 +77,9 @@ Layer::Layer() use_parent_backface_visibility_(false), use_local_transform_for_backface_visibility_(false), should_check_backface_visibility_(false), - force_render_surface_(false), - transform_is_invertible_(true), - has_render_surface_(false), + force_render_surface_for_testing_(false), subtree_property_changed_(false), + has_will_change_transform_hint_(false), background_color_(0), safe_opaque_background_color_(0), opacity_(1.f), @@ -90,8 +89,7 @@ Layer::Layer() clip_parent_(nullptr), replica_layer_(nullptr), client_(nullptr), - num_unclipped_descendants_(0), - frame_timing_requests_dirty_(false) {} + num_unclipped_descendants_(0) {} Layer::~Layer() { // Our parent should be holding a reference to us so there should be no @@ -351,14 +349,14 @@ bool Layer::HasAncestor(const Layer* ancestor) const { return false; } -void Layer::RequestCopyOfOutput( - scoped_ptr<CopyOutputRequest> request) { +void Layer::RequestCopyOfOutput(std::unique_ptr<CopyOutputRequest> request) { DCHECK(IsPropertyChangeAllowed()); if (void* source = request->source()) { - auto it = std::find_if(copy_requests_.begin(), copy_requests_.end(), - [source](const scoped_ptr<CopyOutputRequest>& x) { - return x->source() == source; - }); + auto it = + std::find_if(copy_requests_.begin(), copy_requests_.end(), + [source](const std::unique_ptr<CopyOutputRequest>& x) { + return x->source() == source; + }); if (it != copy_requests_.end()) copy_requests_.erase(it); } @@ -470,8 +468,24 @@ void Layer::SetOpacity(float opacity) { DCHECK(IsPropertyChangeAllowed()); if (opacity_ == opacity) return; + // We need to force a property tree rebuild when opacity changes from 1 to a + // non-1 value or vice-versa as render surfaces can change. + bool force_rebuild = opacity == 1.f || opacity_ == 1.f; opacity_ = opacity; SetSubtreePropertyChanged(); + if (layer_tree_host_ && !force_rebuild) { + PropertyTrees* property_trees = layer_tree_host_->property_trees(); + auto effect_id_to_index = property_trees->effect_id_to_index_map.find(id()); + if (effect_id_to_index != property_trees->effect_id_to_index_map.end()) { + EffectNode* node = + property_trees->effect_tree.Node(effect_id_to_index->second); + node->data.opacity = opacity; + node->data.effect_changed = true; + property_trees->effect_tree.set_needs_update(true); + SetNeedsCommitNoRebuild(); + return; + } + } SetNeedsCommit(); } @@ -492,6 +506,10 @@ bool Layer::OpacityCanAnimateOnImplThread() const { return false; } +bool Layer::AlwaysUseActiveTreeOpacity() const { + return false; +} + void Layer::SetBlendMode(SkXfermode::Mode blend_mode) { DCHECK(IsPropertyChangeAllowed()); if (blend_mode_ == blend_mode) @@ -594,19 +612,19 @@ bool Layer::IsContainerForFixedPositionLayers() const { return is_container_for_fixed_position_layers_; } -bool Are2dAxisAligned(const gfx::Transform& a, - const gfx::Transform& b, - bool* is_invertible) { +bool Are2dAxisAligned(const gfx::Transform& a, const gfx::Transform& b) { if (a.IsScaleOrTranslation() && b.IsScaleOrTranslation()) { - *is_invertible = b.IsInvertible(); return true; } gfx::Transform inverse(gfx::Transform::kSkipInitialization); - *is_invertible = b.GetInverse(&inverse); - - inverse *= a; - return inverse.Preserves2dAxisAlignment(); + if (b.GetInverse(&inverse)) { + inverse *= a; + return inverse.Preserves2dAxisAlignment(); + } else { + // TODO(weiliangc): Should return false because b is not invertible. + return a.Preserves2dAxisAlignment(); + } } void Layer::SetTransform(const gfx::Transform& transform) { @@ -623,9 +641,8 @@ void Layer::SetTransform(const gfx::Transform& transform) { // We need to trigger a rebuild if we could have affected 2d axis // alignment. We'll check to see if transform and transform_ are axis // align with respect to one another. - bool invertible = false; bool preserves_2d_axis_alignment = - Are2dAxisAligned(transform_, transform, &invertible); + Are2dAxisAligned(transform_, transform); transform_node->data.local = transform; transform_node->data.needs_local_transform_update = true; transform_node->data.transform_changed = true; @@ -636,14 +653,12 @@ void Layer::SetTransform(const gfx::Transform& transform) { else SetNeedsCommit(); transform_ = transform; - transform_is_invertible_ = invertible; return; } } } transform_ = transform; - transform_is_invertible_ = transform.IsInvertible(); SetNeedsCommit(); } @@ -903,11 +918,11 @@ void Layer::SetTouchEventHandlerRegion(const Region& region) { SetNeedsCommit(); } -void Layer::SetForceRenderSurface(bool force) { +void Layer::SetForceRenderSurfaceForTesting(bool force) { DCHECK(IsPropertyChangeAllowed()); - if (force_render_surface_ == force) + if (force_render_surface_for_testing_ == force) return; - force_render_surface_ = force; + force_render_surface_for_testing_ = force; SetNeedsCommit(); } @@ -1096,15 +1111,16 @@ void Layer::SetPositionConstraint(const LayerPositionConstraint& constraint) { SetNeedsCommit(); } -static void RunCopyCallbackOnMainThread(scoped_ptr<CopyOutputRequest> request, - scoped_ptr<CopyOutputResult> result) { +static void RunCopyCallbackOnMainThread( + std::unique_ptr<CopyOutputRequest> request, + std::unique_ptr<CopyOutputResult> result) { request->SendResult(std::move(result)); } static void PostCopyCallbackToMainThread( scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, - scoped_ptr<CopyOutputRequest> request, - scoped_ptr<CopyOutputResult> result) { + std::unique_ptr<CopyOutputRequest> request, + std::unique_ptr<CopyOutputResult> result) { main_thread_task_runner->PostTask(FROM_HERE, base::Bind(&RunCopyCallbackOnMainThread, base::Passed(&request), @@ -1120,7 +1136,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { bool use_paint_properties = paint_properties_.source_frame_number == layer_tree_host_->source_frame_number(); - layer->SetTransformOrigin(transform_origin_); layer->SetBackgroundColor(background_color_); layer->SetSafeOpaqueBackgroundColor(safe_opaque_background_color_); layer->SetBounds(use_paint_properties ? paint_properties_.bounds @@ -1138,34 +1153,23 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetClipTreeIndex(clip_tree_index()); layer->SetScrollTreeIndex(scroll_tree_index()); layer->set_offset_to_transform_parent(offset_to_transform_parent_); - layer->SetDoubleSided(double_sided_); layer->SetDrawsContent(DrawsContent()); - layer->SetHideLayerAndSubtree(hide_layer_and_subtree_); - layer->SetHasRenderSurface(has_render_surface_); // subtree_property_changed_ is propagated to all descendants while building // property trees. So, it is enough to check it only for the current layer. if (subtree_property_changed_) layer->NoteLayerPropertyChanged(); - layer->SetForceRenderSurface(force_render_surface_); - if (!layer->FilterIsAnimatingOnImplOnly() && !FilterIsAnimating()) + if (!FilterIsAnimating()) layer->SetFilters(filters_); - DCHECK(!(FilterIsAnimating() && layer->FilterIsAnimatingOnImplOnly())); layer->SetBackgroundFilters(background_filters()); layer->SetMasksToBounds(masks_to_bounds_); layer->set_main_thread_scrolling_reasons(main_thread_scrolling_reasons_); layer->SetNonFastScrollableRegion(non_fast_scrollable_region_); layer->SetTouchEventHandlerRegion(touch_event_handler_region_); layer->SetContentsOpaque(contents_opaque_); - if (!layer->OpacityIsAnimatingOnImplOnly() && !OpacityIsAnimating()) + if (!OpacityIsAnimating()) layer->SetOpacity(opacity_); - DCHECK(!(OpacityIsAnimating() && layer->OpacityIsAnimatingOnImplOnly())); layer->SetBlendMode(blend_mode_); - layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_); layer->SetPosition(position_); - layer->SetIsContainerForFixedPositionLayers( - IsContainerForFixedPositionLayers()); - layer->SetPositionConstraint(position_constraint_); - layer->SetShouldFlattenTransform(should_flatten_transform_); layer->set_should_flatten_transform_from_property_tree( should_flatten_transform_from_property_tree_); layer->set_draw_blend_mode(draw_blend_mode_); @@ -1173,11 +1177,9 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetUseLocalTransformForBackfaceVisibility( use_local_transform_for_backface_visibility_); layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility_); - if (!layer->TransformIsAnimatingOnImplOnly() && !TransformIsAnimating()) - layer->SetTransformAndInvertibility(transform_, transform_is_invertible_); - DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly())); + if (!TransformIsAnimating()) + layer->SetTransform(transform_); layer->Set3dSortingContextId(sorting_context_id_); - layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_); layer->SetScrollClipLayer(scroll_clip_layer_id_); layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); @@ -1185,51 +1187,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetElementId(element_id_); layer->SetMutableProperties(mutable_properties_); - LayerImpl* scroll_parent = nullptr; - if (scroll_parent_) { - scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); - DCHECK(scroll_parent); - } - - layer->SetScrollParent(scroll_parent); - if (scroll_children_) { - std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; - for (std::set<Layer*>::iterator it = scroll_children_->begin(); - it != scroll_children_->end(); - ++it) { - DCHECK_EQ((*it)->scroll_parent(), this); - LayerImpl* scroll_child = - layer->layer_tree_impl()->LayerById((*it)->id()); - DCHECK(scroll_child); - scroll_children->insert(scroll_child); - } - layer->SetScrollChildren(scroll_children); - } else { - layer->SetScrollChildren(nullptr); - } - - LayerImpl* clip_parent = nullptr; - if (clip_parent_) { - clip_parent = - layer->layer_tree_impl()->LayerById(clip_parent_->id()); - DCHECK(clip_parent); - } - - layer->SetClipParent(clip_parent); - if (clip_children_) { - std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>; - for (std::set<Layer*>::iterator it = clip_children_->begin(); - it != clip_children_->end(); ++it) { - DCHECK_EQ((*it)->clip_parent(), this); - LayerImpl* clip_child = layer->layer_tree_impl()->LayerById((*it)->id()); - DCHECK(clip_child); - clip_children->insert(clip_child); - } - layer->SetClipChildren(clip_children); - } else { - layer->SetClipChildren(nullptr); - } - // When a scroll offset animation is interrupted the new scroll position on // 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 @@ -1242,13 +1199,13 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { { TRACE_EVENT0("cc", "Layer::PushPropertiesTo::CopyOutputRequests"); // Wrap the copy_requests_ in a PostTask to the main thread. - std::vector<scoped_ptr<CopyOutputRequest>> main_thread_copy_requests; + std::vector<std::unique_ptr<CopyOutputRequest>> main_thread_copy_requests; for (auto it = copy_requests_.begin(); it != copy_requests_.end(); ++it) { scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner = layer_tree_host()->task_runner_provider()->MainThreadTaskRunner(); - scoped_ptr<CopyOutputRequest> original_request = std::move(*it); + std::unique_ptr<CopyOutputRequest> original_request = std::move(*it); const CopyOutputRequest& original_request_ref = *original_request; - scoped_ptr<CopyOutputRequest> main_thread_request = + std::unique_ptr<CopyOutputRequest> main_thread_request = CopyOutputRequest::CreateRelayRequest( original_request_ref, base::Bind(&PostCopyCallbackToMainThread, main_thread_task_runner, @@ -1269,10 +1226,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { update_rect_.Union(layer->update_rect()); layer->SetUpdateRect(update_rect_); - if (frame_timing_requests_dirty_) { - layer->SetFrameTimingRequests(frame_timing_requests_); - frame_timing_requests_dirty_ = false; - } + layer->SetHasWillChangeTransformHint(has_will_change_transform_hint()); // Reset any state that should be cleared for the next update. subtree_property_changed_ = false; @@ -1415,7 +1369,6 @@ void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto) { base->set_double_sided(double_sided_); base->set_draws_content(draws_content_); base->set_hide_layer_and_subtree(hide_layer_and_subtree_); - base->set_has_render_surface(has_render_surface_); base->set_subtree_property_changed(subtree_property_changed_); // TODO(nyquist): Add support for serializing FilterOperations for @@ -1441,7 +1394,6 @@ void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto) { base->set_draw_blend_mode(SkXfermodeModeToProto(draw_blend_mode_)); base->set_use_parent_backface_visibility(use_parent_backface_visibility_); TransformToProto(transform_, base->mutable_transform()); - base->set_transform_is_invertible(transform_is_invertible_); base->set_sorting_context_id(sorting_context_id_); base->set_num_descendants_that_draw_content( num_descendants_that_draw_content_); @@ -1473,12 +1425,12 @@ void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto) { RectToProto(update_rect_, base->mutable_update_rect()); - // TODO(nyquist): Figure out what to do with LayerAnimationController. + // TODO(nyquist): Figure out what to do with ElementAnimations. // See crbug.com/570376. - // TODO(nyquist): Figure out what to do with FrameTimingRequests. See - // crbug.com/570377. update_rect_ = gfx::Rect(); + + base->set_has_will_change_transform_hint(has_will_change_transform_hint_); } void Layer::FromLayerSpecificPropertiesProto( @@ -1501,7 +1453,6 @@ void Layer::FromLayerSpecificPropertiesProto( double_sided_ = base.double_sided(); draws_content_ = base.draws_content(); hide_layer_and_subtree_ = base.hide_layer_and_subtree(); - has_render_surface_ = base.has_render_surface(); subtree_property_changed_ = base.subtree_property_changed(); masks_to_bounds_ = base.masks_to_bounds(); main_thread_scrolling_reasons_ = base.main_thread_scrolling_reasons(); @@ -1523,7 +1474,6 @@ void Layer::FromLayerSpecificPropertiesProto( draw_blend_mode_ = SkXfermodeModeFromProto(base.draw_blend_mode()); use_parent_backface_visibility_ = base.use_parent_backface_visibility(); transform_ = ProtoToTransform(base.transform()); - transform_is_invertible_ = base.transform_is_invertible(); sorting_context_id_ = base.sorting_context_id(); num_descendants_that_draw_content_ = base.num_descendants_that_draw_content(); @@ -1572,9 +1522,11 @@ void Layer::FromLayerSpecificPropertiesProto( scroll_offset_ = ProtoToScrollOffset(base.scroll_offset()); update_rect_.Union(ProtoToRect(base.update_rect())); + + has_will_change_transform_hint_ = base.has_will_change_transform_hint(); } -scoped_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) { +std::unique_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) { return LayerImpl::Create(tree_impl, layer_id_); } @@ -1625,22 +1577,14 @@ bool Layer::IsSuitableForGpuRasterization() const { return true; } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> Layer::TakeDebugInfo() { +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> +Layer::TakeDebugInfo() { if (client_) return client_->TakeDebugInfo(this); else return nullptr; } -void Layer::SetHasRenderSurface(bool has_render_surface) { - if (has_render_surface_ == has_render_surface) - return; - has_render_surface_ = has_render_surface; - // We do not need SetNeedsCommit here, since this is only ever called - // during a commit, from CalculateDrawProperties using property trees. - SetNeedsPushProperties(); -} - void Layer::SetSubtreePropertyChanged() { if (subtree_property_changed_) return; @@ -1682,7 +1626,6 @@ void Layer::OnTransformAnimated(const gfx::Transform& transform) { if (transform_ == transform) return; transform_ = transform; - transform_is_invertible_ = transform.IsInvertible(); // Changing the transform may change the visible part of this layer, so a new // recording may be needed. SetNeedsUpdate(); @@ -1693,7 +1636,7 @@ void Layer::OnTransformAnimated(const gfx::Transform& transform) { if (node->owner_id == id()) { node->data.local = transform; node->data.needs_local_transform_update = true; - node->data.is_animated = true; + node->data.has_potential_animation = true; layer_tree_host_->property_trees()->transform_tree.set_needs_update( true); } @@ -1707,7 +1650,21 @@ void Layer::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) { // compositor-driven scrolling. } -void Layer::OnTransformIsPotentiallyAnimatingChanged(bool is_animating) { +void Layer::OnTransformIsCurrentlyAnimatingChanged( + bool is_currently_animating) { + DCHECK(layer_tree_host_); + TransformTree& transform_tree = + layer_tree_host_->property_trees()->transform_tree; + TransformNode* node = transform_tree.Node(transform_tree_index()); + if (!node) + return; + + if (node->owner_id == id()) + node->data.is_currently_animating = is_currently_animating; +} + +void Layer::OnTransformIsPotentiallyAnimatingChanged( + bool has_potential_animation) { if (!layer_tree_host_) return; TransformTree& transform_tree = @@ -1717,8 +1674,8 @@ void Layer::OnTransformIsPotentiallyAnimatingChanged(bool is_animating) { return; if (node->owner_id == id()) { - node->data.is_animated = is_animating; - if (is_animating) { + node->data.has_potential_animation = has_potential_animation; + if (has_potential_animation) { float maximum_target_scale = 0.f; node->data.local_maximum_animation_target_scale = MaximumTargetScale(&maximum_target_scale) ? maximum_target_scale @@ -1741,11 +1698,43 @@ void Layer::OnTransformIsPotentiallyAnimatingChanged(bool is_animating) { } } +void Layer::OnOpacityIsCurrentlyAnimatingChanged(bool is_currently_animating) { + DCHECK(layer_tree_host_); + EffectTree& effect_tree = layer_tree_host_->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(effect_tree_index()); + if (!node) + return; + + if (node->owner_id == id()) + node->data.is_currently_animating_opacity = is_currently_animating; +} + +void Layer::OnOpacityIsPotentiallyAnimatingChanged( + bool has_potential_animation) { + DCHECK(layer_tree_host_); + EffectTree& effect_tree = layer_tree_host_->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(effect_tree_index()); + if (!node) + return; + if (node->owner_id == id()) { + node->data.has_potential_opacity_animation = + has_potential_animation || OpacityCanAnimateOnImplThread(); + effect_tree.set_needs_update(true); + } +} + bool Layer::HasActiveAnimationForTesting() const { return layer_tree_host_ ? layer_tree_host_->HasActiveAnimationForTesting(this) : false; } +void Layer::SetHasWillChangeTransformHint(bool has_will_change) { + if (has_will_change_transform_hint_ == has_will_change) + return; + has_will_change_transform_hint_ = has_will_change; + SetNeedsCommit(); +} + ScrollbarLayerInterface* Layer::ToScrollbarLayer() { return nullptr; } @@ -1791,16 +1780,6 @@ void Layer::RunMicroBenchmark(MicroBenchmark* benchmark) { benchmark->RunOnLayer(this); } -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(); -} - void Layer::SetElementId(uint64_t id) { DCHECK(IsPropertyChangeAllowed()); if (element_id_ == id) diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h index eb0ba34ae1e..47ed6224349 100644 --- a/chromium/cc/layers/layer.h +++ b/chromium/cc/layers/layer.h @@ -20,7 +20,6 @@ #include "cc/animation/target_property.h" #include "cc/base/cc_export.h" #include "cc/base/region.h" -#include "cc/debug/frame_timing_request.h" #include "cc/debug/micro_benchmark.h" #include "cc/input/input_handler.h" #include "cc/layers/layer_collections.h" @@ -29,7 +28,6 @@ #include "cc/output/filter_operations.h" #include "cc/trees/property_tree.h" #include "third_party/skia/include/core/SkColor.h" -#include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/geometry/point3_f.h" @@ -103,7 +101,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { // first), then the callback is called with a nullptr/empty result. If the // request's source property is set, any prior uncommitted requests having the // same source will be aborted. - void RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> request); + void RequestCopyOfOutput(std::unique_ptr<CopyOutputRequest> request); bool HasCopyRequest() const { return !copy_requests_.empty(); } @@ -137,6 +135,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { bool HasPotentiallyRunningOpacityAnimation() const; virtual bool OpacityCanAnimateOnImplThread() const; + virtual bool AlwaysUseActiveTreeOpacity() const; + void SetBlendMode(SkXfermode::Mode blend_mode); SkXfermode::Mode blend_mode() const { return blend_mode_; } @@ -200,7 +200,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { bool HasPotentiallyRunningTransformAnimation() const; bool HasOnlyTranslationTransforms() const; bool AnimationsPreserveAxisAlignment() const; - bool transform_is_invertible() const { return transform_is_invertible_; } bool MaximumTargetScale(float* max_scale) const; bool AnimationStartScale(float* start_scale) const; @@ -289,8 +288,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { did_scroll_callback_ = callback; } - void SetForceRenderSurface(bool force_render_surface); - bool force_render_surface() const { return force_render_surface_; } + void SetForceRenderSurfaceForTesting(bool force_render_surface); + bool force_render_surface_for_testing() const { + return force_render_surface_for_testing_; + } gfx::ScrollOffset CurrentScrollOffset() const { return scroll_offset_; } @@ -350,7 +351,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { virtual void SetIsMask(bool is_mask) {} virtual bool IsSuitableForGpuRasterization() const; - virtual scoped_ptr<base::trace_event::ConvertableToTraceFormat> + virtual std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo(); void SetLayerClient(LayerClient* client) { client_ = client; } @@ -409,7 +410,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { virtual sk_sp<SkPicture> GetPicture() const; // Constructs a LayerImpl of the correct runtime type for this Layer type. - virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl); + virtual std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl); bool NeedsDisplayForTesting() const { return !update_rect_.IsEmpty(); } void ResetNeedsDisplayForTesting() { update_rect_ = gfx::Rect(); } @@ -477,25 +478,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void set_clip_rect(const gfx::Rect& rect) {} - // This should only be called during BeginMainFrame since it does not trigger - // a Commit. This is called right after property tree being built and should - // not trigger property tree rebuild. - void SetHasRenderSurface(bool has_render_surface); - bool has_render_surface() const { - return has_render_surface_; - } - void SetSubtreePropertyChanged(); bool subtree_property_changed() const { return subtree_property_changed_; } - // Sets new frame timing requests for this layer. - void SetFrameTimingRequests(const std::vector<FrameTimingRequest>& requests); - - // Accessor for unit tests - const std::vector<FrameTimingRequest>& FrameTimingRequests() const { - return frame_timing_requests_; - } - void DidBeginTracing(); int num_copy_requests_in_target_subtree(); @@ -512,9 +497,17 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void OnOpacityAnimated(float opacity); void OnTransformAnimated(const gfx::Transform& transform); void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset); + void OnTransformIsCurrentlyAnimatingChanged(bool is_animating); void OnTransformIsPotentiallyAnimatingChanged(bool is_animating); + void OnOpacityIsCurrentlyAnimatingChanged(bool is_currently_animating); + void OnOpacityIsPotentiallyAnimatingChanged(bool has_potential_animation); bool HasActiveAnimationForTesting() const; + void SetHasWillChangeTransformHint(bool has_will_change); + bool has_will_change_transform_hint() const { + return has_will_change_transform_hint_; + } + protected: friend class LayerImpl; friend class TreeSynchronizer; @@ -648,10 +641,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { bool use_parent_backface_visibility_ : 1; bool use_local_transform_for_backface_visibility_ : 1; bool should_check_backface_visibility_ : 1; - bool force_render_surface_ : 1; - bool transform_is_invertible_ : 1; - bool has_render_surface_ : 1; + bool force_render_surface_for_testing_ : 1; bool subtree_property_changed_ : 1; + bool has_will_change_transform_hint_ : 1; Region non_fast_scrollable_region_; Region touch_event_handler_region_; gfx::PointF position_; @@ -666,10 +658,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { FilterOperations background_filters_; LayerPositionConstraint position_constraint_; Layer* scroll_parent_; - scoped_ptr<std::set<Layer*>> scroll_children_; + std::unique_ptr<std::set<Layer*>> scroll_children_; Layer* clip_parent_; - scoped_ptr<std::set<Layer*>> clip_children_; + std::unique_ptr<std::set<Layer*>> clip_children_; gfx::Transform transform_; gfx::Point3F transform_origin_; @@ -679,7 +671,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { LayerClient* client_; - std::vector<scoped_ptr<CopyOutputRequest>> copy_requests_; + std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests_; base::Closure did_scroll_callback_; @@ -689,9 +681,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { gfx::Rect visible_layer_rect_; size_t num_unclipped_descendants_; - std::vector<FrameTimingRequest> frame_timing_requests_; - bool frame_timing_requests_dirty_; - DISALLOW_COPY_AND_ASSIGN(Layer); }; diff --git a/chromium/cc/layers/layer_client.h b/chromium/cc/layers/layer_client.h index fa33f92b132..8f9310f2f4a 100644 --- a/chromium/cc/layers/layer_client.h +++ b/chromium/cc/layers/layer_client.h @@ -5,7 +5,8 @@ #ifndef CC_LAYERS_LAYER_CLIENT_H_ #define CC_LAYERS_LAYER_CLIENT_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" namespace base { @@ -27,8 +28,8 @@ class CC_EXPORT LayerClient { // // A pointer to the layer is provided for the convenience of layer clients // which service multiple layers. - virtual scoped_ptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo( - Layer* layer) = 0; + virtual std::unique_ptr<base::trace_event::ConvertableToTraceFormat> + TakeDebugInfo(Layer* layer) = 0; protected: virtual ~LayerClient() {} diff --git a/chromium/cc/layers/layer_collections.h b/chromium/cc/layers/layer_collections.h index 6830261629e..23c6c10d0a1 100644 --- a/chromium/cc/layers/layer_collections.h +++ b/chromium/cc/layers/layer_collections.h @@ -5,11 +5,11 @@ #ifndef CC_LAYERS_LAYER_COLLECTIONS_H_ #define CC_LAYERS_LAYER_COLLECTIONS_H_ +#include <memory> #include <unordered_map> #include <vector> #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" namespace cc { @@ -17,9 +17,9 @@ class Layer; class LayerImpl; using LayerList = std::vector<scoped_refptr<Layer>>; -using OwnedLayerImplList = std::vector<scoped_ptr<LayerImpl>>; +using OwnedLayerImplList = std::vector<std::unique_ptr<LayerImpl>>; using LayerImplList = std::vector<LayerImpl*>; -using OwnedLayerImplMap = std::unordered_map<int, scoped_ptr<LayerImpl>>; +using OwnedLayerImplMap = std::unordered_map<int, std::unique_ptr<LayerImpl>>; using LayerImplMap = std::unordered_map<int, LayerImpl*>; } // namespace cc diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc index 3c41b1832c7..8dd57fd4c47 100644 --- a/chromium/cc/layers/layer_impl.cc +++ b/chromium/cc/layers/layer_impl.cc @@ -11,6 +11,7 @@ #include <utility> #include "base/json/json_reader.h" +#include "base/memory/ptr_util.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" @@ -44,33 +45,27 @@ namespace cc { LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) : parent_(nullptr), - scroll_parent_(nullptr), - clip_parent_(nullptr), mask_layer_id_(-1), mask_layer_(nullptr), replica_layer_id_(-1), replica_layer_(nullptr), layer_id_(id), layer_tree_impl_(tree_impl), + test_properties_(nullptr), scroll_clip_layer_id_(Layer::INVALID_ID), main_thread_scrolling_reasons_( MainThreadScrollingReason::kNotScrollingOnMain), user_scrollable_horizontal_(true), user_scrollable_vertical_(true), - double_sided_(true), - should_flatten_transform_(true), should_flatten_transform_from_property_tree_(false), layer_property_changed_(false), masks_to_bounds_(false), contents_opaque_(false), - is_root_for_isolated_group_(false), use_parent_backface_visibility_(false), use_local_transform_for_backface_visibility_(false), should_check_backface_visibility_(false), draws_content_(false), - hide_layer_and_subtree_(false), - transform_is_invertible_(true), - is_container_for_fixed_position_layers_(false), + is_drawn_render_surface_layer_list_member_(false), is_affected_by_page_scale_(true), was_ever_ready_since_last_transform_animation_(true), background_color_(0), @@ -78,21 +73,17 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) opacity_(1.0), blend_mode_(SkXfermode::kSrcOver_Mode), draw_blend_mode_(SkXfermode::kSrcOver_Mode), - num_descendants_that_draw_content_(0), transform_tree_index_(-1), effect_tree_index_(-1), clip_tree_index_(-1), scroll_tree_index_(-1), - draw_depth_(0.f), sorting_context_id_(0), current_draw_mode_(DRAW_MODE_NONE), element_id_(0), mutable_properties_(MutableProperty::kNone), debug_info_(nullptr), - force_render_surface_(false), - frame_timing_requests_dirty_(false), - layer_or_descendant_is_drawn_(false), - layer_or_descendant_has_touch_handler_(false) { + scrolls_drawn_descendant_(false), + has_will_change_transform_hint_(false) { DCHECK_GT(layer_id_, 0); DCHECK(layer_tree_impl_); @@ -123,14 +114,14 @@ LayerImpl::~LayerImpl() { ClearChildList(); } -void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { +void LayerImpl::AddChild(std::unique_ptr<LayerImpl> child) { child->SetParent(this); DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); children_.push_back(child.get()); layer_tree_impl_->AddLayer(std::move(child)); } -scoped_ptr<LayerImpl> LayerImpl::RemoveChildForTesting(LayerImpl* child) { +std::unique_ptr<LayerImpl> LayerImpl::RemoveChildForTesting(LayerImpl* child) { auto it = std::find(children_.begin(), children_.end(), child); if (it != children_.end()) children_.erase(it); @@ -155,31 +146,20 @@ void LayerImpl::ClearLinksToOtherLayers() { replica_layer_ = nullptr; } -void LayerImpl::SetScrollParent(LayerImpl* parent) { - if (scroll_parent_ == parent) +void LayerImpl::SetHasWillChangeTransformHint(bool has_will_change) { + if (has_will_change_transform_hint_ == has_will_change) return; - - if (parent) - DCHECK_EQ(layer_tree_impl()->LayerById(parent->id()), parent); - - scroll_parent_ = parent; + has_will_change_transform_hint_ = has_will_change; SetNeedsPushProperties(); } void LayerImpl::SetDebugInfo( - scoped_ptr<base::trace_event::ConvertableToTraceFormat> debug_info) { + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> debug_info) { owned_debug_info_ = std::move(debug_info); debug_info_ = owned_debug_info_.get(); SetNeedsPushProperties(); } -void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) { - if (scroll_children_.get() == children) - return; - scroll_children_.reset(children); - SetNeedsPushProperties(); -} - void LayerImpl::DistributeScroll(ScrollState* scroll_state) { DCHECK(scroll_state); if (scroll_state->FullyConsumed()) @@ -206,28 +186,6 @@ void LayerImpl::ApplyScroll(ScrollState* scroll_state) { layer_tree_impl()->ApplyScroll(node, scroll_state); } -void LayerImpl::SetNumDescendantsThatDrawContent(int num_descendants) { - if (num_descendants_that_draw_content_ == num_descendants) - return; - num_descendants_that_draw_content_ = num_descendants; - SetNeedsPushProperties(); -} - -void LayerImpl::SetClipParent(LayerImpl* ancestor) { - if (clip_parent_ == ancestor) - return; - - clip_parent_ = ancestor; - SetNeedsPushProperties(); -} - -void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) { - if (clip_children_.get() == children) - return; - clip_children_.reset(children); - SetNeedsPushProperties(); -} - void LayerImpl::SetTransformTreeIndex(int index) { transform_tree_index_ = index; SetNeedsPushProperties(); @@ -249,7 +207,7 @@ void LayerImpl::SetScrollTreeIndex(int index) { } void LayerImpl::PassCopyRequests( - std::vector<scoped_ptr<CopyOutputRequest>>* requests) { + std::vector<std::unique_ptr<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 @@ -273,10 +231,11 @@ void LayerImpl::PassCopyRequests( } void LayerImpl::TakeCopyRequestsAndTransformToTarget( - std::vector<scoped_ptr<CopyOutputRequest>>* requests) { + std::vector<std::unique_ptr<CopyOutputRequest>>* requests) { DCHECK(!copy_requests_.empty()); DCHECK(layer_tree_impl()->IsActiveTree()); - DCHECK_EQ(render_target(), this); + DCHECK(has_render_surface()); + DCHECK_EQ(render_target(), render_surface()); size_t first_inserted_request = requests->size(); for (auto& request : copy_requests_) @@ -298,17 +257,6 @@ void LayerImpl::TakeCopyRequestsAndTransformToTarget( layer_tree_impl()->set_needs_update_draw_properties(); } -bool LayerImpl::InsideCopyRequest() const { - EffectTree& effect_tree = layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = effect_tree.Node(effect_tree_index_); - - for (; node; node = effect_tree.parent(node)) { - if (node->data.has_copy_request) - return true; - } - return false; -} - void LayerImpl::ClearRenderSurfaceLayerList() { if (render_surface_) render_surface_->ClearLayerLists(); @@ -461,7 +409,8 @@ bool LayerImpl::user_scrollable(ScrollbarOrientation orientation) const { : user_scrollable_vertical_; } -scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { +std::unique_ptr<LayerImpl> LayerImpl::CreateLayerImpl( + LayerTreeImpl* tree_impl) { return LayerImpl::Create(tree_impl, layer_id_); } @@ -483,21 +432,16 @@ void LayerImpl::set_main_thread_scrolling_reasons( } void LayerImpl::PushPropertiesTo(LayerImpl* layer) { - layer->SetTransformOrigin(transform_origin_); layer->SetBackgroundColor(background_color_); layer->SetSafeOpaqueBackgroundColor(safe_opaque_background_color_); layer->SetBounds(bounds_); - layer->SetDoubleSided(double_sided_); layer->SetDrawsContent(DrawsContent()); - layer->SetHideLayerAndSubtree(hide_layer_and_subtree_); // If whether layer has render surface changes, we need to update draw // properties. // TODO(weiliangc): Should be safely removed after impl side is able to // update render surfaces without rebuilding property trees. if (layer->has_render_surface() != has_render_surface()) layer->layer_tree_impl()->set_needs_update_draw_properties(); - layer->SetHasRenderSurface(!!render_surface()); - layer->SetForceRenderSurface(force_render_surface_); layer->SetFilters(filters()); layer->SetBackgroundFilters(background_filters()); layer->SetMasksToBounds(masks_to_bounds_); @@ -507,12 +451,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetContentsOpaque(contents_opaque_); layer->SetOpacity(opacity_); layer->SetBlendMode(blend_mode_); - layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_); layer->SetPosition(position_); - layer->SetIsContainerForFixedPositionLayers( - is_container_for_fixed_position_layers_); - layer->SetPositionConstraint(position_constraint_); - layer->SetShouldFlattenTransform(should_flatten_transform_); layer->set_should_flatten_transform_from_property_tree( should_flatten_transform_from_property_tree_); layer->set_draw_blend_mode(draw_blend_mode_); @@ -520,7 +459,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetUseLocalTransformForBackfaceVisibility( use_local_transform_for_backface_visibility_); layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility_); - layer->SetTransformAndInvertibility(transform_, transform_is_invertible_); + layer->SetTransform(transform_); if (layer_property_changed_) layer->NoteLayerPropertyChanged(); @@ -531,7 +470,6 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->set_user_scrollable_vertical(user_scrollable_vertical_); layer->Set3dSortingContextId(sorting_context_id_); - layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_); layer->SetTransformTreeIndex(transform_tree_index_); layer->SetClipTreeIndex(clip_tree_index_); @@ -539,47 +477,6 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetScrollTreeIndex(scroll_tree_index_); layer->set_offset_to_transform_parent(offset_to_transform_parent_); - LayerImpl* scroll_parent = nullptr; - if (scroll_parent_) { - scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); - DCHECK(scroll_parent); - } - - layer->SetScrollParent(scroll_parent); - if (scroll_children_) { - std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>; - for (std::set<LayerImpl*>::iterator it = scroll_children_->begin(); - it != scroll_children_->end(); - ++it) { - DCHECK_EQ((*it)->scroll_parent(), this); - LayerImpl* scroll_child = - layer->layer_tree_impl()->LayerById((*it)->id()); - DCHECK(scroll_child); - scroll_children->insert(scroll_child); - } - layer->SetScrollChildren(scroll_children); - } else { - layer->SetScrollChildren(nullptr); - } - - LayerImpl* clip_parent = nullptr; - if (clip_parent_) { - clip_parent = layer->layer_tree_impl()->LayerById( - clip_parent_->id()); - DCHECK(clip_parent); - } - - layer->SetClipParent(clip_parent); - if (clip_children_) { - std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>; - for (std::set<LayerImpl*>::iterator it = clip_children_->begin(); - it != clip_children_->end(); ++it) - clip_children->insert(layer->layer_tree_impl()->LayerById((*it)->id())); - layer->SetClipChildren(clip_children); - } else { - layer->SetClipChildren(nullptr); - } - layer->PassCopyRequests(©_requests_); // If the main thread commits multiple times before the impl thread actually @@ -592,10 +489,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { if (owned_debug_info_) layer->SetDebugInfo(std::move(owned_debug_info_)); - if (frame_timing_requests_dirty_) { - layer->SetFrameTimingRequests(frame_timing_requests_); - frame_timing_requests_dirty_ = false; - } + layer->SetHasWillChangeTransformHint(has_will_change_transform_hint()); // Reset any state that should be cleared for the next update. layer_property_changed_ = false; @@ -634,13 +528,13 @@ base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { list->AppendDouble(position_.y()); result->Set("Position", list); - const gfx::Transform& gfx_transform = DrawTransform(); + const gfx::Transform& gfx_transform = transform(); double transform[16]; gfx_transform.matrix().asColMajord(transform); list = new base::ListValue; for (int i = 0; i < 16; ++i) list->AppendDouble(transform[i]); - result->Set("DrawTransform", list); + result->Set("Transform", list); result->SetBoolean("DrawsContent", draws_content_); result->SetBoolean("Is3dSorted", Is3dSorted()); @@ -651,7 +545,7 @@ base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { result->SetBoolean("Scrollable", true); if (!touch_event_handler_region_.IsEmpty()) { - scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue(); + std::unique_ptr<base::Value> region = touch_event_handler_region_.AsValue(); result->Set("TouchRegion", region.release()); } @@ -691,33 +585,6 @@ void LayerImpl::NoteLayerPropertyChanged() { SetNeedsPushProperties(); } -void LayerImpl::PushLayerPropertyChangedForSubtreeInternal() { - if (LayerPropertyChanged()) - NoteLayerPropertyChanged(); - for (size_t i = 0; i < children_.size(); ++i) - children_[i]->PushLayerPropertyChangedForSubtreeInternal(); -} - -void LayerImpl::PushLayerPropertyChangedForSubtree() { - // We need to update property trees first as layer property can change - // when its corresponsing property tree node changes. - PropertyTrees* property_trees = layer_tree_impl()->property_trees(); - EffectTree& effect_tree = property_trees->effect_tree; - TransformTree& transform_tree = property_trees->transform_tree; - for (int i = 1; i < static_cast<int>(effect_tree.size()); ++i) { - EffectNode* node = effect_tree.Node(i); - EffectNode* parent_node = effect_tree.parent(node); - effect_tree.UpdateEffectChanged(node, parent_node); - } - for (int i = 1; i < static_cast<int>(transform_tree.size()); ++i) { - TransformNode* node = transform_tree.Node(i); - TransformNode* parent_node = transform_tree.parent(node); - TransformNode* source_node = transform_tree.Node(node->data.source_node_id); - transform_tree.UpdateTransformChanged(node, parent_node, source_node); - } - PushLayerPropertyChangedForSubtreeInternal(); -} - void LayerImpl::ValidateQuadResourcesInternal(DrawQuad* quad) const { #if DCHECK_IS_ON() const ResourceProvider* resource_provider = @@ -801,8 +668,8 @@ void LayerImpl::UpdatePropertyTreeTransformIsAnimated(bool is_animated) { // node). if (node->owner_id != id()) return; - if (node->data.is_animated != is_animated) { - node->data.is_animated = is_animated; + if (node->data.has_potential_animation != is_animated) { + node->data.has_potential_animation = is_animated; if (is_animated) { float maximum_target_scale = 0.f; node->data.local_maximum_animation_target_scale = @@ -839,10 +706,9 @@ void LayerImpl::UpdatePropertyTreeOpacity() { // corresponding Layer at the time of the last commit. For example, an // opacity animation might have been in progress at the time the last commit // started, but might have finished since then on the compositor thread. - float effective_opacity = EffectiveOpacity(); - if (node->owner_id != id() || node->data.opacity == effective_opacity) + if (node->owner_id != id() || node->data.opacity == opacity_) return; - node->data.opacity = effective_opacity; + node->data.opacity = opacity_; node->data.effect_changed = true; layer_tree_impl()->property_trees()->changed = true; effect_tree.set_needs_update(true); @@ -853,9 +719,6 @@ void LayerImpl::UpdatePropertyTreeForScrollingAndAnimationIfNeeded() { if (scrollable()) UpdatePropertyTreeScrollOffset(); - if (HasAnyAnimationTargetingProperty(TargetProperty::OPACITY)) - UpdatePropertyTreeOpacity(); - if (HasAnyAnimationTargetingProperty(TargetProperty::TRANSFORM)) { UpdatePropertyTreeTransform(); UpdatePropertyTreeTransformIsAnimated( @@ -883,13 +746,10 @@ void LayerImpl::OnFilterAnimated(const FilterOperations& filters) { void LayerImpl::OnOpacityAnimated(float opacity) { SetOpacity(opacity); - // When hide_layer_and_subtree is true, the effective opacity is zero and we - // need not update the opacity on property trees. - if (!hide_layer_and_subtree_) { - UpdatePropertyTreeOpacity(); - SetNeedsPushProperties(); - layer_tree_impl()->set_needs_update_draw_properties(); - } + UpdatePropertyTreeOpacity(); + SetNeedsPushProperties(); + layer_tree_impl()->set_needs_update_draw_properties(); + layer_tree_impl()->AddToOpacityAnimationsMap(id(), opacity); } void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { @@ -910,16 +770,51 @@ void LayerImpl::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) { if (!IsActive()) return; - SetCurrentScrollOffset(scroll_offset); + SetCurrentScrollOffset(ClampScrollOffsetToLimits(scroll_offset)); layer_tree_impl_->DidAnimateScrollOffset(); } -void LayerImpl::OnTransformIsPotentiallyAnimatingChanged(bool is_animating) { - UpdatePropertyTreeTransformIsAnimated(is_animating); +void LayerImpl::OnTransformIsCurrentlyAnimatingChanged( + bool is_currently_animating) { + DCHECK(layer_tree_impl_); + TransformTree& transform_tree = + layer_tree_impl_->property_trees()->transform_tree; + TransformNode* node = transform_tree.Node(transform_tree_index()); + if (!node) + return; + + if (node->owner_id == id()) + node->data.is_currently_animating = is_currently_animating; +} + +void LayerImpl::OnTransformIsPotentiallyAnimatingChanged( + bool has_potential_animation) { + UpdatePropertyTreeTransformIsAnimated(has_potential_animation); was_ever_ready_since_last_transform_animation_ = false; } +void LayerImpl::OnOpacityIsCurrentlyAnimatingChanged( + bool is_currently_animating) { + DCHECK(layer_tree_impl_); + EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(effect_tree_index()); + + if (node->owner_id == id()) + node->data.is_currently_animating_opacity = is_currently_animating; +} + +void LayerImpl::OnOpacityIsPotentiallyAnimatingChanged( + bool has_potential_animation) { + DCHECK(layer_tree_impl_); + EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(effect_tree_index()); + if (node->owner_id == id()) { + node->data.has_potential_opacity_animation = has_potential_animation; + effect_tree.set_needs_update(true); + } +} + bool LayerImpl::IsActive() const { return layer_tree_impl_->IsActiveTree(); } @@ -979,7 +874,7 @@ void LayerImpl::SetBoundsDelta(const gfx::Vector2dF& bounds_delta) { } } -void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { +void LayerImpl::SetMaskLayer(std::unique_ptr<LayerImpl> mask_layer) { int new_layer_id = mask_layer ? mask_layer->id() : -1; if (mask_layer) { @@ -998,16 +893,16 @@ void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { mask_layer_id_ = new_layer_id; } -scoped_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { +std::unique_ptr<LayerImpl> LayerImpl::TakeMaskLayer() { mask_layer_id_ = -1; - scoped_ptr<LayerImpl> ret; + std::unique_ptr<LayerImpl> ret; if (mask_layer_) ret = layer_tree_impl_->RemoveLayer(mask_layer_->id()); mask_layer_ = nullptr; return ret; } -void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { +void LayerImpl::SetReplicaLayer(std::unique_ptr<LayerImpl> replica_layer) { int new_layer_id = replica_layer ? replica_layer->id() : -1; if (replica_layer) { @@ -1026,9 +921,9 @@ void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { replica_layer_id_ = new_layer_id; } -scoped_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { +std::unique_ptr<LayerImpl> LayerImpl::TakeReplicaLayer() { replica_layer_id_ = -1; - scoped_ptr<LayerImpl> ret; + std::unique_ptr<LayerImpl> ret; if (replica_layer_) ret = layer_tree_impl_->RemoveLayer(replica_layer_->id()); replica_layer_ = nullptr; @@ -1047,19 +942,6 @@ void LayerImpl::SetDrawsContent(bool draws_content) { NoteLayerPropertyChanged(); } -void LayerImpl::SetHideLayerAndSubtree(bool hide) { - if (hide_layer_and_subtree_ == hide) - return; - - hide_layer_and_subtree_ = hide; -} - -void LayerImpl::SetTransformOrigin(const gfx::Point3F& transform_origin) { - if (transform_origin_ == transform_origin) - return; - transform_origin_ = transform_origin; -} - void LayerImpl::SetBackgroundColor(SkColor background_color) { if (background_color_ == background_color) return; @@ -1100,10 +982,6 @@ bool LayerImpl::HasPotentiallyRunningFilterAnimation() const { return layer_tree_impl_->HasPotentiallyRunningFilterAnimation(this); } -bool LayerImpl::FilterIsAnimatingOnImplOnly() const { - return layer_tree_impl_->FilterIsAnimatingOnImplOnly(this); -} - void LayerImpl::SetBackgroundFilters( const FilterOperations& filters) { if (background_filters_ == filters) @@ -1134,10 +1012,6 @@ void LayerImpl::SetOpacity(float opacity) { opacity_ = opacity; } -float LayerImpl::EffectiveOpacity() const { - return hide_layer_and_subtree_ ? 0.f : opacity_; -} - bool LayerImpl::OpacityIsAnimating() const { return layer_tree_impl_->IsAnimatingOpacityProperty(this); } @@ -1146,10 +1020,6 @@ bool LayerImpl::HasPotentiallyRunningOpacityAnimation() const { return layer_tree_impl_->HasPotentiallyRunningOpacityAnimation(this); } -bool LayerImpl::OpacityIsAnimatingOnImplOnly() const { - return layer_tree_impl_->OpacityIsAnimatingOnImplOnly(this); -} - void LayerImpl::SetElementId(uint64_t element_id) { if (element_id == element_id_) return; @@ -1183,14 +1053,6 @@ void LayerImpl::SetBlendMode(SkXfermode::Mode blend_mode) { blend_mode_ = blend_mode; } -void LayerImpl::SetIsRootForIsolatedGroup(bool root) { - if (is_root_for_isolated_group_ == root) - return; - - is_root_for_isolated_group_ = root; - SetNeedsPushProperties(); -} - void LayerImpl::SetPosition(const gfx::PointF& position) { if (position_ == position) return; @@ -1198,48 +1060,17 @@ void LayerImpl::SetPosition(const gfx::PointF& position) { position_ = position; } -void LayerImpl::SetShouldFlattenTransform(bool flatten) { - if (should_flatten_transform_ == flatten) - return; - - should_flatten_transform_ = flatten; -} - void LayerImpl::Set3dSortingContextId(int id) { if (id == sorting_context_id_) return; sorting_context_id_ = id; } -void LayerImpl::SetFrameTimingRequests( - const std::vector<FrameTimingRequest>& requests) { - frame_timing_requests_ = requests; - frame_timing_requests_dirty_ = true; - SetNeedsPushProperties(); -} - -void LayerImpl::GatherFrameTimingRequestIds(std::vector<int64_t>* request_ids) { - for (const auto& request : frame_timing_requests_) - request_ids->push_back(request.id()); -} - void LayerImpl::SetTransform(const gfx::Transform& transform) { if (transform_ == transform) return; transform_ = transform; - transform_is_invertible_ = transform_.IsInvertible(); -} - -void LayerImpl::SetTransformAndInvertibility(const gfx::Transform& transform, - bool transform_is_invertible) { - if (transform_ == transform) { - DCHECK(transform_is_invertible_ == transform_is_invertible) - << "Can't change invertibility if transform is unchanged"; - return; - } - transform_ = transform; - transform_is_invertible_ = transform_is_invertible; } bool LayerImpl::TransformIsAnimating() const { @@ -1250,10 +1081,6 @@ bool LayerImpl::HasPotentiallyRunningTransformAnimation() const { return layer_tree_impl_->HasPotentiallyRunningTransformAnimation(this); } -bool LayerImpl::TransformIsAnimatingOnImplOnly() const { - return layer_tree_impl_->TransformIsAnimatingOnImplOnly(this); -} - bool LayerImpl::HasOnlyTranslationTransforms() const { return layer_tree_impl_->HasOnlyTranslationTransforms(this); } @@ -1334,13 +1161,6 @@ void LayerImpl::UpdatePropertyTreeScrollOffset() { } } -void LayerImpl::SetDoubleSided(bool double_sided) { - if (double_sided_ == double_sided) - return; - - double_sided_ = double_sided; -} - SimpleEnclosedRegion LayerImpl::VisibleOpaqueRegion() const { if (contents_opaque()) return SimpleEnclosedRegion(visible_layer_rect()); @@ -1409,13 +1229,9 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const { MathUtil::AddToTracedValue("scroll_offset", CurrentScrollOffset(), state); - MathUtil::AddToTracedValue("transform_origin", transform_origin_, state); - if (!transform().IsIdentity()) MathUtil::AddToTracedValue("transform", transform(), state); - state->SetBoolean("should_flatten", should_flatten_transform_); - bool clipped; gfx::QuadF layer_quad = MathUtil::MapQuad(ScreenSpaceTransform(), @@ -1449,18 +1265,15 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const { state->EndDictionary(); } - if (scroll_parent_) - state->SetInteger("scroll_parent", scroll_parent_->id()); - - if (clip_parent_) - state->SetInteger("clip_parent", clip_parent_->id()); - state->SetBoolean("can_use_lcd_text", can_use_lcd_text()); state->SetBoolean("contents_opaque", contents_opaque()); state->SetBoolean("has_animation_bounds", layer_tree_impl_->HasAnimationThatInflatesBounds(this)); + state->SetBoolean("has_will_change_transform_hint", + has_will_change_transform_hint()); + gfx::BoxF box; if (LayerUtils::GetAnimationBounds(*this, &box)) MathUtil::AddToTracedValue("animation_bounds", box, state); @@ -1469,7 +1282,7 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const { std::string str; debug_info_->AppendAsTraceFormat(&str); base::JSONReader json_reader; - scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(str)); + std::unique_ptr<base::Value> debug_info_value(json_reader.ReadToValue(str)); if (debug_info_value->IsType(base::Value::TYPE_DICTIONARY)) { base::DictionaryValue* dictionary_value = nullptr; @@ -1484,22 +1297,6 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const { NOTREACHED(); } } - - if (!frame_timing_requests_.empty()) { - state->BeginArray("frame_timing_requests"); - for (const auto& request : frame_timing_requests_) { - state->BeginDictionary(); - state->SetInteger("request_id", request.id()); - MathUtil::AddToTracedValue("request_rect", request.rect(), state); - state->EndDictionary(); - } - state->EndArray(); - } -} - -bool LayerImpl::IsDrawnRenderSurfaceLayerListMember() const { - return draw_properties_.last_drawn_render_surface_layer_list_id == - layer_tree_impl_->current_render_surface_list_id(); } size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; } @@ -1508,17 +1305,12 @@ void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { benchmark->RunOnLayer(this); } -int LayerImpl::NumDescendantsThatDrawContent() const { - return num_descendants_that_draw_content_; -} - void LayerImpl::SetHasRenderSurface(bool should_have_render_surface) { if (!!render_surface() == should_have_render_surface) return; - SetNeedsPushProperties(); if (should_have_render_surface) { - render_surface_ = make_scoped_ptr(new RenderSurfaceImpl(this)); + render_surface_ = base::WrapUnique(new RenderSurfaceImpl(this)); return; } render_surface_.reset(); @@ -1526,7 +1318,7 @@ void LayerImpl::SetHasRenderSurface(bool should_have_render_surface) { gfx::Transform LayerImpl::DrawTransform() const { // Only drawn layers have up-to-date draw properties. - if (!IsDrawnRenderSurfaceLayerListMember()) { + if (!is_drawn_render_surface_layer_list_member()) { if (layer_tree_impl()->property_trees()->non_root_surfaces_enabled) { return draw_property_utils::DrawTransform( this, layer_tree_impl()->property_trees()->transform_tree); @@ -1541,7 +1333,7 @@ gfx::Transform LayerImpl::DrawTransform() const { gfx::Transform LayerImpl::ScreenSpaceTransform() const { // Only drawn layers have up-to-date draw properties. - if (!IsDrawnRenderSurfaceLayerListMember()) { + if (!is_drawn_render_surface_layer_list_member()) { return draw_property_utils::ScreenSpaceTransform( this, layer_tree_impl()->property_trees()->transform_tree); } @@ -1549,14 +1341,6 @@ gfx::Transform LayerImpl::ScreenSpaceTransform() const { return draw_properties().screen_space_transform; } -void LayerImpl::SetForceRenderSurface(bool force_render_surface) { - if (force_render_surface == force_render_surface_) - return; - - force_render_surface_ = force_render_surface; - NoteLayerPropertyChanged(); -} - Region LayerImpl::GetInvalidationRegionForDebugging() { return Region(update_rect_); } @@ -1574,6 +1358,27 @@ gfx::Rect LayerImpl::GetScaledEnclosingRectInTargetSpace(float scale) const { gfx::Rect(scaled_bounds)); } +RenderSurfaceImpl* LayerImpl::render_target() { + EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(effect_tree_index_); + + if (node->data.render_surface) + return node->data.render_surface; + else + return effect_tree.Node(node->data.target_id)->data.render_surface; +} + +const RenderSurfaceImpl* LayerImpl::render_target() const { + const EffectTree& effect_tree = + layer_tree_impl_->property_trees()->effect_tree; + const EffectNode* node = effect_tree.Node(effect_tree_index_); + + if (node->data.render_surface) + return node->data.render_surface; + else + return effect_tree.Node(node->data.target_id)->data.render_surface; +} + bool LayerImpl::IsHidden() const { EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree; EffectNode* node = effect_tree.Node(effect_tree_index_); @@ -1586,14 +1391,12 @@ bool LayerImpl::InsideReplica() const { EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree; EffectNode* node = effect_tree.Node(effect_tree_index_); - while (node) { - EffectNode* target_node = effect_tree.Node(node->data.target_id); - LayerImpl* target_layer = - layer_tree_impl()->LayerById(target_node->owner_id); + while (node->id > 0) { + LayerImpl* target_layer = layer_tree_impl()->LayerById(node->owner_id); DCHECK(target_layer); if (target_layer->has_replica()) return true; - node = effect_tree.parent(target_node); + node = effect_tree.Node(node->data.target_id); } return false; diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h index 40d7336c64b..e437904b612 100644 --- a/chromium/cc/layers/layer_impl.h +++ b/chromium/cc/layers/layer_impl.h @@ -9,22 +9,23 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <string> #include <vector> #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/values.h" #include "cc/animation/target_property.h" #include "cc/base/cc_export.h" #include "cc/base/region.h" #include "cc/base/synced_property.h" -#include "cc/debug/frame_timing_request.h" #include "cc/input/input_handler.h" #include "cc/layers/draw_properties.h" #include "cc/layers/layer_collections.h" +#include "cc/layers/layer_impl_test_properties.h" #include "cc/layers/layer_position_constraint.h" #include "cc/layers/performance_properties.h" #include "cc/layers/render_surface_impl.h" @@ -33,7 +34,7 @@ #include "cc/resources/resource_provider.h" #include "cc/tiles/tile_priority.h" #include "third_party/skia/include/core/SkColor.h" -#include "third_party/skia/include/core/SkImageFilter.h" +#include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" @@ -80,10 +81,8 @@ class CC_EXPORT LayerImpl { typedef LayerImplList LayerListType; typedef RenderSurfaceImpl RenderSurfaceType; - enum RenderingContextConstants { NO_RENDERING_CONTEXT = 0 }; - - static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr(new LayerImpl(tree_impl, id)); + static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { + return base::WrapUnique(new LayerImpl(tree_impl, id)); } virtual ~LayerImpl(); @@ -96,7 +95,10 @@ class CC_EXPORT LayerImpl { void OnOpacityAnimated(float opacity); void OnTransformAnimated(const gfx::Transform& transform); void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset); - void OnTransformIsPotentiallyAnimatingChanged(bool is_animating); + void OnTransformIsCurrentlyAnimatingChanged(bool is_currently_animating); + void OnTransformIsPotentiallyAnimatingChanged(bool has_potential_animation); + void OnOpacityIsCurrentlyAnimatingChanged(bool is_currently_animating); + void OnOpacityIsPotentiallyAnimatingChanged(bool has_potential_animation); bool IsActive() const; bool OpacityCanAnimateOnImplThread() const { return false; } @@ -104,22 +106,10 @@ class CC_EXPORT LayerImpl { LayerImpl* parent() { return parent_; } LayerImplList& children() { return children_; } LayerImpl* child_at(size_t index) const { return children_[index]; } - void AddChild(scoped_ptr<LayerImpl> child); - scoped_ptr<LayerImpl> RemoveChildForTesting(LayerImpl* child); + void AddChild(std::unique_ptr<LayerImpl> child); + std::unique_ptr<LayerImpl> RemoveChildForTesting(LayerImpl* child); void SetParent(LayerImpl* parent); - void SetScrollParent(LayerImpl* parent); - - LayerImpl* scroll_parent() { return scroll_parent_; } - const LayerImpl* scroll_parent() const { return scroll_parent_; } - - void SetScrollChildren(std::set<LayerImpl*>* children); - - std::set<LayerImpl*>* scroll_children() { return scroll_children_.get(); } - const std::set<LayerImpl*>* scroll_children() const { - return scroll_children_.get(); - } - void DistributeScroll(ScrollState* scroll_state); void ApplyScroll(ScrollState* scroll_state); @@ -162,40 +152,23 @@ class CC_EXPORT LayerImpl { // For compatibility with Layer. bool has_render_surface() const { return !!render_surface(); } - bool force_render_surface() const { return force_render_surface_; } - void SetNumDescendantsThatDrawContent(int num_descendants); - void SetClipParent(LayerImpl* ancestor); - - LayerImpl* clip_parent() { - return clip_parent_; - } - const LayerImpl* clip_parent() const { - return clip_parent_; - } - void SetClipChildren(std::set<LayerImpl*>* children); - - std::set<LayerImpl*>* clip_children() { return clip_children_.get(); } - const std::set<LayerImpl*>* clip_children() const { - return clip_children_.get(); - } - - void PassCopyRequests(std::vector<scoped_ptr<CopyOutputRequest>>* requests); + void PassCopyRequests( + std::vector<std::unique_ptr<CopyOutputRequest>>* requests); // Can only be called when the layer has a copy request. void TakeCopyRequestsAndTransformToTarget( - std::vector<scoped_ptr<CopyOutputRequest>>* request); + std::vector<std::unique_ptr<CopyOutputRequest>>* request); bool HasCopyRequest() const { return !copy_requests_.empty(); } - bool InsideCopyRequest() const; - void SetMaskLayer(scoped_ptr<LayerImpl> mask_layer); + void SetMaskLayer(std::unique_ptr<LayerImpl> mask_layer); LayerImpl* mask_layer() { return mask_layer_; } const LayerImpl* mask_layer() const { return mask_layer_; } - scoped_ptr<LayerImpl> TakeMaskLayer(); + std::unique_ptr<LayerImpl> TakeMaskLayer(); - void SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer); + void SetReplicaLayer(std::unique_ptr<LayerImpl> replica_layer); LayerImpl* replica_layer() { return replica_layer_; } const LayerImpl* replica_layer() const { return replica_layer_; } - scoped_ptr<LayerImpl> TakeReplicaLayer(); + std::unique_ptr<LayerImpl> TakeReplicaLayer(); bool has_mask() const { return !!mask_layer_; } bool has_replica() const { return !!replica_layer_; } @@ -237,12 +210,11 @@ class CC_EXPORT LayerImpl { void SetDrawsContent(bool draws_content); bool DrawsContent() const { return draws_content_; } - int NumDescendantsThatDrawContent() const; - void SetHideLayerAndSubtree(bool hide); - bool hide_layer_and_subtree() const { return hide_layer_and_subtree_; } - - void SetTransformOrigin(const gfx::Point3F& transform_origin); - gfx::Point3F transform_origin() const { return transform_origin_; } + LayerImplTestProperties* test_properties() { + if (!test_properties_) + test_properties_.reset(new LayerImplTestProperties()); + return test_properties_.get(); + } void SetBackgroundColor(SkColor background_color); SkColor background_color() const { return background_color_; } @@ -255,7 +227,6 @@ class CC_EXPORT LayerImpl { const FilterOperations& filters() const { return filters_; } bool FilterIsAnimating() const; bool HasPotentiallyRunningFilterAnimation() const; - bool FilterIsAnimatingOnImplOnly() const; void SetBackgroundFilters(const FilterOperations& filters); const FilterOperations& background_filters() const { @@ -270,10 +241,8 @@ class CC_EXPORT LayerImpl { void SetOpacity(float opacity); float opacity() const { return opacity_; } - float EffectiveOpacity() const; bool OpacityIsAnimating() const; bool HasPotentiallyRunningOpacityAnimation() const; - bool OpacityIsAnimatingOnImplOnly() const; void SetElementId(uint64_t element_id); uint64_t element_id() const { return element_id_; } @@ -294,36 +263,13 @@ class CC_EXPORT LayerImpl { return blend_mode_ == SkXfermode::kSrcOver_Mode; } - void SetIsRootForIsolatedGroup(bool root); - bool is_root_for_isolated_group() const { - return is_root_for_isolated_group_; - } - void SetPosition(const gfx::PointF& position); gfx::PointF position() const { return position_; } - void SetIsContainerForFixedPositionLayers(bool container) { - is_container_for_fixed_position_layers_ = container; - } - // This is a non-trivial function in Layer. - bool IsContainerForFixedPositionLayers() const { - return is_container_for_fixed_position_layers_; - } - bool IsAffectedByPageScale() const; gfx::Vector2dF FixedContainerSizeDelta() const; - void SetPositionConstraint(const LayerPositionConstraint& constraint) { - position_constraint_ = constraint; - } - const LayerPositionConstraint& position_constraint() const { - return position_constraint_; - } - - void SetShouldFlattenTransform(bool flatten); - bool should_flatten_transform() const { return should_flatten_transform_; } - bool Is3dSorted() const { return sorting_context_id_ != 0; } void SetUseParentBackfaceVisibility(bool use) { @@ -359,6 +305,11 @@ class CC_EXPORT LayerImpl { RenderSurfaceImpl* render_surface() const { return render_surface_.get(); } + // The render surface which this layer draws into. This can be either owned by + // the same layer or an ancestor of this layer. + RenderSurfaceImpl* render_target(); + const RenderSurfaceImpl* render_target() const; + DrawProperties& draw_properties() { return draw_properties_; } const DrawProperties& draw_properties() const { return draw_properties_; } @@ -390,20 +341,6 @@ class CC_EXPORT LayerImpl { gfx::Rect visible_layer_rect() const { return draw_properties_.visible_layer_rect; } - LayerImpl* render_target() { - DCHECK(!draw_properties_.render_target || - draw_properties_.render_target->render_surface()); - return draw_properties_.render_target; - } - const LayerImpl* render_target() const { - DCHECK(!draw_properties_.render_target || - draw_properties_.render_target->render_surface()); - return draw_properties_.render_target; - } - - size_t num_unclipped_descendants() const { - return draw_properties_.num_unclipped_descendants; - } // The client should be responsible for setting bounds, content bounds and // contents scale to appropriate values. LayerImpl doesn't calculate any of @@ -447,9 +384,6 @@ class CC_EXPORT LayerImpl { uint32_t main_thread_scrolling_reasons() const { return main_thread_scrolling_reasons_; } - bool should_scroll_on_main_thread() const { - return !!main_thread_scrolling_reasons_; - } void SetNonFastScrollableRegion(const Region& region) { non_fast_scrollable_region_ = region; @@ -465,19 +399,12 @@ class CC_EXPORT LayerImpl { return touch_event_handler_region_; } - void SetDoubleSided(bool double_sided); - bool double_sided() const { return double_sided_; } - 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; bool AnimationsPreserveAxisAlignment() 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; @@ -522,7 +449,7 @@ class CC_EXPORT LayerImpl { // ReleaseResources call. virtual void RecreateResources(); - virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl); + virtual std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl); virtual void PushPropertiesTo(LayerImpl* layer); virtual void GetAllPrioritizedTilesForTracing( @@ -536,20 +463,19 @@ class CC_EXPORT LayerImpl { virtual void RunMicroBenchmark(MicroBenchmarkImpl* benchmark); void SetDebugInfo( - scoped_ptr<base::trace_event::ConvertableToTraceFormat> debug_info); + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> debug_info); - bool IsDrawnRenderSurfaceLayerListMember() const; + void set_is_drawn_render_surface_layer_list_member(bool is_member) { + is_drawn_render_surface_layer_list_member_ = is_member; + } + + bool is_drawn_render_surface_layer_list_member() const { + return is_drawn_render_surface_layer_list_member_; + } void Set3dSortingContextId(int id); int sorting_context_id() { return sorting_context_id_; } - void SetFrameTimingRequests( - const std::vector<FrameTimingRequest>& frame_timing_requests); - const std::vector<FrameTimingRequest>& frame_timing_requests() const { - return frame_timing_requests_; - } - void GatherFrameTimingRequestIds(std::vector<int64_t>* request_ids); - const SyncedScrollOffset* synced_scroll_offset() const; SyncedScrollOffset* synced_scroll_offset(); @@ -559,21 +485,11 @@ class CC_EXPORT LayerImpl { virtual gfx::Rect GetEnclosingRectInTargetSpace() const; - 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_layer_or_descendant_has_touch_handler( - bool layer_or_descendant_has_touch_handler) { - layer_or_descendant_has_touch_handler_ = - layer_or_descendant_has_touch_handler; + void set_scrolls_drawn_descendant(bool scrolls_drawn_descendant) { + scrolls_drawn_descendant_ = scrolls_drawn_descendant; } - bool layer_or_descendant_has_touch_handler() { - return layer_or_descendant_has_touch_handler_; - } + bool scrolls_drawn_descendant() { return scrolls_drawn_descendant_; } int num_copy_requests_in_target_subtree(); @@ -595,10 +511,13 @@ class CC_EXPORT LayerImpl { void NoteLayerPropertyChanged(); - void PushLayerPropertyChangedForSubtree(); - void ClearLinksToOtherLayers(); + void SetHasWillChangeTransformHint(bool has_will_change); + bool has_will_change_transform_hint() const { + return has_will_change_transform_hint_; + } + protected: LayerImpl(LayerTreeImpl* layer_impl, int id, @@ -627,26 +546,12 @@ class CC_EXPORT LayerImpl { void ValidateQuadResourcesInternal(DrawQuad* quad) const; - void NoteLayerPropertyChangedForDescendantsInternal(); - void PushLayerPropertyChangedForSubtreeInternal(); - virtual const char* LayerTypeAsString() const; // Properties internal to LayerImpl LayerImpl* parent_; LayerImplList children_; - LayerImpl* scroll_parent_; - - // Storing a pointer to a set rather than a set since this will be rarely - // used. If this pointer turns out to be too heavy, we could have this (and - // the scroll parent above) be stored in a LayerImpl -> scroll_info - // map somewhere. - scoped_ptr<std::set<LayerImpl*>> scroll_children_; - - LayerImpl* clip_parent_; - scoped_ptr<std::set<LayerImpl*>> clip_children_; - // mask_layer_ can be temporarily stolen during tree sync, we need this ID to // confirm newly assigned layer is still the previous one int mask_layer_id_; @@ -656,10 +561,11 @@ class CC_EXPORT LayerImpl { int layer_id_; LayerTreeImpl* layer_tree_impl_; + std::unique_ptr<LayerImplTestProperties> test_properties_; + gfx::Vector2dF bounds_delta_; // Properties synchronized from the associated Layer. - gfx::Point3F transform_origin_; gfx::Size bounds_; int scroll_clip_layer_id_; @@ -668,9 +574,6 @@ class CC_EXPORT LayerImpl { bool user_scrollable_horizontal_ : 1; bool user_scrollable_vertical_ : 1; - // Whether the "back" of this layer should draw. - bool double_sided_ : 1; - bool should_flatten_transform_ : 1; bool should_flatten_transform_from_property_tree_ : 1; // Tracks if drawing-related properties have changed since last redraw. @@ -678,18 +581,11 @@ class CC_EXPORT LayerImpl { bool masks_to_bounds_ : 1; bool contents_opaque_ : 1; - bool is_root_for_isolated_group_ : 1; bool use_parent_backface_visibility_ : 1; bool use_local_transform_for_backface_visibility_ : 1; bool should_check_backface_visibility_ : 1; bool draws_content_ : 1; - bool hide_layer_and_subtree_ : 1; - - // Cache transform_'s invertibility. - bool transform_is_invertible_ : 1; - - // Set for the layer that other layers are fixed to. - bool is_container_for_fixed_position_layers_ : 1; + bool is_drawn_render_surface_layer_list_member_ : 1; bool is_affected_by_page_scale_ : 1; @@ -710,20 +606,12 @@ class CC_EXPORT LayerImpl { gfx::PointF position_; gfx::Transform transform_; - LayerPositionConstraint position_constraint_; - - int num_descendants_that_draw_content_; - gfx::Rect clip_rect_in_target_space_; int transform_tree_index_; int effect_tree_index_; int clip_tree_index_; int scroll_tree_index_; - // The global depth value of the center of the layer. This value is used - // to sort layers from back to front. - float draw_depth_; - FilterOperations filters_; FilterOperations background_filters_; @@ -749,24 +637,20 @@ class CC_EXPORT LayerImpl { // space. gfx::Rect damage_rect_; - std::vector<scoped_ptr<CopyOutputRequest>> copy_requests_; + std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests_; // Group of properties that need to be computed based on the layer tree // hierarchy before layers can be drawn. DrawProperties draw_properties_; PerformanceProperties<LayerImpl> performance_properties_; - scoped_ptr<base::trace_event::ConvertableToTraceFormat> owned_debug_info_; + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> + owned_debug_info_; base::trace_event::ConvertableToTraceFormat* debug_info_; - scoped_ptr<RenderSurfaceImpl> render_surface_; - - bool force_render_surface_; + std::unique_ptr<RenderSurfaceImpl> render_surface_; - std::vector<FrameTimingRequest> frame_timing_requests_; - bool frame_timing_requests_dirty_; - bool layer_or_descendant_is_drawn_; - // If true, the layer or one of its descendants has a touch handler. - bool layer_or_descendant_has_touch_handler_; + bool scrolls_drawn_descendant_; + bool has_will_change_transform_hint_; DISALLOW_COPY_AND_ASSIGN(LayerImpl); }; diff --git a/chromium/cc/layers/layer_impl_test_properties.cc b/chromium/cc/layers/layer_impl_test_properties.cc new file mode 100644 index 00000000000..c204f917d90 --- /dev/null +++ b/chromium/cc/layers/layer_impl_test_properties.cc @@ -0,0 +1,22 @@ +// Copyright 2016 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/layer_impl_test_properties.h" + +namespace cc { + +LayerImplTestProperties::LayerImplTestProperties() + : double_sided(true), + force_render_surface(false), + is_container_for_fixed_position_layers(false), + should_flatten_transform(true), + hide_layer_and_subtree(false), + num_descendants_that_draw_content(0), + num_unclipped_descendants(0), + scroll_parent(nullptr), + clip_parent(nullptr) {} + +LayerImplTestProperties::~LayerImplTestProperties() {} + +} // namespace cc diff --git a/chromium/cc/layers/layer_impl_test_properties.h b/chromium/cc/layers/layer_impl_test_properties.h new file mode 100644 index 00000000000..627362e4815 --- /dev/null +++ b/chromium/cc/layers/layer_impl_test_properties.h @@ -0,0 +1,39 @@ +// Copyright 2016 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_LAYER_IMPL_TEST_PROPERTIES_H_ +#define CC_LAYERS_LAYER_IMPL_TEST_PROPERTIES_H_ + +#include <set> + +#include "base/memory/ptr_util.h" +#include "cc/layers/layer_position_constraint.h" +#include "ui/gfx/geometry/point3_f.h" + +namespace cc { + +class LayerImpl; + +struct CC_EXPORT LayerImplTestProperties { + LayerImplTestProperties(); + ~LayerImplTestProperties(); + + bool double_sided; + bool force_render_surface; + bool is_container_for_fixed_position_layers; + bool should_flatten_transform; + bool hide_layer_and_subtree; + int num_descendants_that_draw_content; + size_t num_unclipped_descendants; + LayerPositionConstraint position_constraint; + gfx::Point3F transform_origin; + LayerImpl* scroll_parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children; + LayerImpl* clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children; +}; + +} // namespace cc + +#endif // CC_LAYERS_LAYER_IMPL_TEST_PROPERTIES_H_ diff --git a/chromium/cc/layers/layer_impl_unittest.cc b/chromium/cc/layers/layer_impl_unittest.cc index 7e8c3275280..2fdedf1173c 100644 --- a/chromium/cc/layers/layer_impl_unittest.cc +++ b/chromium/cc/layers/layer_impl_unittest.cc @@ -27,8 +27,7 @@ namespace cc { namespace { #define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking( \ - PropertyTrees::ResetFlags::ALL_TREES); \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ code_to_test; \ EXPECT_TRUE( \ root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(root)); \ @@ -41,8 +40,7 @@ namespace { EXPECT_TRUE(grand_child->LayerPropertyChanged()); #define EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking( \ - PropertyTrees::ResetFlags::ALL_TREES); \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ code_to_test; \ EXPECT_FALSE( \ root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(root)); \ @@ -56,8 +54,7 @@ namespace { #define EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( \ code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking( \ - PropertyTrees::ResetFlags::ALL_TREES); \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ code_to_test; \ EXPECT_TRUE( \ root->layer_tree_impl()->LayerNeedsPushPropertiesForTesting(root)); \ @@ -70,8 +67,7 @@ namespace { EXPECT_FALSE(grand_child->LayerPropertyChanged()); #define EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking( \ - PropertyTrees::ResetFlags::ALL_TREES); \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ root->layer_tree_impl()->property_trees()->full_tree_damaged = false; \ code_to_test; \ EXPECT_TRUE( \ @@ -85,8 +81,7 @@ namespace { EXPECT_FALSE(grand_child->LayerPropertyChanged()); #define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking( \ - PropertyTrees::ResetFlags::ALL_TREES); \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ host_impl.active_tree()->property_trees()->needs_rebuild = true; \ host_impl.active_tree()->BuildPropertyTreesForTesting(); \ host_impl.ForcePrepareToDraw(); \ @@ -95,8 +90,7 @@ namespace { EXPECT_TRUE(host_impl.active_tree()->needs_update_draw_properties()); #define VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking( \ - PropertyTrees::ResetFlags::ALL_TREES); \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ host_impl.active_tree()->property_trees()->needs_rebuild = true; \ host_impl.active_tree()->BuildPropertyTreesForTesting(); \ host_impl.ForcePrepareToDraw(); \ @@ -122,35 +116,22 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(output_surface.get())); - scoped_ptr<LayerImpl> root_clip_ptr = + std::unique_ptr<LayerImpl> root_clip_ptr = LayerImpl::Create(host_impl.active_tree(), 1); LayerImpl* root_clip = root_clip_ptr.get(); - scoped_ptr<LayerImpl> root_ptr = + std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl.active_tree(), 2); LayerImpl* root = root_ptr.get(); root_clip_ptr->AddChild(std::move(root_ptr)); host_impl.active_tree()->SetRootLayer(std::move(root_clip_ptr)); - scoped_ptr<LayerImpl> scroll_parent = - LayerImpl::Create(host_impl.active_tree(), 3); - LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 4).get(); - std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>(); - scroll_children->insert(scroll_child); - scroll_children->insert(root); - root->SetForceRenderSurface(true); - - scoped_ptr<LayerImpl> clip_parent = - LayerImpl::Create(host_impl.active_tree(), 5); - LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 6).get(); - std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>(); - clip_children->insert(clip_child); - clip_children->insert(root); - root->layer_tree_impl()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + + root->test_properties()->force_render_surface = true; + root->layer_tree_impl()->ResetAllChangeTracking(); root->AddChild(LayerImpl::Create(host_impl.active_tree(), 7)); LayerImpl* child = root->children()[0]; @@ -226,59 +207,31 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { // Changing these properties does not cause the layer to be marked as changed // but does cause the layer to need to push properties. EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetIsRootForIsolatedGroup(true)); - EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( root->SetElementId(2)); EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( root->SetMutableProperties(MutableProperty::kOpacity)); - EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetScrollParent(scroll_parent.get())); - EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetScrollChildren(scroll_children)); - EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetClipParent(clip_parent.get())); - EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetClipChildren(clip_children)); - EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetNumDescendantsThatDrawContent(10)); // After setting all these properties already, setting to the exact same // values again should not cause any change. - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetTransformOrigin(arbitrary_point_3f)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetMasksToBounds(true)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( root->SetPosition(arbitrary_point_f)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetShouldFlattenTransform(false)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->Set3dSortingContextId(1)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( root->SetTransform(arbitrary_transform)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetDoubleSided(false)); // constructor initializes it to "true". 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( root->SetBlendMode(arbitrary_blend_mode)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetIsRootForIsolatedGroup(true)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetDrawsContent(true)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(bounds_size)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetScrollParent(scroll_parent.get())); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetScrollChildren(scroll_children)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetClipParent(clip_parent.get())); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->SetClipChildren(clip_children)); } TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); @@ -287,12 +240,12 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { LayerImpl::Create(host_impl.active_tree(), 1)); LayerImpl* root = host_impl.active_tree()->root_layer(); root->SetHasRenderSurface(true); - scoped_ptr<LayerImpl> layer_ptr = + std::unique_ptr<LayerImpl> layer_ptr = LayerImpl::Create(host_impl.active_tree(), 2); LayerImpl* layer = layer_ptr.get(); root->AddChild(std::move(layer_ptr)); layer->SetScrollClipLayer(root->id()); - scoped_ptr<LayerImpl> layer2_ptr = + std::unique_ptr<LayerImpl> layer2_ptr = LayerImpl::Create(host_impl.active_tree(), 3); LayerImpl* layer2 = layer2_ptr.get(); root->AddChild(std::move(layer2_ptr)); @@ -327,11 +280,6 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { // filters. VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(true)); - VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(true)); - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(false)); - VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetForceRenderSurface(false)); - // Related filter functions. VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( root->OnFilterAnimated(arbitrary_filters)); @@ -373,14 +321,9 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { layer->NoteLayerPropertyChanged()); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer2->SetPosition(arbitrary_point_f); layer->NoteLayerPropertyChanged()); - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetShouldFlattenTransform(false); - layer->NoteLayerPropertyChanged()); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1); layer->NoteLayerPropertyChanged()); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( - layer->SetDoubleSided(false); // constructor initializes it to "true". - layer->NoteLayerPropertyChanged()); - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetBackgroundColor(arbitrary_color)); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetBackgroundFilters(arbitrary_filters)); @@ -394,16 +337,12 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { layer->NoteLayerPropertyChanged()); // Unrelated functions, set to the same values, no needs update. - VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( - layer->SetIsRootForIsolatedGroup(true)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( layer2->SetPosition(arbitrary_point_f)); 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->SetDrawsContent(true)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetBackgroundColor(arbitrary_color)); @@ -413,8 +352,6 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetBlendMode(arbitrary_blend_mode)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( - layer->SetIsRootForIsolatedGroup(true)); - VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetTransform(arbitrary_transform)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetElementId(2)); @@ -426,7 +363,7 @@ TEST(LayerImplTest, SafeOpaqueBackgroundColor) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); @@ -461,38 +398,6 @@ TEST(LayerImplTest, SafeOpaqueBackgroundColor) { } } -TEST(LayerImplTest, TransformInvertibility) { - FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); - - scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1); - EXPECT_TRUE(layer->transform().IsInvertible()); - EXPECT_TRUE(layer->transform_is_invertible()); - - gfx::Transform transform; - transform.Scale3d( - SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0)); - layer->SetTransform(transform); - EXPECT_FALSE(layer->transform().IsInvertible()); - EXPECT_FALSE(layer->transform_is_invertible()); - - transform.MakeIdentity(); - transform.ApplyPerspectiveDepth(SkDoubleToMScalar(100.0)); - transform.RotateAboutZAxis(75.0); - transform.RotateAboutXAxis(32.2); - transform.RotateAboutZAxis(-75.0); - transform.Translate3d(SkDoubleToMScalar(50.5), - SkDoubleToMScalar(42.42), - SkDoubleToMScalar(-100.25)); - - layer->SetTransform(transform); - EXPECT_TRUE(layer->transform().IsInvertible()); - EXPECT_TRUE(layer->transform_is_invertible()); -} - class LayerImplScrollTest : public testing::Test { public: LayerImplScrollTest() @@ -529,6 +434,7 @@ class LayerImplScrollTest : public testing::Test { LayerTreeSettings settings() { LayerTreeSettings settings; + settings.verify_clip_tree_calculations = true; return settings; } @@ -658,7 +564,7 @@ TEST_F(LayerImplScrollTest, PushPropertiesToMirrorsCurrentScrollOffset) { scroll_tree(layer())->CollectScrollDeltasForTesting(); - scoped_ptr<LayerImpl> pending_layer = + std::unique_ptr<LayerImpl> pending_layer = LayerImpl::Create(host_impl().sync_tree(), layer()->id()); scroll_tree(pending_layer.get()) ->UpdateScrollOffsetBaseForTesting(pending_layer->id(), diff --git a/chromium/cc/layers/layer_iterator.h b/chromium/cc/layers/layer_iterator.h index cf01ca19a41..dc89e113ad3 100644 --- a/chromium/cc/layers/layer_iterator.h +++ b/chromium/cc/layers/layer_iterator.h @@ -246,13 +246,12 @@ class LayerIterator { inline LayerImpl* current_layer() const { return current_layer_represents_target_render_surface() ? target_render_surface_layer() - : LayerTreeHostCommon::get_layer_as_raw_ptr( - target_render_surface_children(), current_layer_index_); + : target_render_surface_children().at(current_layer_index_); } inline bool current_layer_represents_contributing_render_surface() const { - return LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>( - current_layer(), target_render_surface_layer()->id()); + return current_layer()->render_surface() && + current_layer()->render_surface() != target_render_surface(); } inline bool current_layer_represents_target_render_surface() const { return current_layer_index_ == diff --git a/chromium/cc/layers/layer_iterator_unittest.cc b/chromium/cc/layers/layer_iterator_unittest.cc index 158dd935200..3e8cb0990d5 100644 --- a/chromium/cc/layers/layer_iterator_unittest.cc +++ b/chromium/cc/layers/layer_iterator_unittest.cc @@ -6,6 +6,7 @@ #include <vector> +#include "base/memory/ptr_util.h" #include "cc/layers/layer.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/test_task_graph_runner.h" @@ -24,8 +25,8 @@ namespace { class TestLayerImpl : public LayerImpl { public: - static scoped_ptr<TestLayerImpl> Create(LayerTreeImpl* tree, int id) { - return make_scoped_ptr(new TestLayerImpl(tree, id)); + static std::unique_ptr<TestLayerImpl> Create(LayerTreeImpl* tree, int id) { + return base::WrapUnique(new TestLayerImpl(tree, id)); } ~TestLayerImpl() override {} @@ -98,7 +99,7 @@ class LayerIteratorTest : public testing::Test { &task_graph_runner_), id_(1) {} - scoped_ptr<TestLayerImpl> CreateLayer() { + std::unique_ptr<TestLayerImpl> CreateLayer() { return TestLayerImpl::Create(host_impl_.active_tree(), id_++); } @@ -118,11 +119,11 @@ TEST_F(LayerIteratorTest, EmptyTree) { } 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(); + std::unique_ptr<TestLayerImpl> root_layer = CreateLayer(); + std::unique_ptr<TestLayerImpl> first = CreateLayer(); + std::unique_ptr<TestLayerImpl> second = CreateLayer(); + std::unique_ptr<TestLayerImpl> third = CreateLayer(); + std::unique_ptr<TestLayerImpl> fourth = CreateLayer(); TestLayerImpl* root_ptr = root_layer.get(); TestLayerImpl* first_ptr = first.get(); @@ -138,11 +139,9 @@ TEST_F(LayerIteratorTest, SimpleTree) { host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; - host_impl_.active_tree()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, root_ptr->bounds(), &render_surface_layer_list, - host_impl_.active_tree()->current_render_surface_list_id()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + root_ptr, root_ptr->bounds(), &render_surface_layer_list); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); IterateFrontToBack(&render_surface_layer_list); EXPECT_COUNT(root_ptr, 5, -1, 4); @@ -153,15 +152,15 @@ TEST_F(LayerIteratorTest, SimpleTree) { } 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(); + std::unique_ptr<TestLayerImpl> root_layer = CreateLayer(); + std::unique_ptr<TestLayerImpl> root1 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root2 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root3 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root21 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root22 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root23 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root221 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root231 = CreateLayer(); TestLayerImpl* root_ptr = root_layer.get(); TestLayerImpl* root1_ptr = root1.get(); @@ -185,11 +184,9 @@ TEST_F(LayerIteratorTest, ComplexTree) { host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; - host_impl_.active_tree()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, root_ptr->bounds(), &render_surface_layer_list, - host_impl_.active_tree()->current_render_surface_list_id()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + root_ptr, root_ptr->bounds(), &render_surface_layer_list); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); IterateFrontToBack(&render_surface_layer_list); EXPECT_COUNT(root_ptr, 9, -1, 8); @@ -204,15 +201,15 @@ TEST_F(LayerIteratorTest, ComplexTree) { } 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(); + std::unique_ptr<TestLayerImpl> root_layer = CreateLayer(); + std::unique_ptr<TestLayerImpl> root1 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root2 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root3 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root21 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root22 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root23 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root221 = CreateLayer(); + std::unique_ptr<TestLayerImpl> root231 = CreateLayer(); TestLayerImpl* root_ptr = root_layer.get(); TestLayerImpl* root1_ptr = root1.get(); @@ -224,9 +221,9 @@ TEST_F(LayerIteratorTest, ComplexTreeMultiSurface) { TestLayerImpl* root221_ptr = root221.get(); TestLayerImpl* root231_ptr = root231.get(); - root22->SetForceRenderSurface(true); - root23->SetForceRenderSurface(true); - root2->SetForceRenderSurface(true); + root22->test_properties()->force_render_surface = true; + root23->test_properties()->force_render_surface = true; + root2->test_properties()->force_render_surface = true; root22->AddChild(std::move(root221)); root23->AddChild(std::move(root231)); root2->SetDrawsContent(false); @@ -240,11 +237,9 @@ TEST_F(LayerIteratorTest, ComplexTreeMultiSurface) { host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; - host_impl_.active_tree()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, root_ptr->bounds(), &render_surface_layer_list, - host_impl_.active_tree()->current_render_surface_list_id()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + root_ptr, root_ptr->bounds(), &render_surface_layer_list); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); IterateFrontToBack(&render_surface_layer_list); EXPECT_COUNT(root_ptr, 14, -1, 13); diff --git a/chromium/cc/layers/layer_list_iterator.cc b/chromium/cc/layers/layer_list_iterator.cc index e71238d6020..ec728993777 100644 --- a/chromium/cc/layers/layer_list_iterator.cc +++ b/chromium/cc/layers/layer_list_iterator.cc @@ -4,42 +4,45 @@ #include "cc/layers/layer_list_iterator.h" +#include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" namespace cc { -LayerListIterator::LayerListIterator(LayerImpl* root_layer) +template <typename LayerType> +LayerListIterator<LayerType>::LayerListIterator(LayerType* root_layer) : current_layer_(root_layer) { DCHECK(!root_layer || !root_layer->parent()); list_indices_.push_back(0); } -LayerListIterator::LayerListIterator(const LayerListIterator& other) = default; +template <typename LayerType> +LayerListIterator<LayerType>::LayerListIterator( + const LayerListIterator<LayerType>& other) = default; -LayerListIterator::~LayerListIterator() {} +template <typename LayerType> +LayerListIterator<LayerType>::~LayerListIterator() {} -LayerListIterator& LayerListIterator::operator++() { +template <typename LayerType> +LayerListIterator<LayerType>& LayerListIterator<LayerType>::operator++() { // case 0: done if (!current_layer_) return *this; // case 1: descend. - const LayerImplList& current_list = current_layer_->children(); - if (!current_list.empty()) { - current_layer_ = current_list[0]; + if (!current_layer_->children().empty()) { + current_layer_ = current_layer_->child_at(0); list_indices_.push_back(0); return *this; } - for (LayerImpl* parent = current_layer_->parent(); parent; + for (LayerType* parent = current_layer_->parent(); parent; parent = parent->parent()) { // We now try and advance in some list of siblings. - const LayerImplList& sibling_list = parent->children(); - // case 2: Advance to a sibling. - if (list_indices_.back() + 1 < sibling_list.size()) { + if (list_indices_.back() + 1 < parent->children().size()) { ++list_indices_.back(); - current_layer_ = sibling_list[list_indices_.back()]; + current_layer_ = parent->child_at(list_indices_.back()); return *this; } @@ -51,48 +54,58 @@ LayerListIterator& LayerListIterator::operator++() { return *this; } -LayerListReverseIterator::LayerListReverseIterator(LayerImpl* root_layer) - : LayerListIterator(root_layer) { +template <typename LayerType> +LayerListReverseIterator<LayerType>::LayerListReverseIterator( + LayerType* root_layer) + : LayerListIterator<LayerType>(root_layer) { DescendToRightmostInSubtree(); } -LayerListReverseIterator::~LayerListReverseIterator() {} +template <typename LayerType> +LayerListReverseIterator<LayerType>::~LayerListReverseIterator() {} // We will only support prefix increment. -LayerListIterator& LayerListReverseIterator::operator++() { +template <typename LayerType> +LayerListIterator<LayerType>& LayerListReverseIterator<LayerType>:: +operator++() { // case 0: done - if (!current_layer_) + if (!current_layer()) return *this; // case 1: we're the leftmost sibling. - if (!list_indices_.back()) { - list_indices_.pop_back(); - current_layer_ = current_layer_->parent(); + if (!list_indices().back()) { + list_indices().pop_back(); + this->current_layer_ = current_layer()->parent(); return *this; } // case 2: we're not the leftmost sibling. In this case, we want to move one // sibling over, and then descend to the rightmost descendant in that subtree. - CHECK(current_layer_->parent()); - --list_indices_.back(); - const LayerImplList& parent_list = current_layer_->parent()->children(); - current_layer_ = parent_list[list_indices_.back()]; + CHECK(current_layer()->parent()); + --list_indices().back(); + this->current_layer_ = + current_layer()->parent()->child_at(list_indices().back()); DescendToRightmostInSubtree(); return *this; } -void LayerListReverseIterator::DescendToRightmostInSubtree() { - if (!current_layer_) +template <typename LayerType> +void LayerListReverseIterator<LayerType>::DescendToRightmostInSubtree() { + if (!current_layer()) return; - const LayerImplList& current_list = current_layer_->children(); - if (current_list.empty()) + if (current_layer()->children().empty()) return; - size_t last_index = current_list.size() - 1; - current_layer_ = current_list[last_index]; - list_indices_.push_back(last_index); + size_t last_index = current_layer()->children().size() - 1; + this->current_layer_ = current_layer()->child_at(last_index); + list_indices().push_back(last_index); DescendToRightmostInSubtree(); } +template class LayerListIterator<Layer>; +template class LayerListIterator<LayerImpl>; +template class LayerListReverseIterator<Layer>; +template class LayerListReverseIterator<LayerImpl>; + } // namespace cc diff --git a/chromium/cc/layers/layer_list_iterator.h b/chromium/cc/layers/layer_list_iterator.h index bdc4a4a438a..948ec25ea64 100644 --- a/chromium/cc/layers/layer_list_iterator.h +++ b/chromium/cc/layers/layer_list_iterator.h @@ -12,6 +12,7 @@ namespace cc { +class Layer; class LayerImpl; // Unlike LayerIterator and friends, these iterators are not intended to permit @@ -19,43 +20,47 @@ class LayerImpl; // stacking order. All recursive walks over the LayerImpl tree should be // switched to use these classes instead as the concept of a LayerImpl tree is // deprecated. +template <typename LayerType> class CC_EXPORT LayerListIterator { public: - explicit LayerListIterator(LayerImpl* root_layer); - LayerListIterator(const LayerListIterator& other); + explicit LayerListIterator(LayerType* root_layer); + LayerListIterator(const LayerListIterator<LayerType>& other); virtual ~LayerListIterator(); - bool operator==(const LayerListIterator& other) const { + bool operator==(const LayerListIterator<LayerType>& other) const { return current_layer_ == other.current_layer_; } - bool operator!=(const LayerListIterator& other) const { + bool operator!=(const LayerListIterator<LayerType>& other) const { return !(*this == other); } // We will only support prefix increment. virtual LayerListIterator& operator++(); - LayerImpl* operator->() const { return current_layer_; } - LayerImpl* operator*() const { return current_layer_; } + LayerType* operator->() const { return current_layer_; } + LayerType* operator*() const { return current_layer_; } protected: // The implementation of this iterator is currently tied tightly to the layer // tree, but it should be straightforward to reimplement in terms of a list // when it's ready. - LayerImpl* current_layer_; + LayerType* current_layer_; std::vector<size_t> list_indices_; }; -class CC_EXPORT LayerListReverseIterator : public LayerListIterator { +template <typename LayerType> +class CC_EXPORT LayerListReverseIterator : public LayerListIterator<LayerType> { public: - explicit LayerListReverseIterator(LayerImpl* root_layer); + explicit LayerListReverseIterator(LayerType* root_layer); ~LayerListReverseIterator() override; // We will only support prefix increment. - LayerListIterator& operator++() override; + LayerListIterator<LayerType>& operator++() override; private: void DescendToRightmostInSubtree(); + LayerType* current_layer() { return this->current_layer_; } + std::vector<size_t>& list_indices() { return this->list_indices_; } }; } // namespace cc diff --git a/chromium/cc/layers/layer_list_iterator_unittest.cc b/chromium/cc/layers/layer_list_iterator_unittest.cc index 97b2cd558c5..503c1e6d94a 100644 --- a/chromium/cc/layers/layer_list_iterator_unittest.cc +++ b/chromium/cc/layers/layer_list_iterator_unittest.cc @@ -4,9 +4,11 @@ #include "cc/layers/layer_list_iterator.h" +#include <memory> + #include "base/containers/adapters.h" -#include "base/memory/scoped_ptr.h" #include "cc/test/fake_impl_task_runner_provider.h" +#include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_output_surface.h" #include "cc/test/test_shared_bitmap_manager.h" @@ -17,12 +19,188 @@ namespace cc { namespace { +// Layer version unit tests + TEST(LayerListIteratorTest, VerifyTraversalOrder) { // Unfortunate preamble. + FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); + TestTaskGraphRunner task_graph_runner; + std::unique_ptr<FakeLayerTreeHost> host_ptr = + FakeLayerTreeHost::Create(&client, &task_graph_runner); + FakeLayerTreeHost* host = host_ptr.get(); + + // This test constructs the following tree. + // 1 + // +-2 + // | +-3 + // | +-4 + // + 5 + // +-6 + // +-7 + // We expect to visit all seven layers in that order. + scoped_refptr<Layer> layer1 = Layer::Create(); + scoped_refptr<Layer> layer2 = Layer::Create(); + scoped_refptr<Layer> layer3 = Layer::Create(); + scoped_refptr<Layer> layer4 = Layer::Create(); + scoped_refptr<Layer> layer5 = Layer::Create(); + scoped_refptr<Layer> layer6 = Layer::Create(); + scoped_refptr<Layer> layer7 = Layer::Create(); + + std::unordered_map<int, int> layer_id_to_order; + layer_id_to_order[layer1->id()] = 1; + layer_id_to_order[layer2->id()] = 2; + layer_id_to_order[layer3->id()] = 3; + layer_id_to_order[layer4->id()] = 4; + layer_id_to_order[layer5->id()] = 5; + layer_id_to_order[layer6->id()] = 6; + layer_id_to_order[layer7->id()] = 7; + + layer2->AddChild(std::move(layer3)); + layer2->AddChild(std::move(layer4)); + + layer5->AddChild(std::move(layer6)); + layer5->AddChild(std::move(layer7)); + + layer1->AddChild(std::move(layer2)); + layer1->AddChild(std::move(layer5)); + + host->SetRootLayer(std::move(layer1)); + + int i = 1; + for (auto* layer : *host) { + EXPECT_EQ(i++, layer_id_to_order[layer->id()]); + } + EXPECT_EQ(8, i); +} + +TEST(LayerListIteratorTest, VerifySingleLayer) { + // Unfortunate preamble. + FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); + TestTaskGraphRunner task_graph_runner; + std::unique_ptr<FakeLayerTreeHost> host_ptr = + FakeLayerTreeHost::Create(&client, &task_graph_runner); + FakeLayerTreeHost* host = host_ptr.get(); + + // This test constructs a tree consisting of a single layer. + scoped_refptr<Layer> layer1 = Layer::Create(); + std::unordered_map<int, int> layer_id_to_order; + layer_id_to_order[layer1->id()] = 1; + host->SetRootLayer(std::move(layer1)); + + int i = 1; + for (auto* layer : *host) { + EXPECT_EQ(i++, layer_id_to_order[layer->id()]); + } + EXPECT_EQ(2, i); +} + +TEST(LayerListIteratorTest, VerifyNullFirstLayer) { + // Ensures that if an iterator is constructed with a nullptr, that it can be + // iterated without issue and that it remains equal to any other + // null-initialized iterator. + LayerListIterator<Layer> it(nullptr); + LayerListIterator<Layer> end(nullptr); + + EXPECT_EQ(it, end); + ++it; + EXPECT_EQ(it, end); +} + +TEST(LayerListReverseIteratorTest, VerifyTraversalOrder) { + // Unfortunate preamble. + FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); + TestTaskGraphRunner task_graph_runner; + std::unique_ptr<FakeLayerTreeHost> host_ptr = + FakeLayerTreeHost::Create(&client, &task_graph_runner); + FakeLayerTreeHost* host = host_ptr.get(); + + // This test constructs the following tree. + // 1 + // +-2 + // | +-3 + // | +-4 + // + 5 + // +-6 + // +-7 + // We expect to visit all seven layers in reverse order. + scoped_refptr<Layer> layer1 = Layer::Create(); + scoped_refptr<Layer> layer2 = Layer::Create(); + scoped_refptr<Layer> layer3 = Layer::Create(); + scoped_refptr<Layer> layer4 = Layer::Create(); + scoped_refptr<Layer> layer5 = Layer::Create(); + scoped_refptr<Layer> layer6 = Layer::Create(); + scoped_refptr<Layer> layer7 = Layer::Create(); + + std::unordered_map<int, int> layer_id_to_order; + layer_id_to_order[layer1->id()] = 1; + layer_id_to_order[layer2->id()] = 2; + layer_id_to_order[layer3->id()] = 3; + layer_id_to_order[layer4->id()] = 4; + layer_id_to_order[layer5->id()] = 5; + layer_id_to_order[layer6->id()] = 6; + layer_id_to_order[layer7->id()] = 7; + + layer2->AddChild(std::move(layer3)); + layer2->AddChild(std::move(layer4)); + + layer5->AddChild(std::move(layer6)); + layer5->AddChild(std::move(layer7)); + + layer1->AddChild(std::move(layer2)); + layer1->AddChild(std::move(layer5)); + + host->SetRootLayer(std::move(layer1)); + + int i = 7; + + for (auto* layer : base::Reversed(*host)) { + EXPECT_EQ(i--, layer_id_to_order[layer->id()]); + } + + EXPECT_EQ(0, i); +} + +TEST(LayerListReverseIteratorTest, VerifySingleLayer) { + // Unfortunate preamble. + FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); + TestTaskGraphRunner task_graph_runner; + std::unique_ptr<FakeLayerTreeHost> host_ptr = + FakeLayerTreeHost::Create(&client, &task_graph_runner); + FakeLayerTreeHost* host = host_ptr.get(); + + // This test constructs a tree consisting of a single layer. + scoped_refptr<Layer> layer1 = Layer::Create(); + std::unordered_map<int, int> layer_id_to_order; + layer_id_to_order[layer1->id()] = 1; + host->SetRootLayer(std::move(layer1)); + + int i = 1; + for (auto* layer : base::Reversed(*host)) { + EXPECT_EQ(i--, layer_id_to_order[layer->id()]); + } + EXPECT_EQ(0, i); +} + +TEST(LayerListReverseIteratorTest, VerifyNullFirstLayer) { + // Ensures that if an iterator is constructed with a nullptr, that it can be + // iterated without issue and that it remains equal to any other + // null-initialized iterator. + LayerListReverseIterator<Layer> it(nullptr); + LayerListReverseIterator<Layer> end(nullptr); + + EXPECT_EQ(it, end); + ++it; + EXPECT_EQ(it, end); +} + +// LayerImpl version unit tests + +TEST(LayerListIteratorTest, VerifyTraversalOrderImpl) { + // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); @@ -37,13 +215,20 @@ TEST(LayerListIteratorTest, VerifyTraversalOrder) { // +-6 // +-7 // We expect to visit all seven layers in that order. - scoped_ptr<LayerImpl> layer1 = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> layer2 = LayerImpl::Create(host_impl.active_tree(), 2); - scoped_ptr<LayerImpl> layer3 = LayerImpl::Create(host_impl.active_tree(), 3); - scoped_ptr<LayerImpl> layer4 = LayerImpl::Create(host_impl.active_tree(), 4); - scoped_ptr<LayerImpl> layer5 = LayerImpl::Create(host_impl.active_tree(), 5); - scoped_ptr<LayerImpl> layer6 = LayerImpl::Create(host_impl.active_tree(), 6); - scoped_ptr<LayerImpl> layer7 = LayerImpl::Create(host_impl.active_tree(), 7); + std::unique_ptr<LayerImpl> layer1 = + LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<LayerImpl> layer2 = + LayerImpl::Create(host_impl.active_tree(), 2); + std::unique_ptr<LayerImpl> layer3 = + LayerImpl::Create(host_impl.active_tree(), 3); + std::unique_ptr<LayerImpl> layer4 = + LayerImpl::Create(host_impl.active_tree(), 4); + std::unique_ptr<LayerImpl> layer5 = + LayerImpl::Create(host_impl.active_tree(), 5); + std::unique_ptr<LayerImpl> layer6 = + LayerImpl::Create(host_impl.active_tree(), 6); + std::unique_ptr<LayerImpl> layer7 = + LayerImpl::Create(host_impl.active_tree(), 7); layer2->AddChild(std::move(layer3)); layer2->AddChild(std::move(layer4)); @@ -63,19 +248,20 @@ TEST(LayerListIteratorTest, VerifyTraversalOrder) { EXPECT_EQ(8, i); } -TEST(LayerListIteratorTest, VerifySingleLayer) { +TEST(LayerListIteratorTest, VerifySingleLayerImpl) { // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(output_surface.get())); // This test constructs a tree consisting of a single layer. - scoped_ptr<LayerImpl> layer1 = LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<LayerImpl> layer1 = + LayerImpl::Create(host_impl.active_tree(), 1); host_impl.active_tree()->SetRootLayer(std::move(layer1)); int i = 1; @@ -85,24 +271,24 @@ TEST(LayerListIteratorTest, VerifySingleLayer) { EXPECT_EQ(2, i); } -TEST(LayerListIteratorTest, VerifyNullFirstLayer) { +TEST(LayerListIteratorTest, VerifyNullFirstLayerImpl) { // Ensures that if an iterator is constructed with a nullptr, that it can be // iterated without issue and that it remains equal to any other // null-initialized iterator. - LayerListIterator it(nullptr); - LayerListIterator end(nullptr); + LayerListIterator<LayerImpl> it(nullptr); + LayerListIterator<LayerImpl> end(nullptr); EXPECT_EQ(it, end); ++it; EXPECT_EQ(it, end); } -TEST(LayerListReverseIteratorTest, VerifyTraversalOrder) { +TEST(LayerListReverseIteratorTest, VerifyTraversalOrderImpl) { // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); @@ -117,13 +303,20 @@ TEST(LayerListReverseIteratorTest, VerifyTraversalOrder) { // +-6 // +-7 // We expect to visit all seven layers in reverse order. - scoped_ptr<LayerImpl> layer1 = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> layer2 = LayerImpl::Create(host_impl.active_tree(), 2); - scoped_ptr<LayerImpl> layer3 = LayerImpl::Create(host_impl.active_tree(), 3); - scoped_ptr<LayerImpl> layer4 = LayerImpl::Create(host_impl.active_tree(), 4); - scoped_ptr<LayerImpl> layer5 = LayerImpl::Create(host_impl.active_tree(), 5); - scoped_ptr<LayerImpl> layer6 = LayerImpl::Create(host_impl.active_tree(), 6); - scoped_ptr<LayerImpl> layer7 = LayerImpl::Create(host_impl.active_tree(), 7); + std::unique_ptr<LayerImpl> layer1 = + LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<LayerImpl> layer2 = + LayerImpl::Create(host_impl.active_tree(), 2); + std::unique_ptr<LayerImpl> layer3 = + LayerImpl::Create(host_impl.active_tree(), 3); + std::unique_ptr<LayerImpl> layer4 = + LayerImpl::Create(host_impl.active_tree(), 4); + std::unique_ptr<LayerImpl> layer5 = + LayerImpl::Create(host_impl.active_tree(), 5); + std::unique_ptr<LayerImpl> layer6 = + LayerImpl::Create(host_impl.active_tree(), 6); + std::unique_ptr<LayerImpl> layer7 = + LayerImpl::Create(host_impl.active_tree(), 7); layer2->AddChild(std::move(layer3)); layer2->AddChild(std::move(layer4)); @@ -145,19 +338,20 @@ TEST(LayerListReverseIteratorTest, VerifyTraversalOrder) { EXPECT_EQ(0, i); } -TEST(LayerListReverseIteratorTest, VerifySingleLayer) { +TEST(LayerListReverseIteratorTest, VerifySingleLayerImpl) { // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(output_surface.get())); // This test constructs a tree consisting of a single layer. - scoped_ptr<LayerImpl> layer1 = LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<LayerImpl> layer1 = + LayerImpl::Create(host_impl.active_tree(), 1); host_impl.active_tree()->SetRootLayer(std::move(layer1)); int i = 1; @@ -167,12 +361,12 @@ TEST(LayerListReverseIteratorTest, VerifySingleLayer) { EXPECT_EQ(0, i); } -TEST(LayerListReverseIteratorTest, VerifyNullFirstLayer) { +TEST(LayerListReverseIteratorTest, VerifyNullFirstLayerImpl) { // Ensures that if an iterator is constructed with a nullptr, that it can be // iterated without issue and that it remains equal to any other // null-initialized iterator. - LayerListReverseIterator it(nullptr); - LayerListReverseIterator end(nullptr); + LayerListReverseIterator<LayerImpl> it(nullptr); + LayerListReverseIterator<LayerImpl> end(nullptr); EXPECT_EQ(it, end); ++it; diff --git a/chromium/cc/layers/layer_perftest.cc b/chromium/cc/layers/layer_perftest.cc index d3c119160dc..0d2e4a146b2 100644 --- a/chromium/cc/layers/layer_perftest.cc +++ b/chromium/cc/layers/layer_perftest.cc @@ -4,7 +4,7 @@ #include "cc/layers/layer.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/debug/lap_timer.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host.h" @@ -51,13 +51,13 @@ class LayerPerfTest : public testing::Test { FakeLayerTreeHostImpl host_impl_; FakeLayerTreeHostClient fake_client_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; LapTimer timer_; }; TEST_F(LayerPerfTest, PushPropertiesTo) { scoped_refptr<Layer> test_layer = Layer::Create(); - scoped_ptr<LayerImpl> impl_layer = + std::unique_ptr<LayerImpl> impl_layer = LayerImpl::Create(host_impl_.active_tree(), 1); layer_tree_host_->SetRootLayer(test_layer); diff --git a/chromium/cc/layers/layer_position_constraint_unittest.cc b/chromium/cc/layers/layer_position_constraint_unittest.cc index d64cf4f44da..c142cfa4675 100644 --- a/chromium/cc/layers/layer_position_constraint_unittest.cc +++ b/chromium/cc/layers/layer_position_constraint_unittest.cc @@ -48,15 +48,13 @@ void SetLayerPropertiesForTesting(Layer* layer, void ExecuteCalculateDrawProperties(LayerImpl* root_layer) { std::vector<LayerImpl*> dummy_render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &dummy_render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + 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); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } class LayerPositionConstraintTest : public testing::Test { @@ -75,7 +73,7 @@ class LayerPositionConstraintTest : public testing::Test { great_grand_child_impl_(nullptr) { layer_tree_host_->InitializeForTesting( TaskRunnerProvider::Create(nullptr, nullptr), - scoped_ptr<Proxy>(new FakeProxy), nullptr); + std::unique_ptr<Proxy>(new FakeProxy), nullptr); CreateTreeForTest(); fixed_to_top_left_.set_is_fixed_position(true); fixed_to_bottom_right_.set_is_fixed_position(true); @@ -155,20 +153,24 @@ class LayerPositionConstraintTest : public testing::Test { SetScrollOffsetDelta(grand_child_impl_, 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]; + layer_tree_impl_ = root_impl_->layer_tree_impl(); + inner_viewport_container_layer_impl_ = + layer_tree_impl_->LayerById(inner_viewport_container_layer_->id()); + scroll_layer_impl_ = layer_tree_impl_->LayerById(scroll_layer_->id()); + outer_viewport_container_layer_impl_ = + layer_tree_impl_->LayerById(outer_viewport_container_layer_->id()); 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]; + layer_tree_impl_->LayerById(child_transform_layer_->id()); + child_impl_ = layer_tree_impl_->LayerById(child_->id()); + grand_child_impl_ = layer_tree_impl_->LayerById(grand_child_->id()); + great_grand_child_impl_ = + layer_tree_impl_->LayerById(great_grand_child_->id()); } protected: FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; scoped_refptr<Layer> root_; scoped_refptr<Layer> inner_viewport_container_layer_; scoped_refptr<Layer> scroll_layer_; @@ -177,6 +179,7 @@ class LayerPositionConstraintTest : public testing::Test { scoped_refptr<Layer> child_; scoped_refptr<Layer> grand_child_; scoped_refptr<Layer> great_grand_child_; + LayerTreeImpl* layer_tree_impl_; LayerImpl* root_impl_; LayerImpl* inner_viewport_container_layer_impl_; LayerImpl* scroll_layer_impl_; @@ -435,7 +438,7 @@ TEST_F(LayerPositionConstraintTest, // for when checking the scroll delta. child_->SetIsContainerForFixedPositionLayers(true); grand_child_->SetPosition(gfx::PointF(8.f, 6.f)); - grand_child_->SetForceRenderSurface(true); + grand_child_->SetForceRenderSurfaceForTesting(true); great_grand_child_->SetPositionConstraint(fixed_to_top_left_); gfx::Transform rotation_about_z; @@ -559,9 +562,9 @@ TEST_F(LayerPositionConstraintTest, // Actually set up the scenario here. child_->SetIsContainerForFixedPositionLayers(true); grand_child_->SetPosition(gfx::PointF(8.f, 6.f)); - grand_child_->SetForceRenderSurface(true); + grand_child_->SetForceRenderSurfaceForTesting(true); great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f)); - great_grand_child_->SetForceRenderSurface(true); + great_grand_child_->SetForceRenderSurfaceForTesting(true); fixed_position_child->SetPositionConstraint(fixed_to_top_left_); // The additional rotation, which is non-commutative with translations, helps @@ -575,7 +578,8 @@ TEST_F(LayerPositionConstraintTest, fixed_position_child->SetTransform(rotation_about_z); CommitAndUpdateImplPointers(); - LayerImpl* fixed_position_child_impl = great_grand_child_impl_->children()[0]; + LayerImpl* fixed_position_child_impl = + layer_tree_impl_->LayerById(fixed_position_child->id()); // Case 1: scroll delta of 0, 0 SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0)); @@ -671,7 +675,8 @@ TEST_F(LayerPositionConstraintTest, // Case 4: Bottom-right fixed-position layer. fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_); CommitAndUpdateImplPointers(); - fixed_position_child_impl = great_grand_child_impl_->children()[0]; + fixed_position_child_impl = + layer_tree_impl_->LayerById(fixed_position_child->id()); SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30)); SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20)); ExecuteCalculateDrawProperties(root_impl_); @@ -715,9 +720,9 @@ TEST_F( // Actually set up the scenario here. child_transform_layer_->SetIsContainerForFixedPositionLayers(true); grand_child_->SetPosition(gfx::PointF(8.f, 6.f)); - grand_child_->SetForceRenderSurface(true); + grand_child_->SetForceRenderSurfaceForTesting(true); great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f)); - great_grand_child_->SetForceRenderSurface(true); + great_grand_child_->SetForceRenderSurfaceForTesting(true); fixed_position_child->SetPositionConstraint(fixed_to_top_left_); // The additional rotations, which are non-commutative with translations, help @@ -732,7 +737,8 @@ TEST_F( fixed_position_child->SetTransform(rotation_about_z); CommitAndUpdateImplPointers(); - LayerImpl* fixed_position_child_impl = great_grand_child_impl_->children()[0]; + LayerImpl* fixed_position_child_impl = + layer_tree_impl_->LayerById(fixed_position_child->id()); // Case 1: scroll delta of 0, 0 SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0)); @@ -828,7 +834,7 @@ TEST_F(LayerPositionConstraintTest, // that render target is completely irrelevant; it should not affect the // scroll compensation. child_->SetIsContainerForFixedPositionLayers(true); - child_->SetForceRenderSurface(true); + child_->SetForceRenderSurfaceForTesting(true); grand_child_->SetPositionConstraint(fixed_to_top_left_); CommitAndUpdateImplPointers(); @@ -1051,7 +1057,8 @@ TEST_F(LayerPositionConstraintTest, LayerImpl* container1 = child_impl_; LayerImpl* fixed_to_container1 = grand_child_impl_; LayerImpl* container2 = great_grand_child_impl_; - LayerImpl* fixed_to_container2 = container2->children()[0]; + LayerImpl* fixed_to_container2 = + layer_tree_impl_->LayerById(great_great_grand_child->id()); SetScrollOffsetDelta(container1, gfx::Vector2d(0, 15)); container1->SetDrawsContent(true); diff --git a/chromium/cc/layers/layer_proto_converter.cc b/chromium/cc/layers/layer_proto_converter.cc index da464a7794b..25dd803c1ef 100644 --- a/chromium/cc/layers/layer_proto_converter.cc +++ b/chromium/cc/layers/layer_proto_converter.cc @@ -5,10 +5,12 @@ #include "cc/layers/layer_proto_converter.h" #include "base/stl_util.h" +#include "base/trace_event/trace_event.h" #include "cc/layers/empty_content_layer_client.h" #include "cc/layers/heads_up_display_layer.h" #include "cc/layers/layer.h" #include "cc/layers/picture_layer.h" +#include "cc/layers/solid_color_scrollbar_layer.h" #include "cc/proto/layer.pb.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_common.h" @@ -24,6 +26,7 @@ LayerProtoConverter::~LayerProtoConverter() {} void LayerProtoConverter::SerializeLayerHierarchy( const scoped_refptr<Layer> root_layer, proto::LayerNode* root_node) { + TRACE_EVENT0("cc.remote", "LayerProtoConverter::SerializeLayerHierarchy"); root_layer->ToLayerNodeProto(root_node); } @@ -53,6 +56,7 @@ scoped_refptr<Layer> LayerProtoConverter::DeserializeLayerHierarchy( void LayerProtoConverter::SerializeLayerProperties( LayerTreeHost* host, proto::LayerUpdate* layer_update) { + TRACE_EVENT0("cc.remote", "LayerProtoConverter::SerializeLayerProperties"); for (auto layer : host->LayersThatShouldPushProperties()) layer->ToLayerPropertiesProto(layer_update); host->LayersThatShouldPushProperties().clear(); @@ -82,8 +86,7 @@ void LayerProtoConverter::RecursivelyFindAllLayers(Layer* root_layer, LayerIdMap* layer_id_map) { LayerTreeHostCommon::CallFunctionForEveryLayer( root_layer->layer_tree_host(), - [layer_id_map](Layer* layer) { (*layer_id_map)[layer->id()] = layer; }, - CallFunctionLayerType::ALL_LAYERS); + [layer_id_map](Layer* layer) { (*layer_id_map)[layer->id()] = layer; }); } // static @@ -106,6 +109,14 @@ scoped_refptr<Layer> LayerProtoConverter::FindOrAllocateAndConstruct( return PictureLayer::Create(EmptyContentLayerClient::GetInstance()); case proto::LayerNode::HEADS_UP_DISPLAY_LAYER: return HeadsUpDisplayLayer::Create(); + case proto::LayerNode::SOLID_COLOR_SCROLLBAR_LAYER: + // Create and return a SolidColorScrollbarLayer with invalid properties + // (orientation, thumb thickness, starting track, left_side_scroll, layer + // id etc.). + // These properties will be set correctly in the later step when we run + // through LayerTreeHost and deserialize them for each layer. + return SolidColorScrollbarLayer::Create(ScrollbarOrientation::HORIZONTAL, + -1, -1, false, Layer::INVALID_ID); } // TODO(nyquist): Add the rest of the necessary LayerTypes. This function // should not return null. diff --git a/chromium/cc/layers/layer_proto_converter_unittest.cc b/chromium/cc/layers/layer_proto_converter_unittest.cc index 33d12aca653..49da6c86b72 100644 --- a/chromium/cc/layers/layer_proto_converter_unittest.cc +++ b/chromium/cc/layers/layer_proto_converter_unittest.cc @@ -35,7 +35,7 @@ class LayerProtoConverterTest : public testing::Test { TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostClient fake_client_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; TEST_F(LayerProtoConverterTest, TestKeepingRoot) { diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc index 752757b449a..f7d560ed64d 100644 --- a/chromium/cc/layers/layer_unittest.cc +++ b/chromium/cc/layers/layer_unittest.cc @@ -6,7 +6,7 @@ #include <stddef.h> -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" #include "cc/animation/keyframed_animation_curve.h" @@ -14,6 +14,7 @@ #include "cc/base/math_util.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/layer_impl.h" +#include "cc/layers/solid_color_scrollbar_layer.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/proto/layer.pb.h" @@ -155,7 +156,6 @@ class LayerSerializationTest : public testing::Test { EXPECT_EQ(src->double_sided_, dest->double_sided_); EXPECT_EQ(src->draws_content_, dest->draws_content_); EXPECT_EQ(src->hide_layer_and_subtree_, dest->hide_layer_and_subtree_); - EXPECT_EQ(src->has_render_surface_, dest->has_render_surface_); EXPECT_EQ(src->masks_to_bounds_, dest->masks_to_bounds_); EXPECT_EQ(src->main_thread_scrolling_reasons_, dest->main_thread_scrolling_reasons_); @@ -179,7 +179,6 @@ class LayerSerializationTest : public testing::Test { EXPECT_EQ(src->use_parent_backface_visibility_, dest->use_parent_backface_visibility_); EXPECT_EQ(src->transform_, dest->transform_); - EXPECT_EQ(src->transform_is_invertible_, dest->transform_is_invertible_); EXPECT_EQ(src->sorting_context_id_, dest->sorting_context_id_); EXPECT_EQ(src->num_descendants_that_draw_content_, dest->num_descendants_that_draw_content_); @@ -264,7 +263,6 @@ class LayerSerializationTest : public testing::Test { layer->double_sided_ = true; layer->draws_content_ = true; layer->hide_layer_and_subtree_ = false; - layer->has_render_surface_ = false; layer->masks_to_bounds_ = true; layer->main_thread_scrolling_reasons_ = MainThreadScrollingReason::kNotScrollingOnMain; @@ -286,7 +284,6 @@ class LayerSerializationTest : public testing::Test { gfx::Transform transform; transform.Rotate(90); layer->transform_ = transform; - layer->transform_is_invertible_ = true; layer->sorting_context_id_ = 0; layer->num_descendants_that_draw_content_ = 5; layer->scroll_clip_layer_id_ = Layer::INVALID_ID; @@ -310,7 +307,6 @@ class LayerSerializationTest : public testing::Test { layer->double_sided_ = !layer->double_sided_; layer->draws_content_ = !layer->draws_content_; layer->hide_layer_and_subtree_ = !layer->hide_layer_and_subtree_; - layer->has_render_surface_ = !layer->has_render_surface_; layer->masks_to_bounds_ = !layer->masks_to_bounds_; layer->main_thread_scrolling_reasons_ = MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; @@ -335,7 +331,6 @@ class LayerSerializationTest : public testing::Test { gfx::Transform transform; transform.Rotate(90); layer->transform_ = transform; - layer->transform_is_invertible_ = !layer->transform_is_invertible_; layer->sorting_context_id_ = 42; layer->num_descendants_that_draw_content_ = 5; layer->scroll_clip_layer_id_ = 17; @@ -347,6 +342,36 @@ class LayerSerializationTest : public testing::Test { VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get()); } + void VerifySolidColorScrollbarLayerAfterSerializationAndDeserialization( + scoped_refptr<SolidColorScrollbarLayer> source_scrollbar) { + proto::LayerProperties serialized_scrollbar; + source_scrollbar->LayerSpecificPropertiesToProto(&serialized_scrollbar); + + scoped_refptr<SolidColorScrollbarLayer> deserialized_scrollbar = + SolidColorScrollbarLayer::Create(ScrollbarOrientation::HORIZONTAL, -1, + -1, false, Layer::INVALID_ID); + deserialized_scrollbar->layer_id_ = source_scrollbar->layer_id_; + + // FromLayerSpecificPropertiesProto expects a non-null LayerTreeHost to be + // set. + deserialized_scrollbar->SetLayerTreeHost(layer_tree_host_.get()); + deserialized_scrollbar->FromLayerSpecificPropertiesProto( + serialized_scrollbar); + + EXPECT_EQ(source_scrollbar->track_start_, + deserialized_scrollbar->track_start_); + EXPECT_EQ(source_scrollbar->thumb_thickness_, + deserialized_scrollbar->thumb_thickness_); + EXPECT_EQ(source_scrollbar->scroll_layer_id_, + deserialized_scrollbar->scroll_layer_id_); + EXPECT_EQ(source_scrollbar->is_left_side_vertical_scrollbar_, + deserialized_scrollbar->is_left_side_vertical_scrollbar_); + EXPECT_EQ(source_scrollbar->orientation_, + deserialized_scrollbar->orientation_); + + deserialized_scrollbar->SetLayerTreeHost(nullptr); + } + void RunScrollAndClipLayersTest() { scoped_refptr<Layer> layer = Layer::Create(); @@ -816,7 +841,7 @@ class LayerSerializationTest : public testing::Test { TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostClient fake_client_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; namespace { @@ -929,7 +954,7 @@ class LayerTest : public testing::Test { FakeLayerTreeHostImpl host_impl_; FakeLayerTreeHostClient fake_client_; - scoped_ptr<StrictMock<MockLayerTreeHost>> layer_tree_host_; + std::unique_ptr<StrictMock<MockLayerTreeHost>> layer_tree_host_; scoped_refptr<Layer> parent_; scoped_refptr<Layer> child1_; scoped_refptr<Layer> child2_; @@ -969,21 +994,21 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) { root->AddChild(child2); child->AddChild(grand_child); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); - child->SetForceRenderSurface(true); + child->SetForceRenderSurfaceForTesting(true); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); child2->SetScrollParent(grand_child.get()); SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode; - scoped_ptr<LayerImpl> root_impl = + std::unique_ptr<LayerImpl> root_impl = LayerImpl::Create(host_impl_.active_tree(), root->id()); - scoped_ptr<LayerImpl> child_impl = + std::unique_ptr<LayerImpl> child_impl = LayerImpl::Create(host_impl_.active_tree(), child->id()); - scoped_ptr<LayerImpl> child2_impl = + std::unique_ptr<LayerImpl> child2_impl = LayerImpl::Create(host_impl_.active_tree(), child2->id()); - scoped_ptr<LayerImpl> grand_child_impl = + std::unique_ptr<LayerImpl> grand_child_impl = LayerImpl::Create(host_impl_.active_tree(), grand_child->id()); - scoped_ptr<LayerImpl> dummy_layer1_impl = + std::unique_ptr<LayerImpl> dummy_layer1_impl = LayerImpl::Create(host_impl_.active_tree(), dummy_layer1->id()); - scoped_ptr<LayerImpl> dummy_layer2_impl = + std::unique_ptr<LayerImpl> dummy_layer2_impl = LayerImpl::Create(host_impl_.active_tree(), dummy_layer2->id()); EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1); @@ -1093,8 +1118,7 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) { child->PushPropertiesTo(child_impl.get()); child2->PushPropertiesTo(child2_impl.get()); grand_child->PushPropertiesTo(grand_child_impl.get()); - layer_tree_host_->property_trees()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES)); + layer_tree_host_->property_trees()->ResetAllChangeTracking()); EXPECT_FALSE(node->data.transform_changed); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); @@ -1112,8 +1136,7 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) { EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET( child->PushPropertiesTo(child_impl.get()); grand_child->PushPropertiesTo(grand_child_impl.get()); - layer_tree_host_->property_trees()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES)); + layer_tree_host_->property_trees()->ResetAllChangeTracking()); node = layer_tree_host_->property_trees()->transform_tree.Node( child->transform_tree_index()); EXPECT_FALSE(node->data.transform_changed); @@ -1129,8 +1152,7 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) { child->PushPropertiesTo(child_impl.get()); child2->PushPropertiesTo(child2_impl.get()); grand_child->PushPropertiesTo(grand_child_impl.get()); - layer_tree_host_->property_trees()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES)); + layer_tree_host_->property_trees()->ResetAllChangeTracking()); gfx::Transform arbitrary_transform; arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f); @@ -1660,7 +1682,7 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetDoubleSided(false)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTouchEventHandlerRegion( gfx::Rect(10, 10))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetForceRenderSurface(true)); + EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetForceRenderSurfaceForTesting(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(2)); EXPECT_SET_NEEDS_COMMIT( @@ -1680,7 +1702,7 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) { scoped_refptr<Layer> test_layer = Layer::Create(); - scoped_ptr<LayerImpl> impl_layer = + std::unique_ptr<LayerImpl> impl_layer = LayerImpl::Create(host_impl_.active_tree(), 1); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, @@ -1702,8 +1724,7 @@ TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) { // If we do clear the LayerImpl side, then the next update_rect() should be // fresh without accumulation. - host_impl_.active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + host_impl_.active_tree()->ResetAllChangeTracking(); test_layer->SetNeedsDisplayRect(gfx::Rect(10, 10, 5, 5)); test_layer->PushPropertiesTo(impl_layer_ptr); EXPECT_FLOAT_RECT_EQ(gfx::RectF(10.f, 10.f, 5.f, 5.f), @@ -1712,7 +1733,7 @@ TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) { TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForTransform) { scoped_refptr<Layer> test_layer = Layer::Create(); - scoped_ptr<LayerImpl> impl_layer = + std::unique_ptr<LayerImpl> impl_layer = LayerImpl::Create(host_impl_.active_tree(), 1); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, @@ -1731,7 +1752,7 @@ TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForTransform) { TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForOpacity) { scoped_refptr<Layer> test_layer = Layer::Create(); - scoped_ptr<LayerImpl> impl_layer = + std::unique_ptr<LayerImpl> impl_layer = LayerImpl::Create(host_impl_.active_tree(), 1); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, @@ -1781,76 +1802,15 @@ TEST_F(LayerTest, MaskAndReplicaHasParent) { EXPECT_EQ(replica.get(), replica->mask_layer()->parent()); } -TEST_F(LayerTest, CheckTransformIsInvertible) { - scoped_refptr<Layer> layer = Layer::Create(); - scoped_ptr<LayerImpl> impl_layer = - LayerImpl::Create(host_impl_.active_tree(), 1); - EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); - layer_tree_host_->SetRootLayer(layer); - - EXPECT_TRUE(layer->transform_is_invertible()); - - gfx::Transform singular_transform; - singular_transform.Scale3d( - SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0)); - - layer->SetTransform(singular_transform); - layer->PushPropertiesTo(impl_layer.get()); - - EXPECT_FALSE(layer->transform_is_invertible()); - EXPECT_FALSE(impl_layer->transform_is_invertible()); - - gfx::Transform rotation_transform; - rotation_transform.RotateAboutZAxis(-45.0); - - layer->SetTransform(rotation_transform); - layer->PushPropertiesTo(impl_layer.get()); - EXPECT_TRUE(layer->transform_is_invertible()); - EXPECT_TRUE(impl_layer->transform_is_invertible()); - - Mock::VerifyAndClearExpectations(layer_tree_host_.get()); -} - -TEST_F(LayerTest, TransformIsInvertibleAnimation) { - scoped_refptr<Layer> layer = Layer::Create(); - scoped_ptr<LayerImpl> impl_layer = - LayerImpl::Create(host_impl_.active_tree(), 1); - EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); - layer_tree_host_->SetRootLayer(layer); - - EXPECT_TRUE(layer->transform_is_invertible()); - - gfx::Transform singular_transform; - singular_transform.Scale3d( - SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0)); - - layer->SetTransform(singular_transform); - layer->PushPropertiesTo(impl_layer.get()); - - EXPECT_FALSE(layer->transform_is_invertible()); - EXPECT_FALSE(impl_layer->transform_is_invertible()); - - gfx::Transform identity_transform; - - EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1); - layer->SetTransform(identity_transform); - layer->OnTransformAnimated(singular_transform); - layer->PushPropertiesTo(impl_layer.get()); - EXPECT_FALSE(layer->transform_is_invertible()); - EXPECT_FALSE(impl_layer->transform_is_invertible()); - - Mock::VerifyAndClearExpectations(layer_tree_host_.get()); -} - class LayerTreeHostFactory { public: LayerTreeHostFactory() : client_(FakeLayerTreeHostClient::DIRECT_3D) {} - scoped_ptr<LayerTreeHost> Create() { return Create(LayerTreeSettings()); } + std::unique_ptr<LayerTreeHost> Create() { + return Create(LayerTreeSettings()); + } - scoped_ptr<LayerTreeHost> Create(LayerTreeSettings settings) { + std::unique_ptr<LayerTreeHost> Create(LayerTreeSettings settings) { LayerTreeHost::InitParams params; params.client = &client_; params.shared_bitmap_manager = &shared_bitmap_manager_; @@ -1900,7 +1860,7 @@ TEST_F(LayerLayerTreeHostTest, EnteringTree) { AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr); LayerTreeHostFactory factory; - scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); // Setting the root layer should set the host pointer for all layers in the // tree. layer_tree_host->SetRootLayer(parent.get()); @@ -1917,7 +1877,7 @@ TEST_F(LayerLayerTreeHostTest, EnteringTree) { TEST_F(LayerLayerTreeHostTest, AddingLayerSubtree) { scoped_refptr<Layer> parent = Layer::Create(); LayerTreeHostFactory factory; - scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); layer_tree_host->SetRootLayer(parent.get()); @@ -1957,7 +1917,7 @@ TEST_F(LayerLayerTreeHostTest, ChangeHost) { replica->SetMaskLayer(replica_mask.get()); LayerTreeHostFactory factory; - scoped_ptr<LayerTreeHost> first_layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> first_layer_tree_host = factory.Create(); first_layer_tree_host->SetRootLayer(parent.get()); AssertLayerTreeHostMatchesForSubtree(parent.get(), @@ -1965,7 +1925,7 @@ TEST_F(LayerLayerTreeHostTest, ChangeHost) { // Now re-root the tree to a new host (simulating what we do on a context lost // event). This should update the host pointers for all layers in the tree. - scoped_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(); second_layer_tree_host->SetRootLayer(parent.get()); AssertLayerTreeHostMatchesForSubtree(parent.get(), @@ -1987,7 +1947,7 @@ TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) { first_parent->AddChild(second_child); LayerTreeHostFactory factory; - scoped_ptr<LayerTreeHost> first_layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> first_layer_tree_host = factory.Create(); first_layer_tree_host->SetRootLayer(first_parent.get()); AssertLayerTreeHostMatchesForSubtree(first_parent.get(), @@ -1995,7 +1955,7 @@ TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) { // Now reparent the subtree starting at second_child to a layer in a different // tree. - scoped_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(); second_layer_tree_host->SetRootLayer(second_parent.get()); second_parent->AddChild(second_child); @@ -2025,7 +1985,7 @@ TEST_F(LayerLayerTreeHostTest, ReplaceMaskAndReplicaLayer) { replica->AddChild(replica_child); LayerTreeHostFactory factory; - scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); layer_tree_host->SetRootLayer(parent.get()); AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get()); @@ -2049,13 +2009,13 @@ TEST_F(LayerLayerTreeHostTest, DestroyHostWithNonNullRootLayer) { scoped_refptr<Layer> child = Layer::Create(); root->AddChild(child); LayerTreeHostFactory factory; - scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); layer_tree_host->SetRootLayer(root); } TEST_F(LayerTest, SafeOpaqueBackgroundColor) { LayerTreeHostFactory factory; - scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); scoped_refptr<Layer> layer = Layer::Create(); layer_tree_host->SetRootLayer(layer); @@ -2132,7 +2092,7 @@ TEST_F(LayerTest, DrawsContentChangedInSetLayerTreeHost) { } void ReceiveCopyOutputResult(int* result_count, - scoped_ptr<CopyOutputResult> result) { + std::unique_ptr<CopyOutputResult> result) { ++(*result_count); } @@ -2142,7 +2102,7 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { // Create identical requests without the source being set, and expect the // layer does not abort either one. - scoped_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateRequest( + std::unique_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateRequest( base::Bind(&ReceiveCopyOutputResult, &result_count)); layer->RequestCopyOfOutput(std::move(request)); EXPECT_EQ(0, result_count); @@ -2493,9 +2453,27 @@ TEST_F(LayerSerializationTest, ScrollAndClipLayers) { RunScrollAndClipLayersTest(); } +TEST_F(LayerSerializationTest, SolidColorScrollbarSerialization) { + std::vector<scoped_refptr<SolidColorScrollbarLayer>> scrollbar_layers; + + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::HORIZONTAL, 20, 5, true, 3)); + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::VERTICAL, 20, 5, false, 3)); + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::HORIZONTAL, 0, 0, true, 0)); + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::VERTICAL, 10, 35, true, 3)); + + for (size_t i = 0; i < scrollbar_layers.size(); i++) { + VerifySolidColorScrollbarLayerAfterSerializationAndDeserialization( + scrollbar_layers[i]); + } +} + TEST_F(LayerTest, ElementIdAndMutablePropertiesArePushed) { scoped_refptr<Layer> test_layer = Layer::Create(); - scoped_ptr<LayerImpl> impl_layer = + std::unique_ptr<LayerImpl> impl_layer = LayerImpl::Create(host_impl_.active_tree(), 1); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, diff --git a/chromium/cc/layers/layer_utils_unittest.cc b/chromium/cc/layers/layer_utils_unittest.cc index 771d5bd5106..d41b7d06a66 100644 --- a/chromium/cc/layers/layer_utils_unittest.cc +++ b/chromium/cc/layers/layer_utils_unittest.cc @@ -56,7 +56,8 @@ class LayerUtilsGetAnimationBoundsTest : public testing::Test { private: static LayerImpl* CreateTwoForkTree(LayerTreeHostImpl* host_impl) { - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl->active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl->active_tree(), 1); LayerImpl* root_ptr = root.get(); root->AddChild(LayerImpl::Create(host_impl->active_tree(), 2)); root->children()[0]->AddChild( @@ -209,8 +210,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, RotateXNoPerspective) { child1()->SetDrawsContent(true); child1()->SetPosition(gfx::PointF(150.f, 50.f)); child1()->SetBounds(bounds); - child1()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0)); + child1()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0); host_impl().active_tree()->BuildPropertyTreesForTesting(); @@ -234,8 +235,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, RotateXWithPerspective) { // Make the anchor point not the default 0.5 value and line up with the // child center to make the math easier. - parent1()->SetTransformOrigin( - gfx::Point3F(0.375f * 400.f, 0.375f * 400.f, 0.f)); + parent1()->test_properties()->transform_origin = + gfx::Point3F(0.375f * 400.f, 0.375f * 400.f, 0.f); parent1()->SetBounds(gfx::Size(400, 400)); gfx::Transform perspective; @@ -246,8 +247,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, RotateXWithPerspective) { child1()->SetDrawsContent(true); child1()->SetPosition(gfx::PointF(100.f, 100.f)); child1()->SetBounds(bounds); - child1()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0)); + child1()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0); host_impl().active_tree()->BuildPropertyTreesForTesting(); @@ -275,8 +276,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, RotateXWithPerspectiveOnSameLayer) { // Make the anchor point not the default 0.5 value and line up // with the child center to make the math easier. - parent1()->SetTransformOrigin( - gfx::Point3F(0.375f * 400.f, 0.375f * 400.f, 0.f)); + parent1()->test_properties()->transform_origin = + gfx::Point3F(0.375f * 400.f, 0.375f * 400.f, 0.f); parent1()->SetBounds(gfx::Size(400, 400)); gfx::Transform perspective; @@ -287,8 +288,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, RotateXWithPerspectiveOnSameLayer) { child1()->SetDrawsContent(true); child1()->SetPosition(gfx::PointF(100.f, 100.f)); child1()->SetBounds(bounds); - child1()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0)); + child1()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0); host_impl().active_tree()->BuildPropertyTreesForTesting(); @@ -315,8 +316,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, RotateZ) { child1()->SetDrawsContent(true); child1()->SetPosition(gfx::PointF(150.f, 50.f)); child1()->SetBounds(bounds); - child1()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0)); + child1()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0); host_impl().active_tree()->BuildPropertyTreesForTesting(); @@ -415,8 +416,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, gfx::Size bounds(100, 100); grand_child()->SetPosition(gfx::PointF(150.f, 50.f)); grand_child()->SetBounds(bounds); - grand_child()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0)); + grand_child()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0); great_grand_child()->SetPosition(gfx::PointF(25.f, 25.f)); great_grand_child()->SetBounds(gfx::Size(50.f, 50.f)); @@ -467,11 +468,11 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, grand_child()->SetPosition(gfx::PointF(150.f, 50.f)); grand_child()->SetBounds(bounds); grand_child()->SetTransform(perspective); - grand_child()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0)); + grand_child()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0); - great_grand_child()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.25f, bounds.height() * 0.25f, 0)); + great_grand_child()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.25f, bounds.height() * 0.25f, 0); great_grand_child()->SetPosition(gfx::PointF(25.f, 25.f)); great_grand_child()->SetBounds(gfx::Size(50.f, 50.f)); great_grand_child()->SetDrawsContent(true); @@ -545,8 +546,8 @@ TEST_F(LayerUtilsGetAnimationBoundsTest, grand_child()->SetPosition(gfx::PointF(150.f, 50.f)); grand_child()->SetBounds(bounds); - great_grand_child()->SetTransformOrigin( - gfx::Point3F(bounds.width() * 0.25f, bounds.height() * 0.25f, 0)); + great_grand_child()->test_properties()->transform_origin = + gfx::Point3F(bounds.width() * 0.25f, bounds.height() * 0.25f, 0); great_grand_child()->SetPosition(gfx::PointF(25.f, 25.f)); great_grand_child()->SetBounds( gfx::Size(bounds.width() * 0.5f, bounds.height() * 0.5f)); diff --git a/chromium/cc/layers/nine_patch_layer.cc b/chromium/cc/layers/nine_patch_layer.cc index e2dc92f344e..b68891cf51e 100644 --- a/chromium/cc/layers/nine_patch_layer.cc +++ b/chromium/cc/layers/nine_patch_layer.cc @@ -21,7 +21,7 @@ NinePatchLayer::NinePatchLayer() NinePatchLayer::~NinePatchLayer() {} -scoped_ptr<LayerImpl> NinePatchLayer::CreateLayerImpl( +std::unique_ptr<LayerImpl> NinePatchLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return NinePatchLayerImpl::Create(tree_impl, id()); } diff --git a/chromium/cc/layers/nine_patch_layer.h b/chromium/cc/layers/nine_patch_layer.h index 20b5e493414..1c2d7259e3e 100644 --- a/chromium/cc/layers/nine_patch_layer.h +++ b/chromium/cc/layers/nine_patch_layer.h @@ -5,8 +5,9 @@ #ifndef CC_LAYERS_NINE_PATCH_LAYER_H_ #define CC_LAYERS_NINE_PATCH_LAYER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/layers/layer.h" #include "cc/layers/ui_resource_layer.h" @@ -44,7 +45,7 @@ class CC_EXPORT NinePatchLayer : public UIResourceLayer { private: NinePatchLayer(); ~NinePatchLayer() override; - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; gfx::Rect border_; bool fill_center_; diff --git a/chromium/cc/layers/nine_patch_layer_impl.cc b/chromium/cc/layers/nine_patch_layer_impl.cc index 933bf60775a..731837f7a14 100644 --- a/chromium/cc/layers/nine_patch_layer_impl.cc +++ b/chromium/cc/layers/nine_patch_layer_impl.cc @@ -21,7 +21,7 @@ NinePatchLayerImpl::NinePatchLayerImpl(LayerTreeImpl* tree_impl, int id) NinePatchLayerImpl::~NinePatchLayerImpl() {} -scoped_ptr<LayerImpl> NinePatchLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> NinePatchLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return NinePatchLayerImpl::Create(tree_impl, id()); } @@ -225,7 +225,7 @@ void NinePatchLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, layer_top_left, opaque_rect, visible_rect, resource, premultiplied_alpha, uv_top_left.origin(), uv_top_left.bottom_right(), SK_ColorTRANSPARENT, - vertex_opacity, flipped, nearest_neighbor_); + vertex_opacity, flipped, nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -239,7 +239,7 @@ void NinePatchLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, layer_top_right, opaque_rect, visible_rect, resource, premultiplied_alpha, uv_top_right.origin(), uv_top_right.bottom_right(), SK_ColorTRANSPARENT, - vertex_opacity, flipped, nearest_neighbor_); + vertex_opacity, flipped, nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -254,7 +254,7 @@ void NinePatchLayerImpl::AppendQuads( visible_rect, resource, premultiplied_alpha, uv_bottom_left.origin(), uv_bottom_left.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity, flipped, - nearest_neighbor_); + nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -269,7 +269,7 @@ void NinePatchLayerImpl::AppendQuads( visible_rect, resource, premultiplied_alpha, uv_bottom_right.origin(), uv_bottom_right.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity, flipped, - nearest_neighbor_); + nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -283,7 +283,7 @@ void NinePatchLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, layer_top, opaque_rect, visible_rect, resource, premultiplied_alpha, uv_top.origin(), uv_top.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity, - flipped, nearest_neighbor_); + flipped, nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -297,7 +297,7 @@ void NinePatchLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, layer_left, opaque_rect, visible_rect, resource, premultiplied_alpha, uv_left.origin(), uv_left.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity, - flipped, nearest_neighbor_); + flipped, nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -311,7 +311,7 @@ void NinePatchLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, layer_right, opaque_rect, layer_right, resource, premultiplied_alpha, uv_right.origin(), uv_right.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity, - flipped, nearest_neighbor_); + flipped, nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -325,7 +325,7 @@ void NinePatchLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, layer_bottom, opaque_rect, visible_rect, resource, premultiplied_alpha, uv_bottom.origin(), uv_bottom.bottom_right(), SK_ColorTRANSPARENT, vertex_opacity, - flipped, nearest_neighbor_); + flipped, nearest_neighbor_, false); ValidateQuadResources(quad); } @@ -340,7 +340,7 @@ void NinePatchLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, layer_center, opaque_rect, visible_rect, resource, premultiplied_alpha, uv_center.origin(), uv_center.bottom_right(), SK_ColorTRANSPARENT, - vertex_opacity, flipped, nearest_neighbor_); + vertex_opacity, flipped, nearest_neighbor_, false); ValidateQuadResources(quad); } } diff --git a/chromium/cc/layers/nine_patch_layer_impl.h b/chromium/cc/layers/nine_patch_layer_impl.h index 539d8e717ae..1fe8e7f2a39 100644 --- a/chromium/cc/layers/nine_patch_layer_impl.h +++ b/chromium/cc/layers/nine_patch_layer_impl.h @@ -8,6 +8,7 @@ #include <string> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" #include "cc/layers/ui_resource_layer_impl.h" @@ -24,9 +25,9 @@ namespace cc { class CC_EXPORT NinePatchLayerImpl : public UIResourceLayerImpl { public: - static scoped_ptr<NinePatchLayerImpl> Create(LayerTreeImpl* tree_impl, - int id) { - return make_scoped_ptr(new NinePatchLayerImpl(tree_impl, id)); + static std::unique_ptr<NinePatchLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new NinePatchLayerImpl(tree_impl, id)); } ~NinePatchLayerImpl() override; @@ -59,7 +60,7 @@ class CC_EXPORT NinePatchLayerImpl : public UIResourceLayerImpl { bool fill_center, bool nearest_neighbor); - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; void AppendQuads(RenderPass* render_pass, diff --git a/chromium/cc/layers/nine_patch_layer_impl_unittest.cc b/chromium/cc/layers/nine_patch_layer_impl_unittest.cc index 2dbc6832683..89cf250e666 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, const gfx::Rect& border, bool fill_center, size_t expected_quad_size) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Rect visible_layer_rect(layer_size); gfx::Rect expected_remaining(border.x(), border.y(), @@ -47,18 +47,17 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size, FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeUIResourceLayerTreeHostImpl host_impl( &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(output_surface.get()); - scoped_ptr<NinePatchLayerImpl> layer = + std::unique_ptr<NinePatchLayerImpl> layer = NinePatchLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->SetForceRenderSurface(true); - layer->draw_properties().render_target = layer.get(); + layer->test_properties()->force_render_surface = true; UIResourceId uid = 1; bool is_opaque = false; diff --git a/chromium/cc/layers/nine_patch_layer_unittest.cc b/chromium/cc/layers/nine_patch_layer_unittest.cc index 381c024bdbc..5cc14e2e76e 100644 --- a/chromium/cc/layers/nine_patch_layer_unittest.cc +++ b/chromium/cc/layers/nine_patch_layer_unittest.cc @@ -42,7 +42,7 @@ class NinePatchLayerTest : public testing::Test { FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; TEST_F(NinePatchLayerTest, SetLayerProperties) { @@ -62,7 +62,7 @@ TEST_F(NinePatchLayerTest, SetLayerProperties) { EXPECT_FALSE(test_layer->DrawsContent()); bool is_opaque = false; - scoped_ptr<ScopedUIResource> resource = ScopedUIResource::Create( + std::unique_ptr<ScopedUIResource> resource = ScopedUIResource::Create( layer_tree_host_.get(), UIResourceBitmap(gfx::Size(10, 10), is_opaque)); gfx::Rect aperture(5, 5, 1, 1); bool fill_center = true; diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc index b94766655d1..6bbcf107bb5 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.cc +++ b/chromium/cc/layers/painted_scrollbar_layer.cc @@ -15,7 +15,6 @@ #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" #include "skia/ext/platform_canvas.h" -#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSize.h" @@ -24,21 +23,22 @@ namespace cc { -scoped_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( +std::unique_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return PaintedScrollbarLayerImpl::Create( tree_impl, id(), scrollbar_->Orientation()); } scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create( - scoped_ptr<Scrollbar> scrollbar, + std::unique_ptr<Scrollbar> scrollbar, int scroll_layer_id) { return make_scoped_refptr( new PaintedScrollbarLayer(std::move(scrollbar), scroll_layer_id)); } -PaintedScrollbarLayer::PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, - int scroll_layer_id) +PaintedScrollbarLayer::PaintedScrollbarLayer( + std::unique_ptr<Scrollbar> scrollbar, + int scroll_layer_id) : scrollbar_(std::move(scrollbar)), scroll_layer_id_(scroll_layer_id), internal_contents_scale_(1.f), @@ -70,6 +70,10 @@ bool PaintedScrollbarLayer::OpacityCanAnimateOnImplThread() const { return scrollbar_->IsOverlay(); } +bool PaintedScrollbarLayer::AlwaysUseActiveTreeOpacity() const { + return true; +} + ScrollbarOrientation PaintedScrollbarLayer::orientation() const { return scrollbar_->Orientation(); } diff --git a/chromium/cc/layers/painted_scrollbar_layer.h b/chromium/cc/layers/painted_scrollbar_layer.h index 1d452bcc41d..ef0f2e87fad 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.h +++ b/chromium/cc/layers/painted_scrollbar_layer.h @@ -19,13 +19,14 @@ class ScrollbarThemeComposite; class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, public Layer { public: - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; static scoped_refptr<PaintedScrollbarLayer> Create( - scoped_ptr<Scrollbar> scrollbar, + std::unique_ptr<Scrollbar> scrollbar, int scroll_layer_id); bool OpacityCanAnimateOnImplThread() const override; + bool AlwaysUseActiveTreeOpacity() const override; ScrollbarLayerInterface* ToScrollbarLayer() override; // ScrollbarLayerInterface @@ -44,7 +45,8 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, } protected: - PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id); + PaintedScrollbarLayer(std::unique_ptr<Scrollbar> scrollbar, + int scroll_layer_id); ~PaintedScrollbarLayer() override; // For unit tests @@ -77,7 +79,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, const gfx::Rect& content_rect, ScrollbarPart part); - scoped_ptr<Scrollbar> scrollbar_; + std::unique_ptr<Scrollbar> scrollbar_; int scroll_layer_id_; float internal_contents_scale_; @@ -92,8 +94,8 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, bool is_overlay_; bool has_thumb_; - scoped_ptr<ScopedUIResource> track_resource_; - scoped_ptr<ScopedUIResource> thumb_resource_; + std::unique_ptr<ScopedUIResource> track_resource_; + std::unique_ptr<ScopedUIResource> thumb_resource_; float thumb_opacity_; diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc index eb44f0dfa17..8014576a403 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc @@ -6,6 +6,7 @@ #include <algorithm> +#include "base/memory/ptr_util.h" #include "cc/input/scrollbar_animation_controller.h" #include "cc/layers/layer.h" #include "cc/quads/solid_color_draw_quad.h" @@ -17,11 +18,11 @@ namespace cc { -scoped_ptr<PaintedScrollbarLayerImpl> PaintedScrollbarLayerImpl::Create( +std::unique_ptr<PaintedScrollbarLayerImpl> PaintedScrollbarLayerImpl::Create( LayerTreeImpl* tree_impl, int id, ScrollbarOrientation orientation) { - return make_scoped_ptr( + return base::WrapUnique( new PaintedScrollbarLayerImpl(tree_impl, id, orientation)); } @@ -41,7 +42,7 @@ PaintedScrollbarLayerImpl::PaintedScrollbarLayerImpl( PaintedScrollbarLayerImpl::~PaintedScrollbarLayerImpl() {} -scoped_ptr<LayerImpl> PaintedScrollbarLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> PaintedScrollbarLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return PaintedScrollbarLayerImpl::Create(tree_impl, id(), orientation()); } @@ -111,7 +112,8 @@ void PaintedScrollbarLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, scaled_thumb_quad_rect, opaque_rect, scaled_visible_thumb_quad_rect, thumb_resource_id, premultipled_alpha, uv_top_left, uv_bottom_right, - SK_ColorTRANSPARENT, opacity, flipped, nearest_neighbor); + SK_ColorTRANSPARENT, opacity, flipped, nearest_neighbor, + false); ValidateQuadResources(quad); } @@ -131,7 +133,8 @@ void PaintedScrollbarLayerImpl::AppendQuads( quad->SetNew(shared_quad_state, scaled_track_quad_rect, opaque_rect, scaled_visible_track_quad_rect, track_resource_id, premultipled_alpha, uv_top_left, uv_bottom_right, - SK_ColorTRANSPARENT, opacity, flipped, nearest_neighbor); + SK_ColorTRANSPARENT, opacity, flipped, nearest_neighbor, + false); ValidateQuadResources(quad); } } diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.h b/chromium/cc/layers/painted_scrollbar_layer_impl.h index 8ea06ab5d8c..10c6ba63af9 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.h +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.h @@ -18,14 +18,12 @@ class ScrollView; class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { public: - static scoped_ptr<PaintedScrollbarLayerImpl> Create( - LayerTreeImpl* tree_impl, - int id, - ScrollbarOrientation orientation); + static std::unique_ptr<PaintedScrollbarLayerImpl> + Create(LayerTreeImpl* tree_impl, int id, ScrollbarOrientation orientation); ~PaintedScrollbarLayerImpl() override; // LayerImpl implementation. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; bool WillDraw(DrawMode draw_mode, diff --git a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc index f5b49b9fff8..cb969e51fdc 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc @@ -29,7 +29,7 @@ class MockScrollbar : public FakeScrollbar { TEST(PaintedScrollbarLayerTest, NeedsPaint) { FakeLayerTreeHostClient fake_client_(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; layer_tree_host_ = FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); @@ -39,7 +39,7 @@ TEST(PaintedScrollbarLayerTest, NeedsPaint) { MockScrollbar* scrollbar = new MockScrollbar(); scoped_refptr<PaintedScrollbarLayer> scrollbar_layer = - PaintedScrollbarLayer::Create(scoped_ptr<Scrollbar>(scrollbar), 1); + PaintedScrollbarLayer::Create(std::unique_ptr<Scrollbar>(scrollbar), 1); scrollbar_layer->SetIsDrawable(true); scrollbar_layer->SetBounds(gfx::Size(100, 100)); diff --git a/chromium/cc/layers/picture_image_layer.cc b/chromium/cc/layers/picture_image_layer.cc index 64d71a53445..4316812ec24 100644 --- a/chromium/cc/layers/picture_image_layer.cc +++ b/chromium/cc/layers/picture_image_layer.cc @@ -27,7 +27,7 @@ PictureImageLayer::~PictureImageLayer() { ClearClient(); } -scoped_ptr<LayerImpl> PictureImageLayer::CreateLayerImpl( +std::unique_ptr<LayerImpl> PictureImageLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return PictureImageLayerImpl::Create(tree_impl, id(), is_mask()); } @@ -36,7 +36,7 @@ bool PictureImageLayer::HasDrawableContent() const { return image_ && PictureLayer::HasDrawableContent(); } -void PictureImageLayer::SetImage(skia::RefPtr<const SkImage> image) { +void PictureImageLayer::SetImage(sk_sp<const SkImage> image) { // SetImage() 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). diff --git a/chromium/cc/layers/picture_image_layer.h b/chromium/cc/layers/picture_image_layer.h index 88dd2c91b7e..7c27fd89ae4 100644 --- a/chromium/cc/layers/picture_image_layer.h +++ b/chromium/cc/layers/picture_image_layer.h @@ -11,7 +11,7 @@ #include "cc/base/cc_export.h" #include "cc/layers/content_layer_client.h" #include "cc/layers/picture_layer.h" -#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/geometry/size.h" class SkImage; @@ -22,10 +22,10 @@ class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient { public: static scoped_refptr<PictureImageLayer> Create(); - void SetImage(skia::RefPtr<const SkImage> image); + void SetImage(sk_sp<const SkImage> image); // Layer implementation. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; gfx::Rect PaintableRegion() override; @@ -42,7 +42,7 @@ class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient { PictureImageLayer(); ~PictureImageLayer() override; - skia::RefPtr<const SkImage> image_; + sk_sp<const SkImage> image_; DISALLOW_COPY_AND_ASSIGN(PictureImageLayer); }; diff --git a/chromium/cc/layers/picture_image_layer_impl.cc b/chromium/cc/layers/picture_image_layer_impl.cc index c816986d6a1..eeae33c367a 100644 --- a/chromium/cc/layers/picture_image_layer_impl.cc +++ b/chromium/cc/layers/picture_image_layer_impl.cc @@ -23,7 +23,7 @@ const char* PictureImageLayerImpl::LayerTypeAsString() const { return "cc::PictureImageLayerImpl"; } -scoped_ptr<LayerImpl> PictureImageLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> PictureImageLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return PictureImageLayerImpl::Create(tree_impl, id(), is_mask_); } diff --git a/chromium/cc/layers/picture_image_layer_impl.h b/chromium/cc/layers/picture_image_layer_impl.h index 759606a2f45..723990599e5 100644 --- a/chromium/cc/layers/picture_image_layer_impl.h +++ b/chromium/cc/layers/picture_image_layer_impl.h @@ -6,22 +6,23 @@ #define CC_LAYERS_PICTURE_IMAGE_LAYER_IMPL_H_ #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/layers/picture_layer_impl.h" namespace cc { class CC_EXPORT PictureImageLayerImpl : public PictureLayerImpl { public: - static scoped_ptr<PictureImageLayerImpl> Create(LayerTreeImpl* tree_impl, - int id, - bool is_mask) { - return make_scoped_ptr(new PictureImageLayerImpl(tree_impl, id, is_mask)); + static std::unique_ptr<PictureImageLayerImpl> Create(LayerTreeImpl* tree_impl, + int id, + bool is_mask) { + return base::WrapUnique(new PictureImageLayerImpl(tree_impl, id, is_mask)); } ~PictureImageLayerImpl() override; // LayerImpl overrides. const char* LayerTypeAsString() const override; - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; protected: PictureImageLayerImpl(LayerTreeImpl* tree_impl, int id, bool is_mask); diff --git a/chromium/cc/layers/picture_image_layer_impl_unittest.cc b/chromium/cc/layers/picture_image_layer_impl_unittest.cc index 63dd21b9586..9027d4a6eae 100644 --- a/chromium/cc/layers/picture_image_layer_impl_unittest.cc +++ b/chromium/cc/layers/picture_image_layer_impl_unittest.cc @@ -4,7 +4,8 @@ #include "cc/layers/picture_image_layer_impl.h" -#include "base/thread_task_runner_handle.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/layers/append_quads_data.h" #include "cc/quads/draw_quad.h" #include "cc/test/fake_impl_task_runner_provider.h" @@ -25,8 +26,9 @@ class TestablePictureImageLayerImpl : public PictureImageLayerImpl { TestablePictureImageLayerImpl(LayerTreeImpl* tree_impl, int id) : PictureImageLayerImpl(tree_impl, id, false) {} - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { - return make_scoped_ptr(new TestablePictureImageLayerImpl(tree_impl, id())); + std::unique_ptr<LayerImpl> CreateLayerImpl( + LayerTreeImpl* tree_impl) override { + return base::WrapUnique(new TestablePictureImageLayerImpl(tree_impl, id())); } using PictureLayerImpl::UpdateIdealScales; @@ -58,8 +60,9 @@ class PictureImageLayerImplTest : public testing::Test { host_impl_.InitializeRenderer(output_surface_.get()); } - scoped_ptr<TestablePictureImageLayerImpl> CreateLayer(int id, - WhichTree which_tree) { + std::unique_ptr<TestablePictureImageLayerImpl> CreateLayer( + int id, + WhichTree which_tree) { LayerTreeImpl* tree = nullptr; switch (which_tree) { case ACTIVE_TREE: @@ -73,7 +76,7 @@ class PictureImageLayerImplTest : public testing::Test { new TestablePictureImageLayerImpl(tree, id); layer->raster_source_ = FakeRasterSource::CreateInfiniteFilled(); layer->SetBounds(layer->raster_source_->GetSize()); - return make_scoped_ptr(layer); + return base::WrapUnique(layer); } void SetupDrawPropertiesAndUpdateTiles(TestablePictureImageLayerImpl* layer, @@ -86,6 +89,7 @@ class PictureImageLayerImplTest : public testing::Test { gfx::Transform scale_transform; scale_transform.Scale(ideal_contents_scale, ideal_contents_scale); layer->draw_properties().target_space_transform = scale_transform; + layer->set_is_drawn_render_surface_layer_list_member(true); DCHECK_EQ(layer->GetIdealContentsScale(), ideal_contents_scale); layer->draw_properties().maximum_animation_contents_scale = maximum_animation_contents_scale; @@ -99,12 +103,13 @@ class PictureImageLayerImplTest : public testing::Test { FakeImplTaskRunnerProvider task_runner_provider_; TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<OutputSurface> output_surface_; + std::unique_ptr<OutputSurface> output_surface_; FakeLayerTreeHostImpl host_impl_; }; TEST_F(PictureImageLayerImplTest, CalculateContentsScale) { - scoped_ptr<TestablePictureImageLayerImpl> layer(CreateLayer(1, PENDING_TREE)); + std::unique_ptr<TestablePictureImageLayerImpl> layer( + CreateLayer(1, PENDING_TREE)); layer->SetDrawsContent(true); TestablePictureImageLayerImpl* layer_ptr = layer.get(); @@ -118,7 +123,7 @@ TEST_F(PictureImageLayerImplTest, CalculateContentsScale) { } TEST_F(PictureImageLayerImplTest, IgnoreIdealContentScale) { - scoped_ptr<TestablePictureImageLayerImpl> pending_layer( + std::unique_ptr<TestablePictureImageLayerImpl> pending_layer( CreateLayer(1, PENDING_TREE)); pending_layer->SetDrawsContent(true); @@ -161,7 +166,7 @@ TEST_F(PictureImageLayerImplTest, IgnoreIdealContentScale) { active_layer->tilings()->tiling_at(0)->AllTilesForTesting()); // Draw. - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; active_layer->WillDraw(DRAW_MODE_SOFTWARE, nullptr); active_layer->AppendQuads(render_pass.get(), &data); diff --git a/chromium/cc/layers/picture_image_layer_unittest.cc b/chromium/cc/layers/picture_image_layer_unittest.cc index fb0f2062466..a741e74c71f 100644 --- a/chromium/cc/layers/picture_image_layer_unittest.cc +++ b/chromium/cc/layers/picture_image_layer_unittest.cc @@ -21,7 +21,7 @@ TEST(PictureImageLayerTest, PaintContentsToDisplayList) { scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create(); FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client, &task_graph_runner); layer->SetLayerTreeHost(host.get()); gfx::Rect layer_rect(200, 200); @@ -38,9 +38,7 @@ TEST(PictureImageLayerTest, PaintContentsToDisplayList) { 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); - skia::RefPtr<const SkImage> image = - skia::AdoptRef(image_surface->newImageSnapshot()); - layer->SetImage(std::move(image)); + layer->SetImage(image_surface->makeImageSnapshot()); layer->SetBounds(gfx::Size(layer_rect.width(), layer_rect.height())); scoped_refptr<DisplayItemList> display_list = diff --git a/chromium/cc/layers/picture_layer.cc b/chromium/cc/layers/picture_layer.cc index 9daded8df16..526c7a498e7 100644 --- a/chromium/cc/layers/picture_layer.cc +++ b/chromium/cc/layers/picture_layer.cc @@ -31,7 +31,7 @@ PictureLayer::PictureLayer(ContentLayerClient* client) nearest_neighbor_(false) {} PictureLayer::PictureLayer(ContentLayerClient* client, - scoped_ptr<RecordingSource> source) + std::unique_ptr<RecordingSource> source) : PictureLayer(client) { recording_source_ = std::move(source); } @@ -39,7 +39,8 @@ PictureLayer::PictureLayer(ContentLayerClient* client, PictureLayer::~PictureLayer() { } -scoped_ptr<LayerImpl> PictureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { +std::unique_ptr<LayerImpl> PictureLayer::CreateLayerImpl( + LayerTreeImpl* tree_impl) { return PictureLayerImpl::Create(tree_impl, id(), is_mask_); } @@ -135,7 +136,7 @@ sk_sp<SkPicture> PictureLayer::GetPicture() const { return nullptr; gfx::Size layer_size = bounds(); - scoped_ptr<RecordingSource> recording_source(new RecordingSource); + std::unique_ptr<RecordingSource> recording_source(new RecordingSource); Region recording_invalidation; recording_source->UpdateAndExpandInvalidation( client_, &recording_invalidation, layer_size, update_source_frame_number_, diff --git a/chromium/cc/layers/picture_layer.h b/chromium/cc/layers/picture_layer.h index a750c9520de..5bafbe5829a 100644 --- a/chromium/cc/layers/picture_layer.h +++ b/chromium/cc/layers/picture_layer.h @@ -26,7 +26,7 @@ class CC_EXPORT PictureLayer : public Layer { void SetNearestNeighbor(bool nearest_neighbor); // Layer interface. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void SetLayerTreeHost(LayerTreeHost* host) override; void PushPropertiesTo(LayerImpl* layer) override; void SetNeedsDisplayRect(const gfx::Rect& layer_rect) override; @@ -46,7 +46,8 @@ class CC_EXPORT PictureLayer : public Layer { protected: explicit PictureLayer(ContentLayerClient* client); // Allow tests to inject a recording source. - PictureLayer(ContentLayerClient* client, scoped_ptr<RecordingSource> source); + PictureLayer(ContentLayerClient* client, + std::unique_ptr<RecordingSource> source); ~PictureLayer() override; bool HasDrawableContent() const override; @@ -63,7 +64,7 @@ class CC_EXPORT PictureLayer : public Layer { void DropRecordingSourceContentIfInvalid(); ContentLayerClient* client_; - scoped_ptr<RecordingSource> recording_source_; + std::unique_ptr<RecordingSource> recording_source_; devtools_instrumentation:: ScopedLayerObjectTracker instrumentation_object_tracker_; diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc index b6ecf848cac..0cf42f07a13 100644 --- a/chromium/cc/layers/picture_layer_impl.cc +++ b/chromium/cc/layers/picture_layer_impl.cc @@ -69,6 +69,7 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, ideal_device_scale_(0.f), ideal_source_scale_(0.f), ideal_contents_scale_(0.f), + last_ideal_source_scale_(0.f), raster_page_scale_(0.f), raster_device_scale_(0.f), raster_source_scale_(0.f), @@ -92,7 +93,7 @@ const char* PictureLayerImpl::LayerTypeAsString() const { return "cc::PictureLayerImpl"; } -scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return PictureLayerImpl::Create(tree_impl, id(), is_mask_); } @@ -433,6 +434,17 @@ bool PictureLayerImpl::UpdateTiles() { AddTilingsForRasterScale(); } + // Inform layer tree impl if we will have blurry content because of fixed + // raster scale (note that this check should happen after we + // ReclaculateRasterScales, since that's the function that will determine + // whether our raster scale is fixed. + if (raster_source_scale_is_fixed_ && !has_will_change_transform_hint()) { + if (raster_source_scale_ != ideal_source_scale_) + layer_tree_impl()->SetFixedRasterScaleHasBlurryContent(); + if (ideal_source_scale_ != last_ideal_source_scale_) + layer_tree_impl()->SetFixedRasterScaleAttemptedToChangeScale(); + } + if (layer_tree_impl()->IsActiveTree()) AddLowResolutionTilingIfNeeded(); @@ -510,7 +522,7 @@ void PictureLayerImpl::UpdateViewportRectForTilePriorityInContentSpace() { gfx::Rect padded_bounds(bounds()); int padding_amount = layer_tree_impl() ->settings() - .skewport_extrapolation_limit_in_content_pixels * + .skewport_extrapolation_limit_in_screen_pixels * MaximumTilingContentsScale(); padded_bounds.Inset(-padding_amount, -padding_amount); visible_rect_in_content_space.Intersect(padded_bounds); @@ -1184,7 +1196,7 @@ float PictureLayerImpl::MaximumTilingContentsScale() const { return std::max(max_contents_scale, MinimumContentsScale()); } -scoped_ptr<PictureLayerTilingSet> +std::unique_ptr<PictureLayerTilingSet> PictureLayerImpl::CreatePictureLayerTilingSet() { const LayerTreeSettings& settings = layer_tree_impl()->settings(); return PictureLayerTilingSet::Create( @@ -1192,7 +1204,7 @@ PictureLayerImpl::CreatePictureLayerTilingSet() { layer_tree_impl()->use_gpu_rasterization() ? settings.gpu_rasterization_skewport_target_time_in_seconds : settings.skewport_target_time_in_seconds, - settings.skewport_extrapolation_limit_in_content_pixels); + settings.skewport_extrapolation_limit_in_screen_pixels); } void PictureLayerImpl::UpdateIdealScales() { @@ -1206,6 +1218,7 @@ void PictureLayerImpl::UpdateIdealScales() { : 1.f; ideal_device_scale_ = layer_tree_impl()->device_scale_factor(); ideal_contents_scale_ = std::max(GetIdealContentsScale(), min_contents_scale); + last_ideal_source_scale_ = ideal_source_scale_; ideal_source_scale_ = ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_; } @@ -1280,7 +1293,8 @@ bool PictureLayerImpl::IsOnActiveOrPendingTree() const { } bool PictureLayerImpl::HasValidTilePriorities() const { - return IsOnActiveOrPendingTree() && IsDrawnRenderSurfaceLayerListMember(); + return IsOnActiveOrPendingTree() && + is_drawn_render_surface_layer_list_member(); } } // namespace cc diff --git a/chromium/cc/layers/picture_layer_impl.h b/chromium/cc/layers/picture_layer_impl.h index c25f19f94ab..17108518fdf 100644 --- a/chromium/cc/layers/picture_layer_impl.h +++ b/chromium/cc/layers/picture_layer_impl.h @@ -12,6 +12,7 @@ #include <vector> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" #include "cc/tiles/picture_layer_tiling.h" @@ -28,10 +29,10 @@ class CC_EXPORT PictureLayerImpl : public LayerImpl, NON_EXPORTED_BASE(public PictureLayerTilingClient) { public: - static scoped_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl, - int id, - bool is_mask) { - return make_scoped_ptr(new PictureLayerImpl(tree_impl, id, is_mask)); + static std::unique_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl, + int id, + bool is_mask) { + return base::WrapUnique(new PictureLayerImpl(tree_impl, id, is_mask)); } ~PictureLayerImpl() override; @@ -39,7 +40,7 @@ class CC_EXPORT PictureLayerImpl // LayerImpl overrides. const char* LayerTypeAsString() const override; - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; void AppendQuads(RenderPass* render_pass, AppendQuadsData* append_quads_data) override; @@ -92,9 +93,6 @@ class CC_EXPORT PictureLayerImpl RasterSource* GetRasterSource() const { return raster_source_.get(); } protected: - friend class LayerRasterTileIterator; - using TileRequirementCheck = bool (PictureLayerTiling::*)(const Tile*) const; - PictureLayerImpl(LayerTreeImpl* tree_impl, int id, bool is_mask); PictureLayerTiling* AddTiling(float contents_scale); void RemoveAllTilings(); @@ -120,11 +118,11 @@ class CC_EXPORT PictureLayerImpl virtual void UpdateIdealScales(); float MaximumTilingContentsScale() const; - scoped_ptr<PictureLayerTilingSet> CreatePictureLayerTilingSet(); + std::unique_ptr<PictureLayerTilingSet> CreatePictureLayerTilingSet(); PictureLayerImpl* twin_layer_; - scoped_ptr<PictureLayerTilingSet> tilings_; + std::unique_ptr<PictureLayerTilingSet> tilings_; scoped_refptr<RasterSource> raster_source_; Region invalidation_; @@ -132,6 +130,9 @@ class CC_EXPORT PictureLayerImpl float ideal_device_scale_; float ideal_source_scale_; float ideal_contents_scale_; + // This refers to the ideal scale from the previous frame (or a previous time + // the ideal scale was updated). + float last_ideal_source_scale_; float raster_page_scale_; float raster_device_scale_; diff --git a/chromium/cc/layers/picture_layer_impl_perftest.cc b/chromium/cc/layers/picture_layer_impl_perftest.cc index 72d135371a9..807b0630973 100644 --- a/chromium/cc/layers/picture_layer_impl_perftest.cc +++ b/chromium/cc/layers/picture_layer_impl_perftest.cc @@ -5,7 +5,7 @@ #include "cc/layers/picture_layer_impl.h" #include "base/macros.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/debug/lap_timer.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host_impl.h" @@ -63,11 +63,11 @@ class PictureLayerImplPerfTest : public testing::Test { LayerTreeImpl* pending_tree = host_impl_.pending_tree(); pending_tree->ClearLayers(); - scoped_ptr<FakePictureLayerImpl> pending_layer = + std::unique_ptr<FakePictureLayerImpl> pending_layer = FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 7, raster_source); pending_layer->SetDrawsContent(true); - pending_layer->SetForceRenderSurface(true); + pending_layer->test_properties()->force_render_surface = true; pending_tree->SetRootLayer(std::move(pending_layer)); pending_tree->BuildPropertyTreesForTesting(); @@ -85,8 +85,9 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.Reset(); do { int count = num_tiles; - scoped_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + std::unique_ptr<TilingSetRasterQueueAll> queue( + new TilingSetRasterQueueAll( + pending_layer_->picture_layer_tiling_set(), false)); while (count--) { ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count; ASSERT_TRUE(queue->Top().tile()) << "count: " << count; @@ -112,8 +113,9 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.Reset(); do { - scoped_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + std::unique_ptr<TilingSetRasterQueueAll> queue( + new TilingSetRasterQueueAll( + pending_layer_->picture_layer_tiling_set(), false)); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); @@ -132,7 +134,7 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.Reset(); do { int count = num_tiles; - scoped_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue( + std::unique_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue( pending_layer_->picture_layer_tiling_set())); while (count--) { ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count; @@ -160,7 +162,7 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.Reset(); do { - scoped_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue( + std::unique_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue( pending_layer_->picture_layer_tiling_set())); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); @@ -173,7 +175,7 @@ class PictureLayerImplPerfTest : public testing::Test { TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeImplTaskRunnerProvider task_runner_provider_; - scoped_ptr<OutputSurface> output_surface_; + std::unique_ptr<OutputSurface> output_surface_; FakeLayerTreeHostImpl host_impl_; FakePictureLayerImpl* pending_layer_; LapTimer timer_; diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc index 61590501c94..f9eea01f7f4 100644 --- a/chromium/cc/layers/picture_layer_impl_unittest.cc +++ b/chromium/cc/layers/picture_layer_impl_unittest.cc @@ -13,7 +13,7 @@ #include "base/location.h" #include "base/macros.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/base/math_util.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/picture_layer.h" @@ -30,6 +30,7 @@ #include "cc/test/geometry_test_utils.h" #include "cc/test/gpu_rasterization_enabled_settings.h" #include "cc/test/layer_test_common.h" +#include "cc/test/test_layer_tree_host_base.h" #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" @@ -43,28 +44,28 @@ namespace cc { namespace { -#define EXPECT_BOTH_EQ(expression, x) \ - do { \ - EXPECT_EQ(x, pending_layer_->expression); \ - EXPECT_EQ(x, active_layer_->expression); \ +#define EXPECT_BOTH_EQ(expression, x) \ + do { \ + EXPECT_EQ(x, pending_layer()->expression); \ + EXPECT_EQ(x, active_layer()->expression); \ } while (false) -#define EXPECT_BOTH_NE(expression, x) \ - do { \ - EXPECT_NE(x, pending_layer_->expression); \ - EXPECT_NE(x, active_layer_->expression); \ +#define EXPECT_BOTH_NE(expression, x) \ + do { \ + EXPECT_NE(x, pending_layer()->expression); \ + EXPECT_NE(x, active_layer()->expression); \ } while (false) -#define EXPECT_BOTH_TRUE(expression) \ - do { \ - EXPECT_TRUE(pending_layer_->expression); \ - EXPECT_TRUE(active_layer_->expression); \ +#define EXPECT_BOTH_TRUE(expression) \ + do { \ + EXPECT_TRUE(pending_layer()->expression); \ + EXPECT_TRUE(active_layer()->expression); \ } while (false) -#define EXPECT_BOTH_FALSE(expression) \ - do { \ - EXPECT_FALSE(pending_layer_->expression); \ - EXPECT_FALSE(active_layer_->expression); \ +#define EXPECT_BOTH_FALSE(expression) \ + do { \ + EXPECT_FALSE(pending_layer()->expression); \ + EXPECT_FALSE(active_layer()->expression); \ } while (false) class MockCanvas : public SkCanvas { @@ -79,192 +80,78 @@ class MockCanvas : public SkCanvas { std::vector<SkRect> rects_; }; -class PictureLayerImplTestSettings : public GpuRasterizationEnabledSettings { - public: - PictureLayerImplTestSettings() { - layer_transforms_should_scale_layer_contents = true; - } -}; - -class NoLowResTilingsSettings : public PictureLayerImplTestSettings {}; - -class LowResTilingsSettings : public PictureLayerImplTestSettings { - public: - LowResTilingsSettings() { create_low_res_tiling = true; } -}; - -class PictureLayerImplTest : public testing::Test { +class PictureLayerImplTest : public TestLayerTreeHostBase { public: - explicit PictureLayerImplTest(const LayerTreeSettings& settings) - : task_runner_provider_(base::ThreadTaskRunnerHandle::Get()), - output_surface_(FakeOutputSurface::Create3d()), - host_impl_(settings, - &task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_), - root_id_(6), - id_(7), - pending_layer_(nullptr), - old_pending_layer_(nullptr), - active_layer_(nullptr) { - host_impl_.SetViewportSize(gfx::Size(10000, 10000)); + void SetUp() override { + TestLayerTreeHostBase::SetUp(); + host_impl()->SetViewportSize(gfx::Size(10000, 10000)); } - PictureLayerImplTest() : PictureLayerImplTest(LowResTilingsSettings()) {} - - ~PictureLayerImplTest() override {} - - void SetUp() override { InitializeRenderer(); } - - virtual void InitializeRenderer() { - host_impl_.SetVisible(true); - host_impl_.InitializeRenderer(output_surface_.get()); + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings; + settings.gpu_rasterization_enabled = true; + settings.layer_transforms_should_scale_layer_contents = true; + settings.create_low_res_tiling = true; + settings.verify_clip_tree_calculations = true; + return settings; } - void SetupDefaultTrees(const gfx::Size& layer_bounds) { - scoped_refptr<FakeRasterSource> pending_raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_refptr<FakeRasterSource> active_raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - - SetupTrees(pending_raster_source, active_raster_source); - } - - void SetupDefaultTreesWithInvalidation(const gfx::Size& layer_bounds, - const Region& invalidation) { + void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds, + const gfx::Size& tile_size, + const Region& invalidation) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); scoped_refptr<FakeRasterSource> active_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - SetupTreesWithInvalidation(pending_raster_source, active_raster_source, - invalidation); + SetupTreesWithFixedTileSize(std::move(pending_raster_source), + std::move(active_raster_source), tile_size, + invalidation); } - void RebuildPropertyTreesOnPendingTree() { - host_impl_.pending_tree()->property_trees()->needs_rebuild = true; - host_impl_.pending_tree()->BuildPropertyTreesForTesting(); - } - - void ActivateTree() { - RebuildPropertyTreesOnPendingTree(); - host_impl_.ActivateSyncTree(); - CHECK(!host_impl_.pending_tree()); - CHECK(host_impl_.recycle_tree()); - old_pending_layer_ = pending_layer_; - pending_layer_ = nullptr; - active_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.active_tree()->LayerById(id_)); - - bool update_lcd_text = false; - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); + void SetupTreesWithFixedTileSize( + scoped_refptr<RasterSource> pending_raster_source, + scoped_refptr<RasterSource> active_raster_source, + const gfx::Size& tile_size, + const Region& pending_invalidation) { + SetupPendingTree(std::move(active_raster_source), tile_size, Region()); + ActivateTree(); + SetupPendingTree(std::move(pending_raster_source), tile_size, + pending_invalidation); } - void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds, - const gfx::Size& tile_size, - const Region& invalidation) { + void SetupDefaultTreesWithInvalidation(const gfx::Size& layer_bounds, + const Region& invalidation) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); scoped_refptr<FakeRasterSource> active_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - SetupTreesWithFixedTileSize(pending_raster_source, active_raster_source, - tile_size, invalidation); - } - - void SetupTrees(scoped_refptr<RasterSource> pending_raster_source, - scoped_refptr<RasterSource> active_raster_source) { - SetupPendingTree(active_raster_source); - ActivateTree(); - SetupPendingTreeInternal(pending_raster_source, gfx::Size(), Region()); + SetupTreesWithInvalidation(std::move(pending_raster_source), + std::move(active_raster_source), invalidation); } void SetupTreesWithInvalidation( scoped_refptr<RasterSource> pending_raster_source, scoped_refptr<RasterSource> active_raster_source, const Region& pending_invalidation) { - SetupPendingTreeInternal(active_raster_source, gfx::Size(), Region()); - ActivateTree(); - SetupPendingTreeInternal(pending_raster_source, gfx::Size(), - pending_invalidation); - } - - void SetupTreesWithFixedTileSize( - scoped_refptr<RasterSource> pending_raster_source, - scoped_refptr<RasterSource> active_raster_source, - const gfx::Size& tile_size, - const Region& pending_invalidation) { - SetupPendingTreeInternal(active_raster_source, tile_size, Region()); + SetupPendingTree(std::move(active_raster_source), gfx::Size(), Region()); ActivateTree(); - SetupPendingTreeInternal(pending_raster_source, tile_size, - pending_invalidation); - } - - void SetupPendingTree(scoped_refptr<RasterSource> raster_source) { - SetupPendingTreeInternal(raster_source, gfx::Size(), Region()); + SetupPendingTree(std::move(pending_raster_source), gfx::Size(), + pending_invalidation); } void SetupPendingTreeWithInvalidation( scoped_refptr<RasterSource> raster_source, const Region& invalidation) { - SetupPendingTreeInternal(raster_source, gfx::Size(), invalidation); + SetupPendingTree(std::move(raster_source), gfx::Size(), invalidation); } void SetupPendingTreeWithFixedTileSize( scoped_refptr<RasterSource> raster_source, const gfx::Size& tile_size, const Region& invalidation) { - SetupPendingTreeInternal(raster_source, tile_size, invalidation); - } - - void SetupPendingTreeInternal(scoped_refptr<RasterSource> raster_source, - const gfx::Size& tile_size, - const Region& invalidation) { - host_impl_.CreatePendingTree(); - host_impl_.pending_tree()->PushPageScaleFromMainThread(1.f, 0.00001f, - 100000.f); - LayerTreeImpl* pending_tree = host_impl_.pending_tree(); - pending_tree->SetDeviceScaleFactor( - host_impl_.active_tree()->device_scale_factor()); - - // Steal from the recycled tree if possible. - LayerImpl* pending_root = pending_tree->root_layer(); - scoped_ptr<FakePictureLayerImpl> pending_layer; - DCHECK(!pending_root || pending_root->id() == root_id_); - if (!pending_root) { - scoped_ptr<LayerImpl> new_pending_root = - LayerImpl::Create(pending_tree, root_id_); - pending_layer = FakePictureLayerImpl::Create(pending_tree, id_); - if (!tile_size.IsEmpty()) - pending_layer->set_fixed_tile_size(tile_size); - pending_layer->SetDrawsContent(true); - pending_layer->SetScrollClipLayer(new_pending_root->id()); - pending_root = new_pending_root.get(); - pending_tree->SetRootLayer(std::move(new_pending_root)); - } else { - pending_layer.reset(static_cast<FakePictureLayerImpl*>( - pending_root->RemoveChildForTesting(pending_root->children()[0]) - .release())); - if (!tile_size.IsEmpty()) - pending_layer->set_fixed_tile_size(tile_size); - } - pending_root->SetForceRenderSurface(true); - // The bounds() just mirror the raster source size. - pending_layer->SetBounds(raster_source->GetSize()); - pending_layer->SetRasterSourceOnPending(raster_source, invalidation); - - pending_root->AddChild(std::move(pending_layer)); - pending_tree->SetViewportLayersFromIds( - Layer::INVALID_ID, pending_tree->root_layer()->id(), Layer::INVALID_ID, - Layer::INVALID_ID); - - pending_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.pending_tree()->LayerById(id_)); - - // Add tilings/tiles for the layer. - bool update_lcd_text = false; - RebuildPropertyTreesOnPendingTree(); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + SetupPendingTree(std::move(raster_source), tile_size, invalidation); } void SetupDrawProperties(FakePictureLayerImpl* layer, @@ -275,11 +162,12 @@ class PictureLayerImplTest : public testing::Test { float starting_animation_contents_scale, bool animating_transform_to_screen) { layer->layer_tree_impl()->SetDeviceScaleFactor(device_scale_factor); - host_impl_.active_tree()->SetPageScaleOnActiveTree(page_scale_factor); + host_impl()->active_tree()->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; + layer->set_is_drawn_render_surface_layer_list_member(true); DCHECK_EQ(layer->GetIdealContentsScale(), ideal_contents_scale); layer->draw_properties().maximum_animation_contents_scale = maximum_animation_contents_scale; @@ -327,29 +215,29 @@ class PictureLayerImplTest : public testing::Test { float starting_animation_contents_scale, bool animating_transform) { SetupDrawPropertiesAndUpdateTiles( - pending_layer_, contents_scale, device_scale_factor, page_scale_factor, + pending_layer(), contents_scale, device_scale_factor, page_scale_factor, maximum_animation_contents_scale, starting_animation_contents_scale, animating_transform); SetupDrawPropertiesAndUpdateTiles( - active_layer_, contents_scale, device_scale_factor, page_scale_factor, + active_layer(), contents_scale, device_scale_factor, page_scale_factor, maximum_animation_contents_scale, starting_animation_contents_scale, animating_transform); } void ResetTilingsAndRasterScales() { - if (pending_layer_) { - pending_layer_->ReleaseResources(); - EXPECT_FALSE(pending_layer_->tilings()); - pending_layer_->RecreateResources(); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); + if (pending_layer()) { + pending_layer()->ReleaseResources(); + EXPECT_FALSE(pending_layer()->tilings()); + pending_layer()->RecreateResources(); + EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings()); } - if (active_layer_) { - active_layer_->ReleaseResources(); - EXPECT_FALSE(active_layer_->tilings()); - active_layer_->RecreateResources(); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + if (active_layer()) { + active_layer()->ReleaseResources(); + EXPECT_FALSE(active_layer()->tilings()); + active_layer()->RecreateResources(); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); } } @@ -380,35 +268,23 @@ class PictureLayerImplTest : public testing::Test { void SetInitialDeviceScaleFactor(float device_scale_factor) { // Device scale factor is a per-tree property. However, tests can't directly // set the pending tree's device scale factor before the pending tree is - // created, and setting it after SetupPendingTreeInternal is too late, since + // created, and setting it after SetupPendingTreeis too late, since // draw properties will already have been updated on the tree. To handle // this, we initially set only the active tree's device scale factor, and we - // copy this over to the pending tree inside SetupPendingTreeInternal. - host_impl_.active_tree()->SetDeviceScaleFactor(device_scale_factor); + // copy this over to the pending tree inside SetupPendingTree. + host_impl()->active_tree()->SetDeviceScaleFactor(device_scale_factor); } - protected: void TestQuadsForSolidColor(bool test_for_solid); - - FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; - TestTaskGraphRunner task_graph_runner_; - scoped_ptr<OutputSurface> output_surface_; - FakeLayerTreeHostImpl host_impl_; - int root_id_; - int id_; - FakePictureLayerImpl* pending_layer_; - FakePictureLayerImpl* old_pending_layer_; - FakePictureLayerImpl* active_layer_; - - private: - DISALLOW_COPY_AND_ASSIGN(PictureLayerImplTest); }; class NoLowResPictureLayerImplTest : public PictureLayerImplTest { public: - NoLowResPictureLayerImplTest() - : PictureLayerImplTest(NoLowResTilingsSettings()) {} + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + settings.create_low_res_tiling = false; + return settings; + } }; TEST_F(PictureLayerImplTest, TileGridAlignment) { @@ -421,7 +297,7 @@ TEST_F(PictureLayerImplTest, TileGridAlignment) { FakeRasterSource::CreateFilled(layer_size); // Create an active recording source, but make sure it's not solid. - scoped_ptr<FakeRecordingSource> active_recording_source = + std::unique_ptr<FakeRecordingSource> active_recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_size); active_recording_source->SetLayerBounds(layer_size); active_recording_source->add_draw_rect(gfx::Rect(layer_size)); @@ -436,9 +312,9 @@ TEST_F(PictureLayerImplTest, TileGridAlignment) { // Add 1x1 rects at the centers of each tile, then re-record recording source // contents. - active_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); + active_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting(); std::vector<Tile*> tiles = - active_layer_->tilings()->tiling_at(0)->AllTilesForTesting(); + active_layer()->tilings()->tiling_at(0)->AllTilesForTesting(); EXPECT_EQ(16u, tiles.size()); std::vector<SkRect> rects; std::vector<Tile*>::const_iterator tile_iter; @@ -480,42 +356,42 @@ TEST_F(PictureLayerImplTest, CloneNoInvalidation) { gfx::Size layer_bounds(400, 400); SetupDefaultTrees(layer_bounds); - EXPECT_EQ(pending_layer_->tilings()->num_tilings(), - active_layer_->tilings()->num_tilings()); + EXPECT_EQ(pending_layer()->tilings()->num_tilings(), + active_layer()->tilings()->num_tilings()); - const PictureLayerTilingSet* tilings = pending_layer_->tilings(); + const PictureLayerTilingSet* tilings = pending_layer()->tilings(); EXPECT_GT(tilings->num_tilings(), 0u); for (size_t i = 0; i < tilings->num_tilings(); ++i) EXPECT_TRUE(tilings->tiling_at(i)->AllTilesForTesting().empty()); } TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(400, 400); SetupDefaultTrees(layer_bounds); - SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, 0.f, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f, false); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + 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. gfx::Rect viewport_rect_for_tile_priority = gfx::Rect(0, 0, 100, 100); gfx::Transform transform, transform_for_tile_priority; - host_impl_.SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority, - transform_for_tile_priority); + host_impl()->SetExternalTilePriorityConstraints( + viewport_rect_for_tile_priority, transform_for_tile_priority); bool update_lcd_text = false; - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text); gfx::Rect viewport_rect_for_tile_priority_in_view_space = viewport_rect_for_tile_priority; // Verify the viewport rect for tile priority is used in picture layer tiling. EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space, - active_layer_->viewport_rect_for_tile_priority_in_content_space()); - PictureLayerTilingSet* tilings = active_layer_->tilings(); + active_layer()->viewport_rect_for_tile_priority_in_content_space()); + PictureLayerTilingSet* tilings = active_layer()->tilings(); for (size_t i = 0; i < tilings->num_tilings(); i++) { PictureLayerTiling* tiling = tilings->tiling_at(i); EXPECT_EQ( @@ -528,14 +404,14 @@ 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. - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + 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); transform_for_tile_priority.Rotate(45); - host_impl_.SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority, - transform_for_tile_priority); - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->SetExternalTilePriorityConstraints( + viewport_rect_for_tile_priority, transform_for_tile_priority); + host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text); gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); bool success = transform_for_tile_priority.GetInverse(&screen_to_view); @@ -550,8 +426,8 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { viewport_rect_for_tile_priority); EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space, - active_layer_->viewport_rect_for_tile_priority_in_content_space()); - tilings = active_layer_->tilings(); + active_layer()->viewport_rect_for_tile_priority_in_content_space()); + tilings = active_layer()->tilings(); for (size_t i = 0; i < tilings->num_tilings(); i++) { PictureLayerTiling* tiling = tilings->tiling_at(i); EXPECT_EQ( @@ -562,42 +438,42 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { } TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(400, 400); SetupDefaultTrees(layer_bounds); - SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, 0.f, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f, false); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); gfx::Rect viewport_rect_for_tile_priority(0, 0, 100, 100); gfx::Transform transform_for_tile_priority; - host_impl_.SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority, - transform_for_tile_priority); + host_impl()->SetExternalTilePriorityConstraints( + viewport_rect_for_tile_priority, transform_for_tile_priority); bool update_lcd_text = false; - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text); EXPECT_EQ(viewport_rect_for_tile_priority, - active_layer_->viewport_rect_for_tile_priority_in_content_space()); + active_layer()->viewport_rect_for_tile_priority_in_content_space()); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); gfx::Rect another_viewport_rect_for_tile_priority(11, 11, 50, 50); - host_impl_.SetExternalTilePriorityConstraints( + host_impl()->SetExternalTilePriorityConstraints( another_viewport_rect_for_tile_priority, transform_for_tile_priority); // Didn't call UpdateDrawProperties yet. The viewport rect for tile priority // should remain to be the previously cached value. EXPECT_EQ(viewport_rect_for_tile_priority, - active_layer_->viewport_rect_for_tile_priority_in_content_space()); - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); + active_layer()->viewport_rect_for_tile_priority_in_content_space()); + host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text); // Now the UpdateDrawProperties is called. The viewport rect for tile // priority should be the latest value. EXPECT_EQ(another_viewport_rect_for_tile_priority, - active_layer_->viewport_rect_for_tile_priority_in_content_space()); + active_layer()->viewport_rect_for_tile_priority_in_content_space()); } TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { @@ -615,21 +491,21 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { Region()); ActivateTree(); // Add a unique tiling on the active tree. - PictureLayerTiling* tiling = active_layer_->AddTiling(3.f); + PictureLayerTiling* tiling = active_layer()->AddTiling(3.f); tiling->set_resolution(HIGH_RESOLUTION); tiling->CreateAllTilesForTesting(); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Then setup a new pending tree and activate it. SetupTreesWithFixedTileSize(pending_raster_source, active_raster_source, gfx::Size(50, 50), layer_invalidation); - EXPECT_EQ(1u, pending_layer_->num_tilings()); - EXPECT_EQ(3u, active_layer_->num_tilings()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); + EXPECT_EQ(3u, active_layer()->num_tilings()); - const PictureLayerTilingSet* tilings = pending_layer_->tilings(); + const PictureLayerTilingSet* tilings = pending_layer()->tilings(); EXPECT_GT(tilings->num_tilings(), 0u); for (size_t i = 0; i < tilings->num_tilings(); ++i) { const PictureLayerTiling* tiling = tilings->tiling_at(i); @@ -658,7 +534,7 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { } } - tilings = active_layer_->tilings(); + tilings = active_layer()->tilings(); EXPECT_GT(tilings->num_tilings(), 0u); for (size_t i = 0; i < tilings->num_tilings(); ++i) { const PictureLayerTiling* tiling = tilings->tiling_at(i); @@ -692,10 +568,10 @@ TEST_F(PictureLayerImplTest, CloneFullInvalidation) { SetupTreesWithInvalidation(pending_raster_source, active_raster_source, gfx::Rect(layer_bounds)); - EXPECT_EQ(pending_layer_->tilings()->num_tilings(), - active_layer_->tilings()->num_tilings()); + EXPECT_EQ(pending_layer()->tilings()->num_tilings(), + active_layer()->tilings()->num_tilings()); - const PictureLayerTilingSet* tilings = pending_layer_->tilings(); + const PictureLayerTilingSet* tilings = pending_layer()->tilings(); EXPECT_GT(tilings->num_tilings(), 0u); for (size_t i = 0; i < tilings->num_tilings(); ++i) { VerifyAllPrioritizedTilesExistAndHaveRasterSource( @@ -707,130 +583,130 @@ TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; EXPECT_LT(low_res_factor, 1.f); - active_layer_->ReleaseResources(); - EXPECT_FALSE(active_layer_->tilings()); - active_layer_->RecreateResources(); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + active_layer()->ReleaseResources(); + EXPECT_FALSE(active_layer()->tilings()); + active_layer()->RecreateResources(); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 6.f, // ideal contents scale 3.f, // device scale 2.f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); EXPECT_FLOAT_EQ(6.f * low_res_factor, - active_layer_->tilings()->tiling_at(1)->contents_scale()); + active_layer()->tilings()->tiling_at(1)->contents_scale()); // If we change the page scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 6.6f, // ideal contents scale 3.f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(4u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.6f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); EXPECT_FLOAT_EQ(6.6f * low_res_factor, - active_layer_->tilings()->tiling_at(2)->contents_scale()); + active_layer()->tilings()->tiling_at(2)->contents_scale()); // If we change the device scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 7.26f, // ideal contents scale 3.3f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(6u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(6u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); EXPECT_FLOAT_EQ(7.26f * low_res_factor, - active_layer_->tilings()->tiling_at(3)->contents_scale()); + active_layer()->tilings()->tiling_at(3)->contents_scale()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 7.26f, // ideal contents scale 2.2f, // device scale 3.3f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(6u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(6u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); EXPECT_FLOAT_EQ(7.26f * low_res_factor, - active_layer_->tilings()->tiling_at(3)->contents_scale()); + active_layer()->tilings()->tiling_at(3)->contents_scale()); } TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; EXPECT_LT(low_res_factor, 1.f); - pending_layer_->ReleaseResources(); - EXPECT_FALSE(pending_layer_->tilings()); - pending_layer_->RecreateResources(); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); + pending_layer()->ReleaseResources(); + EXPECT_FALSE(pending_layer()->tilings()); + pending_layer()->RecreateResources(); + EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings()); - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 6.f, // ideal contents scale 3.f, // device scale 2.f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the page scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 6.6f, // ideal contents scale 3.f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.6f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the device scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 7.26f, // ideal contents scale 3.3f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 7.26f, // ideal contents scale 2.2f, // device scale 3.3f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); } TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) { @@ -845,21 +721,21 @@ TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(valid_raster_source); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); ActivateTree(); SetupPendingTree(empty_raster_source); - EXPECT_FALSE(pending_layer_->CanHaveTilings()); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); - ASSERT_EQ(0u, pending_layer_->tilings()->num_tilings()); + EXPECT_FALSE(pending_layer()->CanHaveTilings()); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(0u, pending_layer()->tilings()->num_tilings()); ActivateTree(); - EXPECT_FALSE(active_layer_->CanHaveTilings()); - ASSERT_EQ(0u, active_layer_->tilings()->num_tilings()); + EXPECT_FALSE(active_layer()->CanHaveTilings()); + ASSERT_EQ(0u, active_layer()->tilings()->num_tilings()); SetupPendingTree(valid_raster_source); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); - ASSERT_EQ(0u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); + ASSERT_EQ(0u, active_layer()->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, LowResTilingStaysOnActiveTree) { @@ -871,20 +747,20 @@ TEST_F(PictureLayerImplTest, LowResTilingStaysOnActiveTree) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(valid_raster_source); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); ActivateTree(); SetupPendingTree(other_valid_raster_source); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); auto* low_res_tiling = - active_layer_->tilings()->FindTilingWithResolution(LOW_RESOLUTION); + active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION); EXPECT_TRUE(low_res_tiling); ActivateTree(); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); auto* other_low_res_tiling = - active_layer_->tilings()->FindTilingWithResolution(LOW_RESOLUTION); + active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION); EXPECT_TRUE(other_low_res_tiling); EXPECT_EQ(low_res_tiling, other_low_res_tiling); } @@ -895,93 +771,93 @@ TEST_F(PictureLayerImplTest, ZoomOutCrash) { // Set up the high and low res tilings before pinch zoom. SetupDefaultTrees(layer_bounds); ResetTilingsAndRasterScales(); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); SetContentsScaleOnBothLayers(32.0f, 1.0f, 32.0f, 1.0f, 0.f, false); - EXPECT_EQ(32.f, active_layer_->HighResTiling()->contents_scale()); - host_impl_.PinchGestureBegin(); + EXPECT_EQ(32.f, active_layer()->HighResTiling()->contents_scale()); + host_impl()->PinchGestureBegin(); SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, 0.f, false); SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, 0.f, false); - EXPECT_EQ(active_layer_->tilings()->NumHighResTilings(), 1); + EXPECT_EQ(active_layer()->tilings()->NumHighResTilings(), 1); } TEST_F(PictureLayerImplTest, PinchGestureTilings) { gfx::Size layer_bounds(1300, 1900); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; // Set up the high and low res tilings before pinch zoom. SetupDefaultTrees(layer_bounds); ResetTilingsAndRasterScales(); SetContentsScaleOnBothLayers(2.f, 1.0f, 2.f, 1.0f, 0.f, false); - EXPECT_EQ(active_layer_->num_tilings(), 2u); - EXPECT_EQ(pending_layer_->num_tilings(), 1u); - EXPECT_EQ(active_layer_->tilings()->tiling_at(0)->contents_scale(), 2.f); - EXPECT_EQ(active_layer_->tilings()->tiling_at(1)->contents_scale(), + EXPECT_EQ(active_layer()->num_tilings(), 2u); + EXPECT_EQ(pending_layer()->num_tilings(), 1u); + EXPECT_EQ(active_layer()->tilings()->tiling_at(0)->contents_scale(), 2.f); + EXPECT_EQ(active_layer()->tilings()->tiling_at(1)->contents_scale(), 2.f * low_res_factor); // One of the tilings has to be a low resolution one. EXPECT_EQ(LOW_RESOLUTION, - active_layer_->tilings()->tiling_at(1)->resolution()); + active_layer()->tilings()->tiling_at(1)->resolution()); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Start a pinch gesture. - host_impl_.PinchGestureBegin(); + host_impl()->PinchGestureBegin(); // Zoom out by a small amount. We should create a tiling at half // the scale (2/kMaxScaleRatioDuringPinch). SetContentsScaleOnBothLayers(1.8f, 1.0f, 1.8f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(2.0f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); EXPECT_FLOAT_EQ(1.0f, - active_layer_->tilings()->tiling_at(1)->contents_scale()); + active_layer()->tilings()->tiling_at(1)->contents_scale()); EXPECT_FLOAT_EQ(2.0f * low_res_factor, - active_layer_->tilings()->tiling_at(2)->contents_scale()); + active_layer()->tilings()->tiling_at(2)->contents_scale()); // Since we're pinching, we shouldn't create a low resolution tiling. EXPECT_FALSE( - active_layer_->tilings()->FindTilingWithResolution(LOW_RESOLUTION)); + active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION)); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Zoom out further, close to our low-res scale factor. We should // use that tiling as high-res, and not create a new tiling. SetContentsScaleOnBothLayers(low_res_factor * 2.1f, 1.0f, low_res_factor * 2.1f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FALSE( - active_layer_->tilings()->FindTilingWithResolution(LOW_RESOLUTION)); + active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION)); // Zoom in a lot now. Since we increase by increments of // kMaxScaleRatioDuringPinch, this will create a new tiling at 4.0. SetContentsScaleOnBothLayers(3.8f, 1.0f, 3.8f, 1.f, 0.f, false); - EXPECT_EQ(4u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(4u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(4.0f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); // Although one of the tilings matches the low resolution scale, it still // shouldn't be marked as low resolution since we're pinching. auto* low_res_tiling = - active_layer_->tilings()->FindTilingWithScale(4.f * low_res_factor); + active_layer()->tilings()->FindTilingWithScale(4.f * low_res_factor); EXPECT_TRUE(low_res_tiling); EXPECT_NE(LOW_RESOLUTION, low_res_tiling->resolution()); // Stop a pinch gesture. - host_impl_.PinchGestureEnd(); + host_impl()->PinchGestureEnd(); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // After pinch ends, set the scale to what the raster scale was updated to // (checked above). SetContentsScaleOnBothLayers(4.0f, 1.0f, 4.0f, 1.f, 0.f, false); - EXPECT_EQ(4u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(4u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(4.0f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); // Now that we stopped pinching, the low resolution tiling that existed should // now be marked as low resolution. low_res_tiling = - active_layer_->tilings()->FindTilingWithScale(4.f * low_res_factor); + active_layer()->tilings()->FindTilingWithScale(4.f * low_res_factor); EXPECT_TRUE(low_res_tiling); EXPECT_EQ(LOW_RESOLUTION, low_res_tiling->resolution()); } @@ -991,52 +867,52 @@ TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) { SetupDefaultTrees(layer_bounds); ResetTilingsAndRasterScales(); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); // Set up the high and low res tilings before pinch zoom. SetContentsScaleOnBothLayers(0.24f, 1.0f, 0.24f, 1.0f, 0.f, false); - EXPECT_EQ(2u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(0.24f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); EXPECT_FLOAT_EQ(0.0625f, - active_layer_->tilings()->tiling_at(1)->contents_scale()); + active_layer()->tilings()->tiling_at(1)->contents_scale()); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Start a pinch gesture. - host_impl_.PinchGestureBegin(); + host_impl()->PinchGestureBegin(); // Zoom out by a small amount. We should create a tiling at half // the scale (1/kMaxScaleRatioDuringPinch). SetContentsScaleOnBothLayers(0.2f, 1.0f, 0.2f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(0.24f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); EXPECT_FLOAT_EQ(0.12f, - active_layer_->tilings()->tiling_at(1)->contents_scale()); + active_layer()->tilings()->tiling_at(1)->contents_scale()); EXPECT_FLOAT_EQ(0.0625, - active_layer_->tilings()->tiling_at(2)->contents_scale()); + active_layer()->tilings()->tiling_at(2)->contents_scale()); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Zoom out further, close to our low-res scale factor. We should // use that tiling as high-res, and not create a new tiling. SetContentsScaleOnBothLayers(0.1f, 1.0f, 0.1f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); // Zoom in. 0.25(desired_scale) should be snapped to 0.24 during zoom-in // because 0.25(desired_scale) is within the ratio(1.2). SetContentsScaleOnBothLayers(0.25f, 1.0f, 0.25f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); // Zoom in a lot. Since we move in factors of two, we should get a scale that // is a power of 2 times 0.24. SetContentsScaleOnBothLayers(1.f, 1.0f, 1.f, 1.0f, 0.f, false); - EXPECT_EQ(4u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(4u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(1.92f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); } TEST_F(PictureLayerImplTest, CleanUpTilings) { @@ -1044,62 +920,60 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { std::vector<PictureLayerTiling*> used_tilings; - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; EXPECT_LT(low_res_factor, 1.f); float scale = 1.f; float page_scale = 1.f; SetupDefaultTrees(layer_bounds); - EXPECT_EQ(2u, active_layer_->tilings()->num_tilings()); - EXPECT_EQ(1.f, active_layer_->HighResTiling()->contents_scale()); + EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); + EXPECT_EQ(1.f, active_layer()->HighResTiling()->contents_scale()); // Ensure UpdateTiles won't remove any tilings. Note this is unrelated to - // |used_tilings| variable, and it's here only to ensure that active_layer_ + // |used_tilings| variable, and it's here only to ensure that active_layer() // won't remove tilings before the test has a chance to verify behavior. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // We only have ideal tilings, so they aren't removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - EXPECT_EQ(2u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); - host_impl_.PinchGestureBegin(); + host_impl()->PinchGestureBegin(); // Changing the ideal but not creating new tilings. scale = 1.5f; page_scale = 1.5f; SetContentsScaleOnBothLayers(scale, 1.f, page_scale, 1.f, 0.f, false); - EXPECT_EQ(2u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); // The tilings are still our target scale, so they aren't removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); - host_impl_.PinchGestureEnd(); + host_impl()->PinchGestureEnd(); // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2. scale = 1.2f; page_scale = 1.2f; SetContentsScaleOnBothLayers(1.2f, 1.f, page_scale, 1.f, 0.f, false); - ASSERT_EQ(4u, active_layer_->tilings()->num_tilings()); - EXPECT_FLOAT_EQ( - 1.f, - active_layer_->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ( - 1.f * low_res_factor, - active_layer_->tilings()->tiling_at(3)->contents_scale()); + ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); + EXPECT_FLOAT_EQ(1.f, + active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ(1.f * low_res_factor, + active_layer()->tilings()->tiling_at(3)->contents_scale()); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Mark the non-ideal tilings as used. They won't be removed. used_tilings.clear(); - used_tilings.push_back(active_layer_->tilings()->tiling_at(1)); - used_tilings.push_back(active_layer_->tilings()->tiling_at(3)); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(4u, active_layer_->tilings()->num_tilings()); + used_tilings.push_back(active_layer()->tilings()->tiling_at(1)); + used_tilings.push_back(active_layer()->tilings()->tiling_at(3)); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); // Now move the ideal scale to 0.5. Our target stays 1.2. SetContentsScaleOnBothLayers(0.5f, 1.f, page_scale, 1.f, 0.f, false); @@ -1107,8 +981,8 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { // The high resolution tiling is between target and ideal, so is not // removed. The low res tiling for the old ideal=1.0 scale is removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(3u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); // Now move the ideal scale to 1.0. Our target stays 1.2. SetContentsScaleOnBothLayers(1.f, 1.f, page_scale, 1.f, 0.f, false); @@ -1116,48 +990,48 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { // All the tilings are between are target and the ideal, so they are not // removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(3u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2. - SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.1f, 1.f, page_scale, 1.f, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.1f, 1.f, page_scale, 1.f, 0.f, false); // Because the pending layer's ideal scale is still 1.0, our tilings fall // in the range [1.0,1.2] and are kept. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(3u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); // Move the ideal scale on the pending layer to 1.1 as well. Our target stays // 1.2 still. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.1f, 1.f, page_scale, 1.f, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.1f, 1.f, page_scale, 1.f, 0.f, false); // Our 1.0 tiling now falls outside the range between our ideal scale and our // target raster scale. But it is in our used tilings set, so nothing is // deleted. used_tilings.clear(); - used_tilings.push_back(active_layer_->tilings()->tiling_at(1)); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(3u, active_layer_->tilings()->num_tilings()); + used_tilings.push_back(active_layer()->tilings()->tiling_at(1)); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); // If we remove it from our used tilings set, it is outside the range to keep // so it is deleted. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { // Make sure this layer covers multiple tiles, since otherwise low // res won't get created because it is too small. - gfx::Size tile_size(host_impl_.settings().default_tile_size); + gfx::Size tile_size(host_impl()->settings().default_tile_size); // Avoid max untiled layer size heuristics via fixed tile size. gfx::Size layer_bounds(tile_size.width() + 1, tile_size.height() + 1); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; float contents_scale = 1.f; float device_scale = 1.f; float page_scale = 1.f; @@ -1180,12 +1054,12 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { maximum_animation_scale, starting_animation_scale, animating_transform); EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); - EXPECT_EQ(active_layer_->LowResTiling()->contents_scale(), low_res_factor); - EXPECT_EQ(active_layer_->num_tilings(), 2u); - EXPECT_EQ(pending_layer_->num_tilings(), 1u); + EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(), low_res_factor); + EXPECT_EQ(active_layer()->num_tilings(), 2u); + EXPECT_EQ(pending_layer()->num_tilings(), 1u); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Page scale animation, new high res, but no low res. We still have // a tiling at the previous scale, it's just not marked as low res on the @@ -1198,10 +1072,10 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { maximum_animation_scale, starting_animation_scale, animating_transform); EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); - EXPECT_FALSE(active_layer_->LowResTiling()); - EXPECT_FALSE(pending_layer_->LowResTiling()); - EXPECT_EQ(3u, active_layer_->num_tilings()); - EXPECT_EQ(1u, pending_layer_->num_tilings()); + EXPECT_FALSE(active_layer()->LowResTiling()); + EXPECT_FALSE(pending_layer()->LowResTiling()); + EXPECT_EQ(3u, active_layer()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); // Stop animating, new low res gets created for final page scale. animating_transform = false; @@ -1209,14 +1083,14 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { maximum_animation_scale, starting_animation_scale, animating_transform); EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); - EXPECT_EQ(active_layer_->LowResTiling()->contents_scale(), + EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(), 2.f * low_res_factor); - EXPECT_EQ(4u, active_layer_->num_tilings()); - EXPECT_EQ(1u, pending_layer_->num_tilings()); + EXPECT_EQ(4u, active_layer()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); } TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { - gfx::Size layer_bounds(host_impl_.settings().default_tile_size); + gfx::Size layer_bounds(host_impl()->settings().default_tile_size); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -1225,7 +1099,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { SetupTrees(pending_raster_source, active_raster_source); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; float device_scale = 1.f; float page_scale = 1.f; float maximum_animation_scale = 1.f; @@ -1260,25 +1134,25 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { maximum_animation_scale, starting_animation_scale, animating_transform); EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale); - EXPECT_EQ(active_layer_->LowResTiling()->contents_scale(), + EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(), contents_scale * low_res_factor); - EXPECT_FALSE(pending_layer_->LowResTiling()); - EXPECT_EQ(active_layer_->num_tilings(), 2u); - EXPECT_EQ(pending_layer_->num_tilings(), 1u); + EXPECT_FALSE(pending_layer()->LowResTiling()); + EXPECT_EQ(active_layer()->num_tilings(), 2u); + EXPECT_EQ(pending_layer()->num_tilings(), 1u); // Mask layers dont create low res since they always fit on one tile. - scoped_ptr<FakePictureLayerImpl> mask = + std::unique_ptr<FakePictureLayerImpl> mask = FakePictureLayerImpl::CreateMaskWithRasterSource( - host_impl_.pending_tree(), 3, pending_raster_source); + host_impl()->pending_tree(), 3, pending_raster_source); mask->SetBounds(layer_bounds); mask->SetDrawsContent(true); - pending_layer_->SetMaskLayer(std::move(mask)); - pending_layer_->SetHasRenderSurface(true); + pending_layer()->SetMaskLayer(std::move(mask)); + pending_layer()->SetHasRenderSurface(true); RebuildPropertyTreesOnPendingTree(); - host_impl_.pending_tree()->UpdateDrawProperties(false); + host_impl()->pending_tree()->UpdateDrawProperties(false); FakePictureLayerImpl* mask_raw = - static_cast<FakePictureLayerImpl*>(pending_layer_->mask_layer()); + static_cast<FakePictureLayerImpl*>(pending_layer()->mask_layer()); // We did an UpdateDrawProperties above, which will set a contents scale on // the mask layer, so allow us to reset the contents scale. mask_raw->ReleaseResources(); @@ -1292,7 +1166,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { } TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); @@ -1300,32 +1174,32 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(valid_raster_source); - scoped_ptr<FakePictureLayerImpl> mask_ptr = + std::unique_ptr<FakePictureLayerImpl> mask_ptr = FakePictureLayerImpl::CreateMaskWithRasterSource( - host_impl_.pending_tree(), 3, valid_raster_source); + host_impl()->pending_tree(), 3, valid_raster_source); mask_ptr->SetBounds(layer_bounds); mask_ptr->SetDrawsContent(true); - pending_layer_->SetMaskLayer(std::move(mask_ptr)); - pending_layer_->SetForceRenderSurface(true); + pending_layer()->SetMaskLayer(std::move(mask_ptr)); + pending_layer()->test_properties()->force_render_surface = true; RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); bool update_lcd_text = false; - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); FakePictureLayerImpl* pending_mask = - static_cast<FakePictureLayerImpl*>(pending_layer_->mask_layer()); + static_cast<FakePictureLayerImpl*>(pending_layer()->mask_layer()); EXPECT_EQ(1.f, pending_mask->HighResTiling()->contents_scale()); EXPECT_EQ(1u, pending_mask->num_tilings()); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting( + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( pending_mask->HighResTiling()->AllTilesForTesting()); ActivateTree(); FakePictureLayerImpl* active_mask = - static_cast<FakePictureLayerImpl*>(active_layer_->mask_layer()); + static_cast<FakePictureLayerImpl*>(active_layer()->mask_layer()); // Mask layers have a tiling with a single tile in it. EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size()); @@ -1349,7 +1223,8 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { EXPECT_EQ(active_mask->bounds(), mask_texture_size); // Resize larger than the max texture size. - int max_texture_size = host_impl_.GetRendererCapabilities().max_texture_size; + int max_texture_size = + host_impl()->GetRendererCapabilities().max_texture_size; gfx::Size huge_bounds(max_texture_size + 1, 10); scoped_refptr<FakeRasterSource> huge_raster_source = FakeRasterSource::CreateFilled(huge_bounds); @@ -1358,14 +1233,14 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { pending_mask->SetBounds(huge_bounds); pending_mask->SetRasterSourceOnPending(huge_raster_source, Region()); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); // The mask tiling gets scaled down. EXPECT_LT(pending_mask->HighResTiling()->contents_scale(), 1.f); EXPECT_EQ(1u, pending_mask->num_tilings()); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting( + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( pending_mask->HighResTiling()->AllTilesForTesting()); ActivateTree(); @@ -1395,13 +1270,13 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { SetupPendingTree(huge_raster_source); ActivateTree(); EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size()); - active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size); + active_layer()->GetContentsResourceId(&mask_resource_id, &mask_texture_size); EXPECT_EQ(expected_size, mask_texture_size); EXPECT_EQ(0u, mask_resource_id); // Resize even larger, so that the scale would be smaller than the minimum // contents scale. Then the layer should no longer have any tiling. - float min_contents_scale = host_impl_.settings().minimum_contents_scale; + float min_contents_scale = host_impl()->settings().minimum_contents_scale; gfx::Size extra_huge_bounds(max_texture_size / min_contents_scale + 1, 10); scoped_refptr<FakeRasterSource> extra_huge_raster_source = FakeRasterSource::CreateFilled(extra_huge_bounds); @@ -1412,14 +1287,14 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { EXPECT_FALSE(pending_mask->CanHaveTilings()); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + 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) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); @@ -1429,33 +1304,33 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(valid_raster_source); - scoped_ptr<FakePictureLayerImpl> mask_ptr = + std::unique_ptr<FakePictureLayerImpl> mask_ptr = FakePictureLayerImpl::CreateMaskWithRasterSource( - host_impl_.pending_tree(), 3, valid_raster_source); + host_impl()->pending_tree(), 3, valid_raster_source); mask_ptr->SetBounds(layer_bounds); mask_ptr->SetDrawsContent(true); - pending_layer_->SetMaskLayer(std::move(mask_ptr)); - pending_layer_->SetForceRenderSurface(true); + pending_layer()->SetMaskLayer(std::move(mask_ptr)); + pending_layer()->test_properties()->force_render_surface = true; RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); bool update_lcd_text = false; - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); FakePictureLayerImpl* pending_mask = - static_cast<FakePictureLayerImpl*>(pending_layer_->mask_layer()); + static_cast<FakePictureLayerImpl*>(pending_layer()->mask_layer()); // Masks are scaled, and do not have a low res tiling. EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale()); EXPECT_EQ(1u, pending_mask->num_tilings()); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting( + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( pending_mask->HighResTiling()->AllTilesForTesting()); ActivateTree(); FakePictureLayerImpl* active_mask = - static_cast<FakePictureLayerImpl*>(active_layer_->mask_layer()); + static_cast<FakePictureLayerImpl*>(active_layer()->mask_layer()); // Mask layers have a tiling with a single tile in it. EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size()); @@ -1472,27 +1347,27 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) { TEST_F(PictureLayerImplTest, ReleaseResources) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); // All tilings should be removed when losing output surface. - active_layer_->ReleaseResources(); - EXPECT_FALSE(active_layer_->tilings()); - active_layer_->RecreateResources(); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); - pending_layer_->ReleaseResources(); - EXPECT_FALSE(pending_layer_->tilings()); - pending_layer_->RecreateResources(); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); + active_layer()->ReleaseResources(); + EXPECT_FALSE(active_layer()->tilings()); + active_layer()->RecreateResources(); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); + pending_layer()->ReleaseResources(); + EXPECT_FALSE(pending_layer()->tilings()); + pending_layer()->RecreateResources(); + EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings()); // This should create new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.f, // ideal contents scale 1.f, // device scale 1.f, // page scale 1.f, // maximum animation scale 0.f, // starting animation_scale false); - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) { @@ -1502,39 +1377,35 @@ TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - EXPECT_GE(pending_layer_->tilings()->num_tilings(), 1u); + EXPECT_GE(pending_layer()->tilings()->num_tilings(), 1u); - pending_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); + pending_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting(); // The default value. EXPECT_EQ(gfx::Size(256, 256).ToString(), - host_impl_.settings().default_tile_size.ToString()); + host_impl()->settings().default_tile_size.ToString()); - Tile* tile = pending_layer_->tilings()->tiling_at(0)->AllTilesForTesting()[0]; + Tile* tile = + pending_layer()->tilings()->tiling_at(0)->AllTilesForTesting()[0]; EXPECT_EQ(gfx::Size(256, 256).ToString(), tile->content_rect().size().ToString()); ResetTilingsAndRasterScales(); // Change the max texture size on the output surface context. - scoped_ptr<TestWebGraphicsContext3D> context = + std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); context->set_max_texture_size(140); - host_impl_.DidLoseOutputSurface(); - scoped_ptr<OutputSurface> new_output_surface = - FakeOutputSurface::Create3d(std::move(context)); - host_impl_.SetVisible(true); - host_impl_.InitializeRenderer(new_output_surface.get()); - output_surface_ = std::move(new_output_surface); - - SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, 0.f, + ResetOutputSurface(FakeOutputSurface::Create3d(std::move(context))); + + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.f, 1.f, 1.f, 1.f, 0.f, false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - pending_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); + pending_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting(); // Verify the tiles are not larger than the context's max texture size. - tile = pending_layer_->tilings()->tiling_at(0)->AllTilesForTesting()[0]; + tile = pending_layer()->tilings()->tiling_at(0)->AllTilesForTesting()[0]; EXPECT_GE(140, tile->content_rect().width()); EXPECT_GE(140, tile->content_rect().height()); } @@ -1542,50 +1413,45 @@ TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) { TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) { gfx::Size layer_bounds(500, 500); SetupDefaultTrees(layer_bounds); - EXPECT_GE(active_layer_->tilings()->num_tilings(), 1u); + EXPECT_GE(active_layer()->tilings()->num_tilings(), 1u); - active_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); + active_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting(); // The default value. The layer is smaller than this. EXPECT_EQ(gfx::Size(512, 512).ToString(), - host_impl_.settings().max_untiled_layer_size.ToString()); + host_impl()->settings().max_untiled_layer_size.ToString()); // There should be a single tile since the layer is small. - PictureLayerTiling* high_res_tiling = active_layer_->tilings()->tiling_at(0); + PictureLayerTiling* high_res_tiling = active_layer()->tilings()->tiling_at(0); EXPECT_EQ(1u, high_res_tiling->AllTilesForTesting().size()); ResetTilingsAndRasterScales(); // Change the max texture size on the output surface context. - scoped_ptr<TestWebGraphicsContext3D> context = + std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); context->set_max_texture_size(140); - host_impl_.DidLoseOutputSurface(); - scoped_ptr<OutputSurface> new_output_surface = - FakeOutputSurface::Create3d(std::move(context)); - host_impl_.SetVisible(true); - host_impl_.InitializeRenderer(new_output_surface.get()); - output_surface_ = std::move(new_output_surface); - - SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, 0.f, + ResetOutputSurface(FakeOutputSurface::Create3d(std::move(context))); + + SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f, false); - ASSERT_LE(1u, active_layer_->tilings()->num_tilings()); + ASSERT_LE(1u, active_layer()->tilings()->num_tilings()); - active_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting(); + active_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting(); // There should be more than one tile since the max texture size won't cover // the layer. - high_res_tiling = active_layer_->tilings()->tiling_at(0); + high_res_tiling = active_layer()->tilings()->tiling_at(0); EXPECT_LT(1u, high_res_tiling->AllTilesForTesting().size()); // Verify the tiles are not larger than the context's max texture size. - Tile* tile = active_layer_->tilings()->tiling_at(0)->AllTilesForTesting()[0]; + Tile* tile = active_layer()->tilings()->tiling_at(0)->AllTilesForTesting()[0]; EXPECT_GE(140, tile->content_rect().width()); EXPECT_GE(140, tile->content_rect().height()); } TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_bounds(1300, 1900); gfx::Rect layer_rect(layer_bounds); @@ -1593,13 +1459,14 @@ TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) { gfx::Rect layer_invalidation(150, 200, 30, 180); SetupDefaultTreesWithInvalidation(layer_bounds, layer_invalidation); - active_layer_->SetContentsOpaque(true); - active_layer_->draw_properties().visible_layer_rect = gfx::Rect(layer_bounds); + active_layer()->SetContentsOpaque(true); + active_layer()->draw_properties().visible_layer_rect = + gfx::Rect(layer_bounds); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); ASSERT_EQ(1u, render_pass->quad_list.size()); EXPECT_EQ(DrawQuad::PICTURE_CONTENT, @@ -1610,7 +1477,7 @@ TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) { } TEST_F(PictureLayerImplTest, ResourcelessPartialRecording) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size tile_size(400, 400); gfx::Size layer_bounds(700, 650); @@ -1624,14 +1491,14 @@ TEST_F(PictureLayerImplTest, ResourcelessPartialRecording) { SetupPendingTree(active_raster_source); ActivateTree(); - active_layer_->SetContentsOpaque(true); + active_layer()->SetContentsOpaque(true); gfx::Rect visible_rect(30, 35, 10, 5); - active_layer_->draw_properties().visible_layer_rect = visible_rect; + active_layer()->draw_properties().visible_layer_rect = visible_rect; AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); gfx::Rect scaled_visible = gfx::ScaleToEnclosingRect(visible_rect, 2.f); gfx::Rect scaled_recorded = gfx::ScaleToEnclosingRect(recorded_viewport, 2.f); @@ -1647,7 +1514,7 @@ TEST_F(PictureLayerImplTest, ResourcelessPartialRecording) { } TEST_F(PictureLayerImplTest, ResourcelessEmptyRecording) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_bounds(700, 650); scoped_refptr<FakeRasterSource> active_raster_source = @@ -1655,19 +1522,20 @@ TEST_F(PictureLayerImplTest, ResourcelessEmptyRecording) { SetupPendingTree(active_raster_source); ActivateTree(); - active_layer_->SetContentsOpaque(true); - active_layer_->draw_properties().visible_layer_rect = gfx::Rect(layer_bounds); + active_layer()->SetContentsOpaque(true); + active_layer()->draw_properties().visible_layer_rect = + gfx::Rect(layer_bounds); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); EXPECT_EQ(0U, render_pass->quad_list.size()); } TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_bounds(1500, 1500); gfx::Rect visible_rect(250, 250, 1000, 1000); @@ -1679,12 +1547,12 @@ TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) { SetupTrees(pending_raster_source, active_raster_source); - active_layer_->draw_properties().visible_layer_rect = visible_rect; + active_layer()->draw_properties().visible_layer_rect = visible_rect; AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); Region remaining = visible_rect; for (const auto& quad : render_pass->quad_list) { @@ -1705,14 +1573,14 @@ TEST_F(PictureLayerImplTest, TileScalesWithSolidColorRasterSource) { SetupTrees(pending_raster_source, active_raster_source); // Solid color raster source should not allow tilings at any scale. - EXPECT_FALSE(active_layer_->CanHaveTilings()); - EXPECT_EQ(0.f, active_layer_->ideal_contents_scale()); + EXPECT_FALSE(active_layer()->CanHaveTilings()); + EXPECT_EQ(0.f, active_layer()->ideal_contents_scale()); // Activate non-solid-color pending raster source makes active layer can have // tilings. ActivateTree(); - EXPECT_TRUE(active_layer_->CanHaveTilings()); - EXPECT_GT(active_layer_->ideal_contents_scale(), 0.f); + EXPECT_TRUE(active_layer()->CanHaveTilings()); + EXPECT_GT(active_layer()->ideal_contents_scale(), 0.f); } TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) { @@ -1720,26 +1588,27 @@ TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) { gfx::Transform transform; gfx::Rect viewport(0, 0, 100, 200); - host_impl_.SetExternalTilePriorityConstraints(viewport, transform); + host_impl()->SetExternalTilePriorityConstraints(viewport, transform); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTreeWithFixedTileSize(pending_raster_source, gfx::Size(100, 100), Region()); - EXPECT_EQ(1u, pending_layer_->num_tilings()); - EXPECT_EQ(viewport, - pending_layer_->viewport_rect_for_tile_priority_in_content_space()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); + EXPECT_EQ( + viewport, + pending_layer()->viewport_rect_for_tile_priority_in_content_space()); base::TimeTicks time_ticks; - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - pending_layer_->UpdateTiles(); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + pending_layer()->UpdateTiles(); int num_visible = 0; int num_offscreen = 0; - scoped_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( + pending_layer()->picture_layer_tiling_set(), false)); for (; !queue->IsEmpty(); queue->Pop()) { const PrioritizedTile& prioritized_tile = queue->Top(); DCHECK(prioritized_tile.tile()); @@ -1758,7 +1627,7 @@ TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) { TEST_F(NoLowResPictureLayerImplTest, TileOutsideOfViewportForTilePriorityNotRequired) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(400, 400); @@ -1767,37 +1636,37 @@ TEST_F(NoLowResPictureLayerImplTest, SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); - ASSERT_EQ(1u, pending_layer_->num_tilings()); - ASSERT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale()); + ASSERT_EQ(1u, pending_layer()->num_tilings()); + ASSERT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale()); // Set external viewport for tile priority. gfx::Rect viewport = gfx::Rect(layer_bounds); gfx::Transform transform; gfx::Transform transform_for_tile_priority; - host_impl_.SetExternalTilePriorityConstraints( + host_impl()->SetExternalTilePriorityConstraints( external_viewport_for_tile_priority, transform_for_tile_priority); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); bool update_lcd_text = false; - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + 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_layer_rect = visible_layer_rect; - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - pending_layer_->UpdateTiles(); + pending_layer()->draw_properties().visible_layer_rect = visible_layer_rect; + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + pending_layer()->UpdateTiles(); // 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_layer_rect()); + pending_layer()->viewport_rect_for_tile_priority_in_content_space(); + viewport_for_tile_priority.Intersect(pending_layer()->visible_layer_rect()); - EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); + EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty()); int num_inside = 0; int num_outside = 0; - for (PictureLayerTiling::CoverageIterator iter(active_layer_->HighResTiling(), - 1.f, gfx::Rect(layer_bounds)); + for (PictureLayerTiling::CoverageIterator iter( + active_layer()->HighResTiling(), 1.f, gfx::Rect(layer_bounds)); iter; ++iter) { if (!*iter) continue; @@ -1817,24 +1686,24 @@ TEST_F(NoLowResPictureLayerImplTest, EXPECT_GT(num_outside, 0); // Activate and draw active layer. - host_impl_.ActivateSyncTree(); - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); - active_layer_->draw_properties().visible_layer_rect = visible_layer_rect; + host_impl()->ActivateSyncTree(); + host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text); + active_layer()->draw_properties().visible_layer_rect = visible_layer_rect; - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); // All tiles in activation rect is ready to draw. EXPECT_EQ(0u, data.num_missing_tiles); EXPECT_EQ(0u, data.num_incomplete_tiles); - EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads()); + EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } TEST_F(PictureLayerImplTest, HighResTileIsComplete) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); @@ -1847,24 +1716,24 @@ TEST_F(PictureLayerImplTest, HighResTileIsComplete) { // All high res tiles have resources. std::vector<Tile*> tiles = - active_layer_->tilings()->tiling_at(0)->AllTilesForTesting(); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); + active_layer()->tilings()->tiling_at(0)->AllTilesForTesting(); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); // All high res tiles drew, nothing was incomplete. EXPECT_EQ(9u, render_pass->quad_list.size()); EXPECT_EQ(0u, data.num_missing_tiles); EXPECT_EQ(0u, data.num_incomplete_tiles); - EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads()); + EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); @@ -1874,20 +1743,20 @@ TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) { SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region()); ActivateTree(); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); EXPECT_EQ(1u, render_pass->quad_list.size()); EXPECT_EQ(1u, data.num_missing_tiles); EXPECT_EQ(0u, data.num_incomplete_tiles); - EXPECT_TRUE(active_layer_->only_used_low_res_last_append_quads()); + EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads()); } TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); @@ -1898,23 +1767,24 @@ TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) { ActivateTree(); std::vector<Tile*> low_tiles = - active_layer_->tilings()->tiling_at(1)->AllTilesForTesting(); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(low_tiles); + active_layer()->tilings()->tiling_at(1)->AllTilesForTesting(); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + low_tiles); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); EXPECT_EQ(1u, render_pass->quad_list.size()); EXPECT_EQ(0u, data.num_missing_tiles); EXPECT_EQ(1u, data.num_incomplete_tiles); - EXPECT_TRUE(active_layer_->only_used_low_res_last_append_quads()); + EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads()); } TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); @@ -1926,73 +1796,76 @@ TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) { // All high res tiles have resources except one. std::vector<Tile*> high_tiles = - active_layer_->tilings()->tiling_at(0)->AllTilesForTesting(); + active_layer()->tilings()->tiling_at(0)->AllTilesForTesting(); high_tiles.erase(high_tiles.begin()); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(high_tiles); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + high_tiles); // All low res tiles have resources. std::vector<Tile*> low_tiles = - active_layer_->tilings()->tiling_at(1)->AllTilesForTesting(); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(low_tiles); + active_layer()->tilings()->tiling_at(1)->AllTilesForTesting(); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + low_tiles); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); // The missing high res tile was replaced by a low res tile. EXPECT_EQ(9u, render_pass->quad_list.size()); EXPECT_EQ(0u, data.num_missing_tiles); EXPECT_EQ(1u, data.num_incomplete_tiles); - EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads()); + EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } TEST_F(PictureLayerImplTest, HighResAndIdealResTileIsCompleteWhenRasterScaleIsNotIdeal) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); gfx::Size viewport_size(400, 400); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); SetInitialDeviceScaleFactor(2.f); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); // One ideal tile exists, this will get used when drawing. std::vector<Tile*> ideal_tiles; - EXPECT_EQ(2.f, active_layer_->HighResTiling()->contents_scale()); - ideal_tiles.push_back(active_layer_->HighResTiling()->TileAt(0, 0)); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting( + EXPECT_EQ(2.f, active_layer()->HighResTiling()->contents_scale()); + ideal_tiles.push_back(active_layer()->HighResTiling()->TileAt(0, 0)); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( ideal_tiles); // Due to layer scale throttling, the raster contents scale is changed to 1, // while the ideal is still 2. - SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, 0.f, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f, false); - SetupDrawPropertiesAndUpdateTiles(active_layer_, 2.f, 1.f, 1.f, 1.f, 0.f, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 2.f, 1.f, 1.f, 1.f, 0.f, false); - EXPECT_EQ(1.f, active_layer_->HighResTiling()->contents_scale()); - EXPECT_EQ(1.f, active_layer_->raster_contents_scale()); - EXPECT_EQ(2.f, active_layer_->ideal_contents_scale()); + EXPECT_EQ(1.f, active_layer()->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, active_layer()->raster_contents_scale()); + EXPECT_EQ(2.f, active_layer()->ideal_contents_scale()); // Both tilings still exist. - EXPECT_EQ(2.f, active_layer_->tilings()->tiling_at(0)->contents_scale()); - EXPECT_EQ(1.f, active_layer_->tilings()->tiling_at(1)->contents_scale()); + EXPECT_EQ(2.f, active_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(1.f, active_layer()->tilings()->tiling_at(1)->contents_scale()); // All high res tiles have resources. std::vector<Tile*> high_tiles = - active_layer_->HighResTiling()->AllTilesForTesting(); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(high_tiles); + active_layer()->HighResTiling()->AllTilesForTesting(); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + high_tiles); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); // All high res tiles drew, and the one ideal res tile drew. ASSERT_GT(render_pass->quad_list.size(), 9u); @@ -2006,11 +1879,11 @@ TEST_F(PictureLayerImplTest, // Neither the high res nor the ideal tiles were considered as incomplete. EXPECT_EQ(0u, data.num_missing_tiles); EXPECT_EQ(0u, data.num_incomplete_tiles); - EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads()); + EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } TEST_F(PictureLayerImplTest, AppendQuadsDataForCheckerboard) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); @@ -2021,11 +1894,11 @@ TEST_F(PictureLayerImplTest, AppendQuadsDataForCheckerboard) { SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region()); ActivateTree(); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); EXPECT_EQ(1u, render_pass->quad_list.size()); EXPECT_EQ(1u, data.num_missing_tiles); @@ -2033,7 +1906,7 @@ TEST_F(PictureLayerImplTest, AppendQuadsDataForCheckerboard) { EXPECT_EQ(40000, data.checkerboarded_visible_content_area); EXPECT_EQ(17500, data.checkerboarded_no_recording_content_area); EXPECT_EQ(22500, data.checkerboarded_needs_raster_content_area); - EXPECT_TRUE(active_layer_->only_used_low_res_last_append_quads()); + EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads()); } TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveAllReady) { @@ -2043,14 +1916,14 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveAllReady) { SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, gfx::Rect(layer_bounds)); - active_layer_->SetAllTilesReady(); + active_layer()->SetAllTilesReady(); // All active tiles ready, so pending can only activate with all high res // tiles. - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - EXPECT_FALSE(pending_layer_->LowResTiling()); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + EXPECT_FALSE(pending_layer()->LowResTiling()); - AssertAllTilesRequired(pending_layer_->HighResTiling()); + AssertAllTilesRequired(pending_layer()->HighResTiling()); } TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) { @@ -2062,21 +1935,21 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) { // Verify active tree not ready. Tile* some_active_tile = - active_layer_->HighResTiling()->AllTilesForTesting()[0]; + active_layer()->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw()); // When high res are required, all tiles in active high res tiling should be // required for activation. - host_impl_.SetRequiresHighResToDraw(); + host_impl()->SetRequiresHighResToDraw(); - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - EXPECT_FALSE(pending_layer_->LowResTiling()); - active_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - active_layer_->LowResTiling()->UpdateAllRequiredStateForTesting(); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + EXPECT_FALSE(pending_layer()->LowResTiling()); + active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting(); - EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); - AssertAllTilesRequired(active_layer_->HighResTiling()); - AssertNoTilesRequired(active_layer_->LowResTiling()); + EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty()); + AssertAllTilesRequired(active_layer()->HighResTiling()); + AssertNoTilesRequired(active_layer()->LowResTiling()); } TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { @@ -2086,18 +1959,18 @@ TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); Tile* some_active_tile = - active_layer_->HighResTiling()->AllTilesForTesting()[0]; + active_layer()->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw()); // Since there are no invalidations, pending tree should have no tiles. - EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); - EXPECT_FALSE(pending_layer_->LowResTiling()); + EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty()); + EXPECT_FALSE(pending_layer()->LowResTiling()); - active_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - active_layer_->LowResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting(); - AssertAllTilesRequired(active_layer_->HighResTiling()); - AssertNoTilesRequired(active_layer_->LowResTiling()); + AssertAllTilesRequired(active_layer()->HighResTiling()); + AssertNoTilesRequired(active_layer()->LowResTiling()); } TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) { @@ -2107,21 +1980,21 @@ TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) { SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); Tile* some_active_tile = - active_layer_->HighResTiling()->AllTilesForTesting()[0]; + active_layer()->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw()); - EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); - EXPECT_FALSE(pending_layer_->LowResTiling()); - active_layer_->HighResTiling()->set_can_require_tiles_for_activation(false); - active_layer_->LowResTiling()->set_can_require_tiles_for_activation(false); - pending_layer_->HighResTiling()->set_can_require_tiles_for_activation(false); + EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty()); + EXPECT_FALSE(pending_layer()->LowResTiling()); + active_layer()->HighResTiling()->set_can_require_tiles_for_activation(false); + active_layer()->LowResTiling()->set_can_require_tiles_for_activation(false); + pending_layer()->HighResTiling()->set_can_require_tiles_for_activation(false); // If we disallow required for activation, no tiles can be required. - active_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - active_layer_->LowResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting(); - AssertNoTilesRequired(active_layer_->HighResTiling()); - AssertNoTilesRequired(active_layer_->LowResTiling()); + AssertNoTilesRequired(active_layer()->HighResTiling()); + AssertNoTilesRequired(active_layer()->LowResTiling()); } TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { @@ -2141,16 +2014,16 @@ TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { tile_size, Region()); // Active layer has tilings, but no tiles due to missing recordings. - EXPECT_TRUE(active_layer_->CanHaveTilings()); - EXPECT_EQ(active_layer_->tilings()->num_tilings(), 2u); - EXPECT_EQ(active_layer_->HighResTiling()->AllTilesForTesting().size(), 0u); + EXPECT_TRUE(active_layer()->CanHaveTilings()); + EXPECT_EQ(active_layer()->tilings()->num_tilings(), 2u); + EXPECT_EQ(active_layer()->HighResTiling()->AllTilesForTesting().size(), 0u); // Since the active layer has no tiles at all, the pending layer doesn't // need content in order to activate. - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - EXPECT_FALSE(pending_layer_->LowResTiling()); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + EXPECT_FALSE(pending_layer()->LowResTiling()); - AssertNoTilesRequired(pending_layer_->HighResTiling()); + AssertNoTilesRequired(pending_layer()->HighResTiling()); } TEST_F(PictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) { @@ -2165,16 +2038,16 @@ TEST_F(PictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) { tile_size, Region()); // Active layer can't have tiles. - EXPECT_FALSE(active_layer_->CanHaveTilings()); + EXPECT_FALSE(active_layer()->CanHaveTilings()); // All high res tiles required. This should be considered identical // to the case where there is no active layer, to avoid flashing content. // This can happen if a layer exists for a while and switches from // not being able to have content to having content. - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - EXPECT_FALSE(pending_layer_->LowResTiling()); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + EXPECT_FALSE(pending_layer()->LowResTiling()); - AssertAllTilesRequired(pending_layer_->HighResTiling()); + AssertAllTilesRequired(pending_layer()->HighResTiling()); } TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) { @@ -2192,14 +2065,14 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) { // Since the active layer has different bounds, the pending layer needs all // high res tiles in order to activate. - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - EXPECT_FALSE(pending_layer_->LowResTiling()); - active_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - active_layer_->LowResTiling()->UpdateAllRequiredStateForTesting(); - - AssertAllTilesRequired(pending_layer_->HighResTiling()); - AssertAllTilesRequired(active_layer_->HighResTiling()); - AssertNoTilesRequired(active_layer_->LowResTiling()); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + EXPECT_FALSE(pending_layer()->LowResTiling()); + active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting(); + + AssertAllTilesRequired(pending_layer()->HighResTiling()); + AssertAllTilesRequired(active_layer()->HighResTiling()); + AssertNoTilesRequired(active_layer()->LowResTiling()); } TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) { @@ -2207,32 +2080,32 @@ TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - host_impl_.CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl_.pending_tree(); + host_impl()->CreatePendingTree(); + LayerTreeImpl* pending_tree = host_impl()->pending_tree(); - scoped_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id_, + std::unique_ptr<FakePictureLayerImpl> pending_layer = + FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(), pending_raster_source); pending_layer->SetDrawsContent(true); pending_tree->SetRootLayer(std::move(pending_layer)); - pending_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.pending_tree()->LayerById(id_)); + FakePictureLayerImpl* raw_pending_layer = static_cast<FakePictureLayerImpl*>( + host_impl()->pending_tree()->LayerById(layer_id())); // Set some state on the pending layer, make sure it is not clobbered // by a sync from the active layer. This could happen because if the // pending layer has not been post-commit initialized it will attempt // to sync from the active layer. - float raster_page_scale = 10.f * pending_layer_->raster_page_scale(); - pending_layer_->set_raster_page_scale(raster_page_scale); + float raster_page_scale = 10.f * raw_pending_layer->raster_page_scale(); + raw_pending_layer->set_raster_page_scale(raster_page_scale); - host_impl_.ActivateSyncTree(); + host_impl()->ActivateSyncTree(); - active_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.active_tree()->LayerById(id_)); + FakePictureLayerImpl* raw_active_layer = static_cast<FakePictureLayerImpl*>( + host_impl()->active_tree()->LayerById(layer_id())); - EXPECT_EQ(0u, active_layer_->num_tilings()); - EXPECT_EQ(raster_page_scale, active_layer_->raster_page_scale()); + EXPECT_EQ(0u, raw_active_layer->num_tilings()); + EXPECT_EQ(raster_page_scale, raw_active_layer->raster_page_scale()); } TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { @@ -2243,7 +2116,7 @@ TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { SetupPendingTree(pending_raster_source); - PictureLayerTiling* tiling = pending_layer_->HighResTiling(); + PictureLayerTiling* tiling = pending_layer()->HighResTiling(); gfx::Rect first_invalidate = tiling->TilingDataForTesting().TileBounds(0, 0); first_invalidate.Inset(tiling->TilingDataForTesting().border_texels(), tiling->TilingDataForTesting().border_texels()); @@ -2261,8 +2134,8 @@ TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { SetupPendingTreeWithInvalidation(pending_raster_source, second_invalidate); - PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0); - PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0); + PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0); + PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0); // Tile 0,0 not exist on pending, but tile 1,1 should. EXPECT_TRUE(active_tiling->TileAt(0, 0)); @@ -2276,7 +2149,8 @@ TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { EXPECT_TRUE(pending_tiling->TileAt(1, 1)); // Drop the tiles on the active tree and recreate them. - active_tiling->ComputeTilePriorityRects(gfx::Rect(), 1.f, 1.0, Occlusion()); + active_layer()->tilings()->UpdateTilePriorities(gfx::Rect(), 1.f, 1.0, + Occlusion(), true); EXPECT_TRUE(active_tiling->AllTilesForTesting().empty()); active_tiling->CreateAllTilesForTesting(); @@ -2295,12 +2169,12 @@ TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { TEST_F(PictureLayerImplTest, PendingHasNoTilesWithNoInvalidation) { SetupDefaultTrees(gfx::Size(1500, 1500)); - EXPECT_GE(active_layer_->num_tilings(), 1u); - EXPECT_GE(pending_layer_->num_tilings(), 1u); + EXPECT_GE(active_layer()->num_tilings(), 1u); + EXPECT_GE(pending_layer()->num_tilings(), 1u); // No invalidation. - PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0); - PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0); + PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0); + PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0); ASSERT_TRUE(active_tiling); ASSERT_TRUE(pending_tiling); @@ -2331,12 +2205,12 @@ TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source2); - EXPECT_GE(active_layer_->num_tilings(), 1u); - EXPECT_GE(pending_layer_->num_tilings(), 1u); + EXPECT_GE(active_layer()->num_tilings(), 1u); + EXPECT_GE(pending_layer()->num_tilings(), 1u); // The active tree invalidation was handled by the active tiles. - PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0); - PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0); + PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0); + PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0); ASSERT_TRUE(active_tiling); ASSERT_TRUE(pending_tiling); @@ -2356,12 +2230,12 @@ TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) { // that touch this. SetupDefaultTreesWithInvalidation(gfx::Size(1500, 1500), gfx::Rect(1, 1)); - EXPECT_GE(active_layer_->num_tilings(), 1u); - EXPECT_GE(pending_layer_->num_tilings(), 1u); + EXPECT_GE(active_layer()->num_tilings(), 1u); + EXPECT_GE(pending_layer()->num_tilings(), 1u); // The pending tree invalidation creates tiles on the pending tree. - PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0); - PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0); + PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0); + PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0); ASSERT_TRUE(active_tiling); ASSERT_TRUE(pending_tiling); @@ -2379,7 +2253,7 @@ TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) { } TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(10, 10); @@ -2390,44 +2264,44 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { SetupTrees(pending_raster_source, active_raster_source); - EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.f)); - EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(1.f)); + EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(1.f)); + EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScale(1.f)); // Gpu rasterization is disabled by default. - EXPECT_FALSE(host_impl_.use_gpu_rasterization()); + EXPECT_FALSE(host_impl()->use_gpu_rasterization()); // Toggling the gpu rasterization clears all tilings on both trees. - host_impl_.SetHasGpuRasterizationTrigger(true); - host_impl_.SetContentIsSuitableForGpuRasterization(true); - host_impl_.UpdateTreeResourcesForGpuRasterizationIfNeeded(); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + host_impl()->SetHasGpuRasterizationTrigger(true); + host_impl()->SetContentIsSuitableForGpuRasterization(true); + host_impl()->UpdateTreeResourcesForGpuRasterizationIfNeeded(); + EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings()); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); // Make sure that we can still add tiling to the pending layer, // that gets synced to the active layer. - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + 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)); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); + EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(1.f)); ActivateTree(); - EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(1.f)); + EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScale(1.f)); SetupPendingTree(pending_raster_source); - EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.f)); + EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(1.f)); // Toggling the gpu rasterization clears all tilings on both trees. - EXPECT_TRUE(host_impl_.use_gpu_rasterization()); - host_impl_.SetHasGpuRasterizationTrigger(false); - host_impl_.UpdateTreeResourcesForGpuRasterizationIfNeeded(); + EXPECT_TRUE(host_impl()->use_gpu_rasterization()); + host_impl()->SetHasGpuRasterizationTrigger(false); + host_impl()->UpdateTreeResourcesForGpuRasterizationIfNeeded(); EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, - host_impl_.gpu_rasterization_status()); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + host_impl()->gpu_rasterization_status()); + EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings()); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); - host_impl_.SetHasGpuRasterizationTrigger(true); - host_impl_.SetContentIsSuitableForGpuRasterization(false); + host_impl()->SetHasGpuRasterizationTrigger(true); + host_impl()->SetContentIsSuitableForGpuRasterization(false); EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, - host_impl_.gpu_rasterization_status()); + host_impl()->gpu_rasterization_status()); } TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) { @@ -2439,8 +2313,8 @@ TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) { SetupPendingTree(pending_raster_source); // Sanity checks. - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); - EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(0.5f)); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); + EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(0.5f)); ActivateTree(); @@ -2449,123 +2323,123 @@ TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) { SetupPendingTree(pending_raster_source); // Another sanity check. - EXPECT_EQ(1.f, pending_layer_->MinimumContentsScale()); + EXPECT_EQ(1.f, pending_layer()->MinimumContentsScale()); // 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()); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); PictureLayerTiling* tiling = - pending_layer_->tilings()->FindTilingWithScale(1.0f); + pending_layer()->tilings()->FindTilingWithScale(1.0f); ASSERT_TRUE(tiling); EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution()); } TEST_F(PictureLayerImplTest, LowResTilingWithoutGpuRasterization) { - gfx::Size default_tile_size(host_impl_.settings().default_tile_size); + gfx::Size default_tile_size(host_impl()->settings().default_tile_size); gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); - host_impl_.SetHasGpuRasterizationTrigger(false); + host_impl()->SetHasGpuRasterizationTrigger(false); SetupDefaultTrees(layer_bounds); - EXPECT_FALSE(host_impl_.use_gpu_rasterization()); + EXPECT_FALSE(host_impl()->use_gpu_rasterization()); // Should have only a high-res tiling. - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); ActivateTree(); // Should add a high and a low res for active tree. - EXPECT_EQ(2u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) { - gfx::Size default_tile_size(host_impl_.settings().default_tile_size); + gfx::Size default_tile_size(host_impl()->settings().default_tile_size); gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); - host_impl_.SetHasGpuRasterizationTrigger(true); - host_impl_.SetContentIsSuitableForGpuRasterization(true); + host_impl()->SetHasGpuRasterizationTrigger(true); + host_impl()->SetContentIsSuitableForGpuRasterization(true); SetupDefaultTrees(layer_bounds); - EXPECT_TRUE(host_impl_.use_gpu_rasterization()); + EXPECT_TRUE(host_impl()->use_gpu_rasterization()); // Should only have the high-res tiling. - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); ActivateTree(); // Should only have the high-res tiling. - EXPECT_EQ(1u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, active_layer()->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, RequiredTilesWithGpuRasterization) { - host_impl_.SetHasGpuRasterizationTrigger(true); - host_impl_.SetContentIsSuitableForGpuRasterization(true); + host_impl()->SetHasGpuRasterizationTrigger(true); + host_impl()->SetContentIsSuitableForGpuRasterization(true); gfx::Size viewport_size(1000, 1000); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); gfx::Size layer_bounds(4000, 4000); SetupDefaultTrees(layer_bounds); - EXPECT_TRUE(host_impl_.use_gpu_rasterization()); + EXPECT_TRUE(host_impl()->use_gpu_rasterization()); // Should only have the high-res tiling. - EXPECT_EQ(1u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, active_layer()->tilings()->num_tilings()); - active_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); // High res tiling should have 64 tiles (4x16 tile grid). - EXPECT_EQ(64u, active_layer_->HighResTiling()->AllTilesForTesting().size()); + EXPECT_EQ(64u, active_layer()->HighResTiling()->AllTilesForTesting().size()); // Visible viewport should be covered by 4 tiles. No other // tiles should be required for activation. - EXPECT_EQ(4u, NumberOfTilesRequired(active_layer_->HighResTiling())); + EXPECT_EQ(4u, NumberOfTilesRequired(active_layer()->HighResTiling())); } TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) { // Set up layers with tilings. SetupDefaultTrees(gfx::Size(10, 10)); SetContentsScaleOnBothLayers(1.f, 1.f, 1.f, 1.f, 0.f, false); - pending_layer_->PushPropertiesTo(active_layer_); - EXPECT_TRUE(pending_layer_->DrawsContent()); - EXPECT_TRUE(pending_layer_->CanHaveTilings()); - EXPECT_GE(pending_layer_->num_tilings(), 0u); - EXPECT_GE(active_layer_->num_tilings(), 0u); + pending_layer()->PushPropertiesTo(active_layer()); + EXPECT_TRUE(pending_layer()->DrawsContent()); + EXPECT_TRUE(pending_layer()->CanHaveTilings()); + EXPECT_GE(pending_layer()->num_tilings(), 0u); + EXPECT_GE(active_layer()->num_tilings(), 0u); // Set content to false, which should make CanHaveTilings return false. - pending_layer_->SetDrawsContent(false); - EXPECT_FALSE(pending_layer_->DrawsContent()); - EXPECT_FALSE(pending_layer_->CanHaveTilings()); + pending_layer()->SetDrawsContent(false); + EXPECT_FALSE(pending_layer()->DrawsContent()); + EXPECT_FALSE(pending_layer()->CanHaveTilings()); // No tilings should be pushed to active layer. - pending_layer_->PushPropertiesTo(active_layer_); - EXPECT_EQ(0u, active_layer_->num_tilings()); + pending_layer()->PushPropertiesTo(active_layer()); + EXPECT_EQ(0u, active_layer()->num_tilings()); } TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) { SetupDefaultTrees(gfx::Size(10, 10)); // We start with a tiling at scale 1. - EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale()); // 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(); + host_impl()->PinchGestureBegin(); float high_res_scale = 2.3f; SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, 0.f, false); - EXPECT_EQ(4.f, pending_layer_->HighResTiling()->contents_scale()); + EXPECT_EQ(4.f, pending_layer()->HighResTiling()->contents_scale()); } TEST_F(PictureLayerImplTest, PinchingTooSmall) { SetupDefaultTrees(gfx::Size(10, 10)); // We start with a tiling at scale 1. - EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale()); - host_impl_.PinchGestureBegin(); + host_impl()->PinchGestureBegin(); float high_res_scale = 0.0001f; - EXPECT_LT(high_res_scale, pending_layer_->MinimumContentsScale()); + EXPECT_LT(high_res_scale, pending_layer()->MinimumContentsScale()); SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, 0.f, false); - EXPECT_FLOAT_EQ(pending_layer_->MinimumContentsScale(), - pending_layer_->HighResTiling()->contents_scale()); + EXPECT_FLOAT_EQ(pending_layer()->MinimumContentsScale(), + pending_layer()->HighResTiling()->contents_scale()); } TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) { @@ -2576,26 +2450,26 @@ TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) { float contents_scale = 0.15f; SetContentsScaleOnBothLayers(contents_scale, 1.f, 1.f, 1.f, 0.f, false); - ASSERT_GE(pending_layer_->num_tilings(), 0u); + ASSERT_GE(pending_layer()->num_tilings(), 0u); EXPECT_FLOAT_EQ(contents_scale, - pending_layer_->HighResTiling()->contents_scale()); + pending_layer()->HighResTiling()->contents_scale()); - host_impl_.PinchGestureBegin(); + host_impl()->PinchGestureBegin(); float page_scale = 0.0001f; EXPECT_LT(page_scale * contents_scale, - pending_layer_->MinimumContentsScale()); + pending_layer()->MinimumContentsScale()); SetContentsScaleOnBothLayers(contents_scale * page_scale, 1.f, page_scale, 1.f, 0.f, false); - ASSERT_GE(pending_layer_->num_tilings(), 0u); - EXPECT_FLOAT_EQ(pending_layer_->MinimumContentsScale(), - pending_layer_->HighResTiling()->contents_scale()); + ASSERT_GE(pending_layer()->num_tilings(), 0u); + EXPECT_FLOAT_EQ(pending_layer()->MinimumContentsScale(), + pending_layer()->HighResTiling()->contents_scale()); } TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { gfx::Size viewport_size(1000, 1000); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); gfx::Size layer_bounds(100, 100); SetupDefaultTrees(layer_bounds); @@ -2653,7 +2527,7 @@ TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForCpuRasterization) { gfx::Size viewport_size(1000, 1000); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); gfx::Size layer_bounds(100, 100); SetupDefaultTrees(layer_bounds); @@ -2796,10 +2670,10 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForGpuRasterization) { gfx::Size layer_bounds(100, 100); gfx::Size viewport_size(1000, 1000); SetupDefaultTrees(layer_bounds); - host_impl_.SetViewportSize(viewport_size); - host_impl_.SetHasGpuRasterizationTrigger(true); - host_impl_.SetContentIsSuitableForGpuRasterization(true); - host_impl_.UpdateTreeResourcesForGpuRasterizationIfNeeded(); + host_impl()->SetViewportSize(viewport_size); + host_impl()->SetHasGpuRasterizationTrigger(true); + host_impl()->SetContentIsSuitableForGpuRasterization(true); + host_impl()->UpdateTreeResourcesForGpuRasterizationIfNeeded(); float contents_scale = 1.f; float device_scale = 1.3f; @@ -2855,9 +2729,9 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForGpuRasterization) { } TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl_.SetViewportSize(gfx::Size(500, 500)); + host_impl()->SetViewportSize(gfx::Size(500, 500)); gfx::Size layer_bounds(1000, 1000); @@ -2865,7 +2739,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - EXPECT_EQ(1u, pending_layer_->num_tilings()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); std::set<Tile*> unique_tiles; bool reached_prepaint = false; @@ -2873,8 +2747,8 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { int low_res_tile_count = 0u; int high_res_tile_count = 0u; int high_res_now_tiles = 0u; - scoped_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( + pending_layer()->picture_layer_tiling_set(), false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); TilePriority priority = prioritized_tile.priority(); @@ -2912,14 +2786,14 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { EXPECT_EQ(low_res_tile_count + high_res_tile_count + non_ideal_tile_count, static_cast<int>(unique_tiles.size())); - scoped_ptr<TilingSetRasterQueueRequired> required_queue( + std::unique_ptr<TilingSetRasterQueueRequired> required_queue( new TilingSetRasterQueueRequired( - pending_layer_->picture_layer_tiling_set(), + pending_layer()->picture_layer_tiling_set(), RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW)); EXPECT_TRUE(required_queue->IsEmpty()); required_queue.reset(new TilingSetRasterQueueRequired( - pending_layer_->picture_layer_tiling_set(), + pending_layer()->picture_layer_tiling_set(), RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); EXPECT_FALSE(required_queue->IsEmpty()); int required_for_activation_count = 0; @@ -2936,16 +2810,16 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { EXPECT_EQ(high_res_now_tiles, required_for_activation_count); // No NOW tiles. - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - pending_layer_->draw_properties().visible_layer_rect = + pending_layer()->draw_properties().visible_layer_rect = gfx::Rect(1100, 1100, 500, 500); - pending_layer_->UpdateTiles(); + pending_layer()->UpdateTiles(); unique_tiles.clear(); high_res_tile_count = 0u; queue.reset(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); TilePriority priority = prioritized_tile.priority(); @@ -2965,14 +2839,14 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { EXPECT_EQ(16, high_res_tile_count); EXPECT_EQ(high_res_tile_count, static_cast<int>(unique_tiles.size())); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - pending_layer_->draw_properties().visible_layer_rect = + pending_layer()->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 500, 500); - pending_layer_->UpdateTiles(); + pending_layer()->UpdateTiles(); std::vector<Tile*> high_res_tiles = - pending_layer_->HighResTiling()->AllTilesForTesting(); + pending_layer()->HighResTiling()->AllTilesForTesting(); for (std::vector<Tile*>::iterator tile_it = high_res_tiles.begin(); tile_it != high_res_tiles.end(); ++tile_it) { @@ -2982,14 +2856,14 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { } queue.reset(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), true)); + pending_layer()->picture_layer_tiling_set(), true)); EXPECT_TRUE(queue->IsEmpty()); } TEST_F(PictureLayerImplTest, TilingSetRasterQueueActiveTree) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl_.SetViewportSize(gfx::Size(500, 500)); + host_impl()->SetViewportSize(gfx::Size(500, 500)); gfx::Size layer_bounds(1000, 1000); @@ -2998,11 +2872,11 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueueActiveTree) { SetupPendingTree(pending_raster_source); ActivateTree(); - EXPECT_EQ(2u, active_layer_->num_tilings()); + EXPECT_EQ(2u, active_layer()->num_tilings()); - scoped_ptr<TilingSetRasterQueueRequired> queue( + std::unique_ptr<TilingSetRasterQueueRequired> queue( new TilingSetRasterQueueRequired( - active_layer_->picture_layer_tiling_set(), + active_layer()->picture_layer_tiling_set(), RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW)); EXPECT_FALSE(queue->IsEmpty()); while (!queue->IsEmpty()) { @@ -3013,7 +2887,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueueActiveTree) { } queue.reset(new TilingSetRasterQueueRequired( - active_layer_->picture_layer_tiling_set(), + active_layer()->picture_layer_tiling_set(), RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); EXPECT_TRUE(queue->IsEmpty()); } @@ -3024,21 +2898,21 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueueRequiredNoHighRes) { SetupPendingTree(pending_raster_source); EXPECT_FALSE( - pending_layer_->picture_layer_tiling_set()->FindTilingWithResolution( + pending_layer()->picture_layer_tiling_set()->FindTilingWithResolution( HIGH_RESOLUTION)); - scoped_ptr<TilingSetRasterQueueRequired> queue( + std::unique_ptr<TilingSetRasterQueueRequired> queue( new TilingSetRasterQueueRequired( - pending_layer_->picture_layer_tiling_set(), + pending_layer()->picture_layer_tiling_set(), RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); EXPECT_TRUE(queue->IsEmpty()); } TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { gfx::Size layer_bounds(1000, 1000); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; - host_impl_.SetViewportSize(gfx::Size(500, 500)); + host_impl()->SetViewportSize(gfx::Size(500, 500)); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -3046,11 +2920,11 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { // TODO(vmpstr): Add a test with tilings other than high res on the active // tree (crbug.com/519607). SetupPendingTree(pending_raster_source); - EXPECT_EQ(1u, pending_layer_->num_tilings()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); std::vector<Tile*> all_tiles; - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); std::vector<Tile*> tiles = tiling->AllTilesForTesting(); all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end()); } @@ -3060,10 +2934,10 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { bool mark_required = false; size_t number_of_marked_tiles = 0u; size_t number_of_unmarked_tiles = 0u; - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); for (PictureLayerTiling::CoverageIterator iter( - tiling, 1.f, pending_layer_->visible_layer_rect()); + tiling, 1.f, pending_layer()->visible_layer_rect()); iter; ++iter) { if (mark_required) { number_of_marked_tiles++; @@ -3082,11 +2956,12 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { EXPECT_GT(number_of_unmarked_tiles, 1u); // Tiles don't have resources yet. - scoped_ptr<TilingSetEvictionQueue> queue( - new TilingSetEvictionQueue(pending_layer_->picture_layer_tiling_set())); + std::unique_ptr<TilingSetEvictionQueue> queue( + new TilingSetEvictionQueue(pending_layer()->picture_layer_tiling_set())); EXPECT_TRUE(queue->IsEmpty()); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + all_tiles); std::set<Tile*> unique_tiles; float expected_scales[] = {low_res_factor, 1.f}; @@ -3096,7 +2971,7 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { size_t distance_decreasing = 0; size_t distance_increasing = 0; queue.reset( - new TilingSetEvictionQueue(pending_layer_->picture_layer_tiling_set())); + new TilingSetEvictionQueue(pending_layer()->picture_layer_tiling_set())); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -3183,7 +3058,7 @@ TEST_F(PictureLayerImplTest, Occlusion) { gfx::Size viewport_size(1000, 1000); LayerTestCommon::LayerImplTest impl; - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -3191,13 +3066,13 @@ TEST_F(PictureLayerImplTest, Occlusion) { ActivateTree(); std::vector<Tile*> tiles = - active_layer_->HighResTiling()->AllTilesForTesting(); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); + active_layer()->HighResTiling()->AllTilesForTesting(); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); { SCOPED_TRACE("No occlusion"); gfx::Rect occluded; - impl.AppendQuadsWithOcclusion(active_layer_, occluded); + impl.AppendQuadsWithOcclusion(active_layer(), occluded); LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_bounds)); @@ -3206,8 +3081,8 @@ TEST_F(PictureLayerImplTest, Occlusion) { { SCOPED_TRACE("Full occlusion"); - gfx::Rect occluded(active_layer_->visible_layer_rect()); - impl.AppendQuadsWithOcclusion(active_layer_, occluded); + gfx::Rect occluded(active_layer()->visible_layer_rect()); + impl.AppendQuadsWithOcclusion(active_layer(), occluded); LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); @@ -3216,7 +3091,7 @@ TEST_F(PictureLayerImplTest, Occlusion) { { SCOPED_TRACE("Partial occlusion"); gfx::Rect occluded(150, 0, 200, 1000); - impl.AppendQuadsWithOcclusion(active_layer_, occluded); + impl.AppendQuadsWithOcclusion(active_layer(), occluded); size_t partially_occluded_count = 0; LayerTestCommon::VerifyQuadsAreOccluded( @@ -3228,7 +3103,7 @@ TEST_F(PictureLayerImplTest, Occlusion) { } TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { - gfx::Size tile_size(host_impl_.settings().default_tile_size); + gfx::Size tile_size(host_impl()->settings().default_tile_size); SetupDefaultTrees(tile_size); ResetTilingsAndRasterScales(); @@ -3273,20 +3148,20 @@ TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) { SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation); // All pending layer tiles required are not ready. - EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate()); // Initialize all low-res tiles. - EXPECT_FALSE(pending_layer_->LowResTiling()); - pending_layer_->SetAllTilesReadyInTiling(active_layer_->LowResTiling()); + EXPECT_FALSE(pending_layer()->LowResTiling()); + pending_layer()->SetAllTilesReadyInTiling(active_layer()->LowResTiling()); // Low-res tiles should not be enough. - EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate()); // Initialize remaining tiles. - pending_layer_->SetAllTilesReady(); - active_layer_->SetAllTilesReady(); + pending_layer()->SetAllTilesReady(); + active_layer()->SetAllTilesReady(); - EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) { @@ -3298,14 +3173,14 @@ TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) { SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation); // All pending layer tiles required are not ready. - EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate()); // Initialize all high-res tiles. - pending_layer_->SetAllTilesReadyInTiling(pending_layer_->HighResTiling()); - active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling()); + pending_layer()->SetAllTilesReadyInTiling(pending_layer()->HighResTiling()); + active_layer()->SetAllTilesReadyInTiling(active_layer()->HighResTiling()); // High-res tiles should be enough, since they cover everything visible. - EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } TEST_F(PictureLayerImplTest, ActiveHighResReadyNotEnoughToActivate) { @@ -3317,130 +3192,130 @@ TEST_F(PictureLayerImplTest, ActiveHighResReadyNotEnoughToActivate) { SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation); // Initialize all high-res tiles in the active layer. - active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling()); + active_layer()->SetAllTilesReadyInTiling(active_layer()->HighResTiling()); // The pending high-res tiles are not ready, so we cannot activate. - EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate()); // When the pending high-res tiles are ready, we can activate. - pending_layer_->SetAllTilesReadyInTiling(pending_layer_->HighResTiling()); - EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); + pending_layer()->SetAllTilesReadyInTiling(pending_layer()->HighResTiling()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; EXPECT_LT(low_res_factor, 1.f); ResetTilingsAndRasterScales(); - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 6.f, // ideal contents scale 3.f, // device scale 2.f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the page scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 6.6f, // ideal contents scale 3.f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.6f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the device scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 7.26f, // ideal contents scale 3.3f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(3u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. - SetupDrawPropertiesAndUpdateTiles(active_layer_, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 7.26f, // ideal contents scale 2.2f, // device scale 3.3f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(3u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - active_layer_->tilings()->tiling_at(0)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); } TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; EXPECT_LT(low_res_factor, 1.f); ResetTilingsAndRasterScales(); - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 6.f, // ideal contents scale 3.f, // device scale 2.f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the page scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 6.6f, // ideal contents scale 3.f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(6.6f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the device scale factor, then we should get new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 7.26f, // ideal contents scale 3.3f, // device scale 2.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 7.26f, // ideal contents scale 2.2f, // device scale 3.3f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(7.26f, - pending_layer_->tilings()->tiling_at(0)->contents_scale()); + pending_layer()->tilings()->tiling_at(0)->contents_scale()); } TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { @@ -3450,21 +3325,21 @@ TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); Tile* some_active_tile = - active_layer_->HighResTiling()->AllTilesForTesting()[0]; + active_layer()->HighResTiling()->AllTilesForTesting()[0]; EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw()); // Since there is no invalidation, pending tree should have no tiles. - EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty()); - if (host_impl_.settings().create_low_res_tiling) - EXPECT_TRUE(pending_layer_->LowResTiling()->AllTilesForTesting().empty()); + EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty()); + if (host_impl()->settings().create_low_res_tiling) + EXPECT_TRUE(pending_layer()->LowResTiling()->AllTilesForTesting().empty()); - active_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - if (host_impl_.settings().create_low_res_tiling) - active_layer_->LowResTiling()->UpdateAllRequiredStateForTesting(); + active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + if (host_impl()->settings().create_low_res_tiling) + active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting(); - AssertAllTilesRequired(active_layer_->HighResTiling()); - if (host_impl_.settings().create_low_res_tiling) - AssertNoTilesRequired(active_layer_->LowResTiling()); + AssertAllTilesRequired(active_layer()->HighResTiling()); + if (host_impl()->settings().create_low_res_tiling) + AssertNoTilesRequired(active_layer()->LowResTiling()); } TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { @@ -3484,20 +3359,20 @@ TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { tile_size, Region()); // Active layer has tilings, but no tiles due to missing recordings. - EXPECT_TRUE(active_layer_->CanHaveTilings()); - EXPECT_EQ(active_layer_->tilings()->num_tilings(), - host_impl_.settings().create_low_res_tiling ? 2u : 1u); - EXPECT_EQ(active_layer_->HighResTiling()->AllTilesForTesting().size(), 0u); + EXPECT_TRUE(active_layer()->CanHaveTilings()); + EXPECT_EQ(active_layer()->tilings()->num_tilings(), + host_impl()->settings().create_low_res_tiling ? 2u : 1u); + EXPECT_EQ(active_layer()->HighResTiling()->AllTilesForTesting().size(), 0u); // Since the active layer has no tiles at all, the pending layer doesn't // need content in order to activate. - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); - if (host_impl_.settings().create_low_res_tiling) - pending_layer_->LowResTiling()->UpdateAllRequiredStateForTesting(); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); + if (host_impl()->settings().create_low_res_tiling) + pending_layer()->LowResTiling()->UpdateAllRequiredStateForTesting(); - AssertNoTilesRequired(pending_layer_->HighResTiling()); - if (host_impl_.settings().create_low_res_tiling) - AssertNoTilesRequired(pending_layer_->LowResTiling()); + AssertNoTilesRequired(pending_layer()->HighResTiling()); + if (host_impl()->settings().create_low_res_tiling) + AssertNoTilesRequired(pending_layer()->LowResTiling()); } TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) { @@ -3505,7 +3380,7 @@ TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) { std::vector<PictureLayerTiling*> used_tilings; SetupDefaultTrees(layer_bounds); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; EXPECT_LT(low_res_factor, 1.f); float device_scale = 1.7f; @@ -3516,50 +3391,50 @@ TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) { SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, 0.f, false); - ASSERT_EQ(1u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); // Ensure UpdateTiles won't remove any tilings. Note this is unrelated to - // |used_tilings| variable, and it's here only to ensure that active_layer_ + // |used_tilings| variable, and it's here only to ensure that active_layer() // won't remove tilings before the test has a chance to verify behavior. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // We only have ideal tilings, so they aren't removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(1u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); - host_impl_.PinchGestureBegin(); + host_impl()->PinchGestureBegin(); // Changing the ideal but not creating new tilings. scale *= 1.5f; page_scale *= 1.5f; SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, 0.f, false); - ASSERT_EQ(1u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); // The tilings are still our target scale, so they aren't removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(1u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); - host_impl_.PinchGestureEnd(); + host_impl()->PinchGestureEnd(); // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2. scale /= 4.f; page_scale /= 4.f; SetContentsScaleOnBothLayers(1.2f, device_scale, page_scale, 1.f, 0.f, false); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ(1.f, - active_layer_->tilings()->tiling_at(1)->contents_scale()); + active_layer()->tilings()->tiling_at(1)->contents_scale()); // Ensure UpdateTiles won't remove any tilings. - active_layer_->MarkAllTilingsUsed(); + active_layer()->MarkAllTilingsUsed(); // Mark the non-ideal tilings as used. They won't be removed. used_tilings.clear(); - used_tilings.push_back(active_layer_->tilings()->tiling_at(1)); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + used_tilings.push_back(active_layer()->tilings()->tiling_at(1)); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); // Now move the ideal scale to 0.5. Our target stays 1.2. SetContentsScaleOnBothLayers(0.5f, device_scale, page_scale, 1.f, 0.f, false); @@ -3567,8 +3442,8 @@ TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) { // The high resolution tiling is between target and ideal, so is not // removed. The low res tiling for the old ideal=1.0 scale is removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); // Now move the ideal scale to 1.0. Our target stays 1.2. SetContentsScaleOnBothLayers(1.f, device_scale, page_scale, 1.f, 0.f, false); @@ -3576,86 +3451,86 @@ TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) { // All the tilings are between are target and the ideal, so they are not // removed. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2. - SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.1f, device_scale, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.1f, device_scale, page_scale, 1.f, 0.f, false); // Because the pending layer's ideal scale is still 1.0, our tilings fall // in the range [1.0,1.2] and are kept. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); // Move the ideal scale on the pending layer to 1.1 as well. Our target stays // 1.2 still. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.1f, device_scale, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.1f, device_scale, page_scale, 1.f, 0.f, false); // Our 1.0 tiling now falls outside the range between our ideal scale and our // target raster scale. But it is in our used tilings set, so nothing is // deleted. used_tilings.clear(); - used_tilings.push_back(active_layer_->tilings()->tiling_at(1)); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(2u, active_layer_->tilings()->num_tilings()); + used_tilings.push_back(active_layer()->tilings()->tiling_at(1)); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); // If we remove it from our used tilings set, it is outside the range to keep // so it is deleted. used_tilings.clear(); - active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); - ASSERT_EQ(1u, active_layer_->tilings()->num_tilings()); + active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); + ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); } TEST_F(NoLowResPictureLayerImplTest, ReleaseResources) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); - EXPECT_EQ(1u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); + EXPECT_EQ(1u, active_layer()->tilings()->num_tilings()); // All tilings should be removed when losing output surface. - active_layer_->ReleaseResources(); - EXPECT_FALSE(active_layer_->tilings()); - active_layer_->RecreateResources(); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); - pending_layer_->ReleaseResources(); - EXPECT_FALSE(pending_layer_->tilings()); - pending_layer_->RecreateResources(); - EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); + active_layer()->ReleaseResources(); + EXPECT_FALSE(active_layer()->tilings()); + active_layer()->RecreateResources(); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); + pending_layer()->ReleaseResources(); + EXPECT_FALSE(pending_layer()->tilings()); + pending_layer()->RecreateResources(); + EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings()); // This should create new tilings. - SetupDrawPropertiesAndUpdateTiles(pending_layer_, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.3f, // ideal contents scale 2.7f, // device scale 3.2f, // page scale 1.f, // maximum animation scale 0.f, // starting animation scale false); - EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings()); + EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_bounds(1000, 2000); - host_impl_.SetViewportSize(gfx::Size(10000, 20000)); + host_impl()->SetViewportSize(gfx::Size(10000, 20000)); SetupDefaultTrees(layer_bounds); ResetTilingsAndRasterScales(); - SetupDrawPropertiesAndUpdateTiles(active_layer_, 2.5f, 1.f, 1.f, 1.f, 0.f, + SetupDrawPropertiesAndUpdateTiles(active_layer(), 2.5f, 1.f, 1.f, 1.f, 0.f, false); - float max_contents_scale = active_layer_->MaximumTilingContentsScale(); + float max_contents_scale = active_layer()->MaximumTilingContentsScale(); EXPECT_EQ(2.5f, max_contents_scale); - gfx::Transform scaled_draw_transform = active_layer_->DrawTransform(); + gfx::Transform scaled_draw_transform = active_layer()->DrawTransform(); scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale, SK_MScalar1 / max_contents_scale); AppendQuadsData data; - active_layer_->AppendQuads(render_pass.get(), &data); + active_layer()->AppendQuads(render_pass.get(), &data); // SharedQuadState should have be of size 1, as we are doing AppenQuad once. EXPECT_EQ(1u, render_pass->shared_quad_state_list.size()); @@ -3678,13 +3553,8 @@ TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) { class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest { public: - PictureLayerImplTestWithDelegatingRenderer() : PictureLayerImplTest() { - output_surface_ = FakeOutputSurface::CreateDelegating3d(); - } - - void InitializeRenderer() override { - host_impl_.SetVisible(true); - host_impl_.InitializeRenderer(output_surface_.get()); + std::unique_ptr<OutputSurface> CreateOutputSurface() override { + return FakeOutputSurface::CreateDelegating3d(); } }; @@ -3698,13 +3568,13 @@ TEST_F(PictureLayerImplTestWithDelegatingRenderer, scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - pending_layer_->SetBounds(layer_bounds); + pending_layer()->SetBounds(layer_bounds); ActivateTree(); bool update_lcd_text = false; - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text); std::vector<Tile*> tiles = - active_layer_->HighResTiling()->AllTilesForTesting(); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); + active_layer()->HighResTiling()->AllTilesForTesting(); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); // Force tiles after max_tiles to be OOM. TileManager uses // GlobalStateThatImpactsTilesPriority from LayerTreeHostImpl, and we cannot @@ -3712,21 +3582,21 @@ TEST_F(PictureLayerImplTestWithDelegatingRenderer, // state. We also need to update tree priority separately. GlobalStateThatImpactsTilePriority state; size_t max_tiles = 1; - gfx::Size tile_size(host_impl_.settings().default_tile_size); + gfx::Size tile_size(host_impl()->settings().default_tile_size); size_t memory_limit = max_tiles * 4 * tile_size.width() * tile_size.height(); size_t resource_limit = max_tiles; ManagedMemoryPolicy policy(memory_limit, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, resource_limit); - host_impl_.SetMemoryPolicy(policy); - host_impl_.SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES); - host_impl_.PrepareTiles(); + host_impl()->SetMemoryPolicy(policy); + host_impl()->SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES); + host_impl()->PrepareTiles(); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_HARDWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_HARDWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); // Even when OOM, quads should be produced, and should be different material // from quads with resource. @@ -3737,15 +3607,13 @@ TEST_F(PictureLayerImplTestWithDelegatingRenderer, render_pass->quad_list.back()->material); } -class OcclusionTrackingSettings : public LowResTilingsSettings { - public: - OcclusionTrackingSettings() { use_occlusion_for_tile_prioritization = true; } -}; - class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { public: - OcclusionTrackingPictureLayerImplTest() - : PictureLayerImplTest(OcclusionTrackingSettings()) {} + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + settings.use_occlusion_for_tile_prioritization = true; + return settings; + } void VerifyEvictionConsidersOcclusion(FakePictureLayerImpl* layer, WhichTree tree, @@ -3754,7 +3622,7 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { size_t occluded_tile_count = 0u; PrioritizedTile last_tile; - scoped_ptr<TilingSetEvictionQueue> queue( + std::unique_ptr<TilingSetEvictionQueue> queue( new TilingSetEvictionQueue(layer->picture_layer_tiling_set())); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); @@ -3793,14 +3661,14 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { TEST_F(OcclusionTrackingPictureLayerImplTest, OccludedTilesSkippedDuringRasterization) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(500, 500); gfx::PointF occluding_layer_position(310.f, 0.f); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -3808,8 +3676,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, // No occlusion. int unoccluded_tile_count = 0; - scoped_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll( + pending_layer()->picture_layer_tiling_set(), false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -3820,7 +3688,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_layer_rect()); + tile->content_rect().Intersects(pending_layer()->visible_layer_rect()); if (tile_is_visible) unoccluded_tile_count++; queue->Pop(); @@ -3828,21 +3696,21 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, EXPECT_EQ(unoccluded_tile_count, 25); // Partial occlusion. - pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1)); - LayerImpl* layer1 = pending_layer_->children()[0]; + pending_layer()->AddChild(LayerImpl::Create(host_impl()->pending_tree(), 1)); + LayerImpl* layer1 = pending_layer()->children()[0]; layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); layer1->SetPosition(occluding_layer_position); RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); bool update_lcd_text = false; - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); unoccluded_tile_count = 0; queue.reset(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -3850,7 +3718,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, EXPECT_FALSE(prioritized_tile.is_occluded()); bool tile_is_visible = - tile->content_rect().Intersects(pending_layer_->visible_layer_rect()); + tile->content_rect().Intersects(pending_layer()->visible_layer_rect()); if (tile_is_visible) unoccluded_tile_count++; queue->Pop(); @@ -3862,12 +3730,12 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, layer1->NoteLayerPropertyChanged(); RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); unoccluded_tile_count = 0; queue.reset(new TilingSetRasterQueueAll( - pending_layer_->picture_layer_tiling_set(), false)); + pending_layer()->picture_layer_tiling_set(), false)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -3875,7 +3743,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, EXPECT_FALSE(prioritized_tile.is_occluded()); bool tile_is_visible = - tile->content_rect().Intersects(pending_layer_->visible_layer_rect()); + tile->content_rect().Intersects(pending_layer()->visible_layer_rect()); if (tile_is_visible) unoccluded_tile_count++; queue->Pop(); @@ -3885,14 +3753,14 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, TEST_F(OcclusionTrackingPictureLayerImplTest, OccludedTilesNotMarkedAsRequired) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(500, 500); gfx::PointF occluding_layer_position(310.f, 0.f); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -3900,8 +3768,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, // No occlusion. int occluded_tile_count = 0; - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); @@ -3923,20 +3791,20 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, } // Partial occlusion. - pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1)); - LayerImpl* layer1 = pending_layer_->children()[0]; + pending_layer()->AddChild(LayerImpl::Create(host_impl()->pending_tree(), 1)); + LayerImpl* layer1 = pending_layer()->children()[0]; layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); layer1->SetPosition(occluding_layer_position); RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); bool update_lcd_text = false; - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); @@ -3970,11 +3838,11 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, layer1->NoteLayerPropertyChanged(); RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + 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) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); @@ -4005,7 +3873,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, } TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); @@ -4015,37 +3883,37 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region()); - ASSERT_TRUE(pending_layer_->CanHaveTilings()); + ASSERT_TRUE(pending_layer()->CanHaveTilings()); - pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1)); - LayerImpl* layer1 = pending_layer_->children()[0]; + pending_layer()->AddChild(LayerImpl::Create(host_impl()->pending_tree(), 1)); + LayerImpl* layer1 = pending_layer()->children()[0]; layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); layer1->SetPosition(occluding_layer_position); - pending_layer_->tilings()->RemoveAllTilings(); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; - pending_layer_->AddTiling(low_res_factor)->set_resolution(LOW_RESOLUTION); - pending_layer_->AddTiling(0.3f)->set_resolution(HIGH_RESOLUTION); - pending_layer_->AddTiling(0.7f)->set_resolution(HIGH_RESOLUTION); - pending_layer_->AddTiling(1.0f)->set_resolution(HIGH_RESOLUTION); - pending_layer_->AddTiling(2.0f)->set_resolution(HIGH_RESOLUTION); + pending_layer()->tilings()->RemoveAllTilings(); + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; + pending_layer()->AddTiling(low_res_factor)->set_resolution(LOW_RESOLUTION); + pending_layer()->AddTiling(0.3f)->set_resolution(HIGH_RESOLUTION); + pending_layer()->AddTiling(0.7f)->set_resolution(HIGH_RESOLUTION); + pending_layer()->AddTiling(1.0f)->set_resolution(HIGH_RESOLUTION); + pending_layer()->AddTiling(2.0f)->set_resolution(HIGH_RESOLUTION); RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + 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); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); - EXPECT_EQ(5u, pending_layer_->num_tilings()); + EXPECT_EQ(5u, pending_layer()->num_tilings()); int occluded_tile_count = 0; - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); std::vector<Tile*> tiles = tiling->AllTilesForTesting(); @@ -4091,12 +3959,12 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { scoped_refptr<FakeRasterSource> active_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); SetupPendingTree(active_raster_source); // Partially occlude the active layer. - pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 2)); - LayerImpl* layer1 = pending_layer_->children()[0]; + pending_layer()->AddChild(LayerImpl::Create(host_impl()->pending_tree(), 2)); + LayerImpl* layer1 = pending_layer()->children()[0]; layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); @@ -4104,8 +3972,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { ActivateTree(); - for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); @@ -4128,8 +3996,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { // Partially invalidate the pending layer. SetupPendingTreeWithInvalidation(pending_raster_source, invalidation_rect); - for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); @@ -4145,12 +4013,13 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { EXPECT_FALSE(prioritized_tiles[tile].is_occluded()); if (tiling->resolution() == LOW_RESOLUTION) { - EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinTiling(tiling)); + EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinTiling(tiling)); continue; } - Tile* twin_tile = active_layer_->GetPendingOrActiveTwinTiling(tiling) - ->TileAt(iter.i(), iter.j()); + Tile* twin_tile = + active_layer()->GetPendingOrActiveTwinTiling(tiling)->TileAt( + iter.i(), iter.j()); gfx::Rect scaled_content_rect = ScaleToEnclosingRect( tile->content_rect(), 1.0f / tile->contents_scale()); @@ -4168,7 +4037,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { TEST_F(OcclusionTrackingPictureLayerImplTest, OccludedTilesConsideredDuringEviction) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); @@ -4177,7 +4046,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, gfx::PointF active_occluding_layer_position(0.f, 310.f); gfx::Rect invalidation_rect(230, 230, 152, 152); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); SetInitialDeviceScaleFactor(2.f); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -4188,8 +4057,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, SetupPendingTreeWithFixedTileSize(active_raster_source, tile_size, Region()); // Partially occlude the active layer. - pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 2)); - LayerImpl* active_occluding_layer = pending_layer_->children()[0]; + 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->SetDrawsContent(true); active_occluding_layer->SetContentsOpaque(true); @@ -4203,21 +4072,21 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, invalidation_rect); // Partially occlude the pending layer in a different way. - pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 3)); - LayerImpl* pending_occluding_layer = pending_layer_->children()[0]; + 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->SetDrawsContent(true); pending_occluding_layer->SetContentsOpaque(true); pending_occluding_layer->SetPosition(pending_occluding_layer_position); - EXPECT_EQ(1u, pending_layer_->num_tilings()); - EXPECT_EQ(2u, active_layer_->num_tilings()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); + EXPECT_EQ(2u, active_layer()->num_tilings()); RebuildPropertyTreesOnPendingTree(); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + 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); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); // The expected number of occluded tiles on each of the 2 tilings for each of // the 3 tree priorities. @@ -4226,8 +4095,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, size_t total_expected_occluded_tile_count_on_trees[] = {15u, 4u}; // Verify number of occluded tiles on the pending layer for each tiling. - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); @@ -4253,8 +4122,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, } // Verify number of occluded tiles on the active layer for each tiling. - for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); @@ -4275,45 +4144,46 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, } std::vector<Tile*> all_tiles; - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); std::vector<Tile*> tiles = tiling->AllTilesForTesting(); all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end()); } - for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); std::vector<Tile*> tiles = tiling->AllTilesForTesting(); all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end()); } - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + all_tiles); VerifyEvictionConsidersOcclusion( - pending_layer_, PENDING_TREE, + pending_layer(), PENDING_TREE, total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__); VerifyEvictionConsidersOcclusion( - active_layer_, ACTIVE_TREE, + active_layer(), ACTIVE_TREE, total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__); // Repeat the tests without valid active tree priorities. - active_layer_->set_has_valid_tile_priorities(false); + active_layer()->set_has_valid_tile_priorities(false); VerifyEvictionConsidersOcclusion( - pending_layer_, PENDING_TREE, + pending_layer(), PENDING_TREE, total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__); VerifyEvictionConsidersOcclusion( - active_layer_, ACTIVE_TREE, + active_layer(), ACTIVE_TREE, total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__); - active_layer_->set_has_valid_tile_priorities(true); + active_layer()->set_has_valid_tile_priorities(true); // Repeat the tests without valid pending tree priorities. - pending_layer_->set_has_valid_tile_priorities(false); + pending_layer()->set_has_valid_tile_priorities(false); VerifyEvictionConsidersOcclusion( - active_layer_, ACTIVE_TREE, + active_layer(), ACTIVE_TREE, total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__); VerifyEvictionConsidersOcclusion( - pending_layer_, PENDING_TREE, + pending_layer(), PENDING_TREE, total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__); - pending_layer_->set_has_valid_tile_priorities(true); + pending_layer()->set_has_valid_tile_priorities(true); } TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) { @@ -4322,28 +4192,28 @@ TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) { scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(raster_source); - EXPECT_FALSE(pending_layer_->GetPendingOrActiveTwinLayer()); + EXPECT_FALSE(pending_layer()->GetPendingOrActiveTwinLayer()); ActivateTree(); - EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer()); + EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinLayer()); SetupPendingTree(raster_source); - EXPECT_TRUE(pending_layer_->GetPendingOrActiveTwinLayer()); - EXPECT_TRUE(active_layer_->GetPendingOrActiveTwinLayer()); - EXPECT_EQ(pending_layer_, active_layer_->GetPendingOrActiveTwinLayer()); - EXPECT_EQ(active_layer_, pending_layer_->GetPendingOrActiveTwinLayer()); + EXPECT_TRUE(pending_layer()->GetPendingOrActiveTwinLayer()); + EXPECT_TRUE(active_layer()->GetPendingOrActiveTwinLayer()); + EXPECT_EQ(pending_layer(), active_layer()->GetPendingOrActiveTwinLayer()); + EXPECT_EQ(active_layer(), pending_layer()->GetPendingOrActiveTwinLayer()); ActivateTree(); - EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer()); + EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinLayer()); // Make an empty pending tree. - host_impl_.CreatePendingTree(); - host_impl_.pending_tree()->ClearLayers(); - EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer()); + host_impl()->CreatePendingTree(); + host_impl()->pending_tree()->ClearLayers(); + EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinLayer()); } void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); @@ -4354,7 +4224,7 @@ void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) { scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); host->SetRootLayer(layer); RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); @@ -4375,21 +4245,21 @@ void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) { ActivateTree(); if (test_for_solid) { - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); } else { - ASSERT_TRUE(active_layer_->tilings()); - ASSERT_GT(active_layer_->tilings()->num_tilings(), 0u); + ASSERT_TRUE(active_layer()->tilings()); + ASSERT_GT(active_layer()->tilings()->num_tilings(), 0u); std::vector<Tile*> tiles = - active_layer_->tilings()->tiling_at(0)->AllTilesForTesting(); + active_layer()->tilings()->tiling_at(0)->AllTilesForTesting(); EXPECT_FALSE(tiles.empty()); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); } - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; - active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); - active_layer_->AppendQuads(render_pass.get(), &data); - active_layer_->DidDraw(nullptr); + active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer()->AppendQuads(render_pass.get(), &data); + active_layer()->DidDraw(nullptr); DrawQuad::Material expected = test_for_solid ? DrawQuad::Material::SOLID_COLOR @@ -4406,7 +4276,7 @@ TEST_F(PictureLayerImplTest, DrawNonSolidQuads) { } TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); gfx::Size layer_bounds(200, 200); @@ -4417,7 +4287,7 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); host->SetRootLayer(layer); RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); @@ -4438,11 +4308,11 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { SetupPendingTree(raster_source1); ActivateTree(); bool update_lcd_text = false; - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text); // We've started with a solid layer that contains some tilings. - ASSERT_TRUE(active_layer_->tilings()); - EXPECT_NE(0u, active_layer_->tilings()->num_tilings()); + ASSERT_TRUE(active_layer()->tilings()); + EXPECT_NE(0u, active_layer()->tilings()->num_tilings()); client.set_fill_with_nonsolid_color(false); @@ -4459,12 +4329,12 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { ActivateTree(); // We've switched to a solid color, so we should end up with no tilings. - ASSERT_TRUE(active_layer_->tilings()); - EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); + ASSERT_TRUE(active_layer()->tilings()); + EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); } TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(400, 4000); SetupDefaultTrees(layer_bounds); @@ -4473,52 +4343,50 @@ TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) { gfx::Rect viewport = gfx::Rect(0, 0, 100, 100); gfx::Transform transform; - host_impl_.SetRequiresHighResToDraw(); + host_impl()->SetRequiresHighResToDraw(); // Update tiles. - 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, + 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); - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); // Ensure we can't activate. - EXPECT_FALSE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate()); // Now in the same frame, move the viewport (this can happen during // animation). viewport = gfx::Rect(0, 2000, 100, 100); // Update tiles. - 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, + 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); - pending_layer_->HighResTiling()->UpdateAllRequiredStateForTesting(); + pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting(); // Make sure all viewport tiles (viewport from the tiling) are ready to draw. std::vector<Tile*> tiles; for (PictureLayerTiling::CoverageIterator iter( - pending_layer_->HighResTiling(), - 1.f, - pending_layer_->HighResTiling()->GetCurrentVisibleRectForTesting()); - iter; - ++iter) { + pending_layer()->HighResTiling(), 1.f, + pending_layer()->HighResTiling()->GetCurrentVisibleRectForTesting()); + iter; ++iter) { if (*iter) tiles.push_back(*iter); } for (PictureLayerTiling::CoverageIterator iter( - active_layer_->HighResTiling(), 1.f, - active_layer_->HighResTiling()->GetCurrentVisibleRectForTesting()); + active_layer()->HighResTiling(), 1.f, + active_layer()->HighResTiling()->GetCurrentVisibleRectForTesting()); iter; ++iter) { if (*iter) tiles.push_back(*iter); } - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); // Ensure we can activate. - EXPECT_TRUE(host_impl_.tile_manager()->IsReadyToActivate()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } TEST_F(PictureLayerImplTest, CloneMissingRecordings) { @@ -4535,8 +4403,8 @@ TEST_F(PictureLayerImplTest, CloneMissingRecordings) { SetupPendingTreeWithFixedTileSize(filled_raster_source, tile_size, Region()); ActivateTree(); - PictureLayerTiling* pending_tiling = old_pending_layer_->HighResTiling(); - PictureLayerTiling* active_tiling = active_layer_->HighResTiling(); + PictureLayerTiling* pending_tiling = old_pending_layer()->HighResTiling(); + PictureLayerTiling* active_tiling = active_layer()->HighResTiling(); // We should have all tiles on active, and none on pending. EXPECT_EQ(0u, pending_tiling->AllTilesForTesting().size()); @@ -4583,13 +4451,13 @@ TEST_F(PictureLayerImplTest, CloneMissingRecordings) { } TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); gfx::Size layer_bounds(100, 100); gfx::Size viewport_size(100, 100); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); SetInitialDeviceScaleFactor(1.f); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -4600,100 +4468,105 @@ TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) { SetupPendingTreeWithFixedTileSize(active_raster_source, tile_size, Region()); ActivateTree(); - EXPECT_TRUE(active_layer_->HighResTiling()->has_tiles()); + EXPECT_TRUE(active_layer()->HighResTiling()->has_tiles()); - host_impl_.SetExternalTilePriorityConstraints(gfx::Rect(0, 5000, 100, 100), - gfx::Transform()); + host_impl()->SetExternalTilePriorityConstraints(gfx::Rect(0, 5000, 100, 100), + gfx::Transform()); SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, gfx::Rect()); - EXPECT_FALSE(pending_layer_->HighResTiling()->has_tiles()); - EXPECT_TRUE(pending_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); + EXPECT_FALSE(pending_layer()->HighResTiling()->has_tiles()); + EXPECT_TRUE(pending_layer()->HighResTiling()->live_tiles_rect().IsEmpty()); ActivateTree(); - EXPECT_FALSE(active_layer_->HighResTiling()->has_tiles()); - EXPECT_TRUE(active_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); + EXPECT_FALSE(active_layer()->HighResTiling()->has_tiles()); + EXPECT_TRUE(active_layer()->HighResTiling()->live_tiles_rect().IsEmpty()); - host_impl_.SetExternalTilePriorityConstraints(gfx::Rect(0, 110, 100, 100), - gfx::Transform()); + host_impl()->SetExternalTilePriorityConstraints(gfx::Rect(0, 110, 100, 100), + gfx::Transform()); SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, gfx::Rect()); - EXPECT_FALSE(pending_layer_->HighResTiling()->has_tiles()); - EXPECT_FALSE(pending_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); + EXPECT_FALSE(pending_layer()->HighResTiling()->has_tiles()); + EXPECT_FALSE(pending_layer()->HighResTiling()->live_tiles_rect().IsEmpty()); ActivateTree(); - EXPECT_TRUE(active_layer_->HighResTiling()->has_tiles()); - EXPECT_FALSE(active_layer_->HighResTiling()->live_tiles_rect().IsEmpty()); + EXPECT_TRUE(active_layer()->HighResTiling()->has_tiles()); + EXPECT_FALSE(active_layer()->HighResTiling()->live_tiles_rect().IsEmpty()); } TEST_F(PictureLayerImplTest, ScrollPropagatesToPending) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(100, 100); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); SetInitialDeviceScaleFactor(1.f); SetupDefaultTrees(layer_bounds); - active_layer_->SetCurrentScrollOffset(gfx::ScrollOffset(0.0, 50.0)); - host_impl_.active_tree()->UpdateDrawProperties(false); - EXPECT_EQ("0,50 100x100", active_layer_->HighResTiling() + active_layer()->SetCurrentScrollOffset(gfx::ScrollOffset(0.0, 50.0)); + host_impl()->active_tree()->UpdateDrawProperties(false); + EXPECT_EQ("0,50 100x100", active_layer() + ->HighResTiling() ->GetCurrentVisibleRectForTesting() .ToString()); - EXPECT_EQ("0,0 100x100", pending_layer_->HighResTiling() + EXPECT_EQ("0,0 100x100", pending_layer() + ->HighResTiling() ->GetCurrentVisibleRectForTesting() .ToString()); - host_impl_.pending_tree()->UpdateDrawProperties(false); - EXPECT_EQ("0,50 100x100", pending_layer_->HighResTiling() + host_impl()->pending_tree()->UpdateDrawProperties(false); + EXPECT_EQ("0,50 100x100", pending_layer() + ->HighResTiling() ->GetCurrentVisibleRectForTesting() .ToString()); } TEST_F(PictureLayerImplTest, UpdateLCDInvalidatesPendingTree) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); gfx::Size layer_bounds(100, 100); gfx::Size viewport_size(100, 100); - host_impl_.SetViewportSize(viewport_size); + host_impl()->SetViewportSize(viewport_size); SetInitialDeviceScaleFactor(1.f); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilledLCD(layer_bounds); SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region()); - EXPECT_TRUE(pending_layer_->RasterSourceUsesLCDText()); - EXPECT_TRUE(pending_layer_->HighResTiling()->has_tiles()); + EXPECT_TRUE(pending_layer()->RasterSourceUsesLCDText()); + EXPECT_TRUE(pending_layer()->HighResTiling()->has_tiles()); std::vector<Tile*> tiles = - pending_layer_->HighResTiling()->AllTilesForTesting(); - auto prioritized_tiles = pending_layer_->HighResTiling() + pending_layer()->HighResTiling()->AllTilesForTesting(); + auto prioritized_tiles = pending_layer() + ->HighResTiling() ->UpdateAndGetAllPrioritizedTilesForTesting(); for (Tile* tile : tiles) - EXPECT_EQ(pending_layer_->raster_source(), + EXPECT_EQ(pending_layer()->raster_source(), prioritized_tiles[tile].raster_source()); - pending_layer_->draw_properties().can_use_lcd_text = false; - pending_layer_->UpdateCanUseLCDTextAfterCommit(); + pending_layer()->draw_properties().can_use_lcd_text = false; + pending_layer()->UpdateCanUseLCDTextAfterCommit(); - EXPECT_FALSE(pending_layer_->RasterSourceUsesLCDText()); - EXPECT_NE(pending_raster_source.get(), pending_layer_->raster_source()); - EXPECT_TRUE(pending_layer_->HighResTiling()->has_tiles()); - tiles = pending_layer_->HighResTiling()->AllTilesForTesting(); - prioritized_tiles = pending_layer_->HighResTiling() + EXPECT_FALSE(pending_layer()->RasterSourceUsesLCDText()); + EXPECT_NE(pending_raster_source.get(), pending_layer()->raster_source()); + EXPECT_TRUE(pending_layer()->HighResTiling()->has_tiles()); + tiles = pending_layer()->HighResTiling()->AllTilesForTesting(); + prioritized_tiles = pending_layer() + ->HighResTiling() ->UpdateAndGetAllPrioritizedTilesForTesting(); for (Tile* tile : tiles) - EXPECT_EQ(pending_layer_->raster_source(), + EXPECT_EQ(pending_layer()->raster_source(), prioritized_tiles[tile].raster_source()); } TEST_F(PictureLayerImplTest, TilingAllTilesDone) { - gfx::Size tile_size = host_impl_.settings().default_tile_size; + 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); @@ -4701,13 +4574,13 @@ TEST_F(PictureLayerImplTest, TilingAllTilesDone) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - pending_layer_->SetBounds(layer_bounds); + pending_layer()->SetBounds(layer_bounds); ActivateTree(); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting( - active_layer_->HighResTiling()->AllTilesForTesting()); - host_impl_.SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES); + 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()); + EXPECT_FALSE(active_layer()->HighResTiling()->all_tiles_done()); { // Set a memory policy that will fit all tiles. @@ -4716,10 +4589,10 @@ TEST_F(PictureLayerImplTest, TilingAllTilesDone) { ManagedMemoryPolicy policy(memory_limit, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, max_tiles); - host_impl_.SetMemoryPolicy(policy); - host_impl_.PrepareTiles(); + host_impl()->SetMemoryPolicy(policy); + host_impl()->PrepareTiles(); - EXPECT_TRUE(active_layer_->HighResTiling()->all_tiles_done()); + EXPECT_TRUE(active_layer()->HighResTiling()->all_tiles_done()); } { @@ -4729,39 +4602,36 @@ TEST_F(PictureLayerImplTest, TilingAllTilesDone) { ManagedMemoryPolicy policy(memory_limit, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, max_tiles); - host_impl_.SetMemoryPolicy(policy); - host_impl_.PrepareTiles(); + host_impl()->SetMemoryPolicy(policy); + host_impl()->PrepareTiles(); - EXPECT_FALSE(active_layer_->HighResTiling()->all_tiles_done()); + EXPECT_FALSE(active_layer()->HighResTiling()->all_tiles_done()); } } -class TileSizeSettings : public PictureLayerImplTestSettings { - public: - TileSizeSettings() { - default_tile_size = gfx::Size(100, 100); - max_untiled_layer_size = gfx::Size(200, 200); - } -}; - class TileSizeTest : public PictureLayerImplTest { public: - TileSizeTest() : PictureLayerImplTest(TileSizeSettings()) {} + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + settings.default_tile_size = gfx::Size(100, 100); + settings.max_untiled_layer_size = gfx::Size(200, 200); + return settings; + } }; TEST_F(TileSizeTest, TileSizes) { - host_impl_.CreatePendingTree(); + host_impl()->CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl_.pending_tree(); - scoped_ptr<FakePictureLayerImpl> layer = - FakePictureLayerImpl::Create(pending_tree, id_); + LayerTreeImpl* pending_tree = host_impl()->pending_tree(); + std::unique_ptr<FakePictureLayerImpl> layer = + FakePictureLayerImpl::Create(pending_tree, layer_id()); - host_impl_.SetViewportSize(gfx::Size(1000, 1000)); + host_impl()->SetViewportSize(gfx::Size(1000, 1000)); gfx::Size result; - host_impl_.SetContentIsSuitableForGpuRasterization(true); - host_impl_.SetHasGpuRasterizationTrigger(false); - EXPECT_EQ(host_impl_.gpu_rasterization_status(), + host_impl()->SetContentIsSuitableForGpuRasterization(true); + host_impl()->SetHasGpuRasterizationTrigger(false); + EXPECT_EQ(host_impl()->gpu_rasterization_status(), GpuRasterizationStatus::OFF_VIEWPORT); // Default tile-size for large layers. @@ -4781,11 +4651,12 @@ TEST_F(TileSizeTest, TileSizes) { // Gpu-rasterization uses 25% viewport-height tiles. // The +2's below are for border texels. - host_impl_.SetHasGpuRasterizationTrigger(true); - EXPECT_EQ(host_impl_.gpu_rasterization_status(), GpuRasterizationStatus::ON); - host_impl_.SetViewportSize(gfx::Size(2000, 2000)); + host_impl()->SetHasGpuRasterizationTrigger(true); + EXPECT_EQ(host_impl()->gpu_rasterization_status(), + GpuRasterizationStatus::ON); + host_impl()->SetViewportSize(gfx::Size(2000, 2000)); - layer->set_gpu_raster_max_texture_size(host_impl_.device_viewport_size()); + layer->set_gpu_raster_max_texture_size(host_impl()->device_viewport_size()); result = layer->CalculateTileSize(gfx::Size(10000, 10000)); EXPECT_EQ(result.width(), MathUtil::UncheckedRoundUp( @@ -4794,8 +4665,8 @@ TEST_F(TileSizeTest, TileSizes) { // Clamp and round-up, when smaller than viewport. // Tile-height doubles to 50% when width shrinks to <= 50%. - host_impl_.SetViewportSize(gfx::Size(1000, 1000)); - layer->set_gpu_raster_max_texture_size(host_impl_.device_viewport_size()); + host_impl()->SetViewportSize(gfx::Size(1000, 1000)); + layer->set_gpu_raster_max_texture_size(host_impl()->device_viewport_size()); result = layer->CalculateTileSize(gfx::Size(447, 10000)); EXPECT_EQ(result.width(), 448); EXPECT_EQ(result.height(), 504); // 500 + 2, 4-byte aliged. @@ -4813,7 +4684,7 @@ TEST_F(TileSizeTest, TileSizes) { TEST_F(NoLowResPictureLayerImplTest, LowResWasHighResCollision) { gfx::Size layer_bounds(1300, 1900); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; SetupDefaultTrees(layer_bounds); ResetTilingsAndRasterScales(); @@ -4822,20 +4693,20 @@ TEST_F(NoLowResPictureLayerImplTest, LowResWasHighResCollision) { EXPECT_BOTH_EQ(num_tilings(), 1u); EXPECT_BOTH_EQ(tilings()->tiling_at(0)->contents_scale(), page_scale); - host_impl_.PinchGestureBegin(); + 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()); + EXPECT_EQ(1u, pending_layer()->num_tilings()); + EXPECT_EQ(zoomed, pending_layer()->tilings()->tiling_at(0)->contents_scale()); } TEST_F(PictureLayerImplTest, HighResWasLowResCollision) { gfx::Size layer_bounds(1300, 1900); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; SetupDefaultTrees(layer_bounds); ResetTilingsAndRasterScales(); @@ -4843,34 +4714,36 @@ TEST_F(PictureLayerImplTest, HighResWasLowResCollision) { float page_scale = 4.f; float low_res = page_scale * low_res_factor; float extra_low_res = low_res * low_res_factor; - SetupDrawPropertiesAndUpdateTiles(active_layer_, page_scale, 1.0f, page_scale, - 1.0f, 0.f, false); - EXPECT_EQ(2u, active_layer_->tilings()->num_tilings()); + SetupDrawPropertiesAndUpdateTiles(active_layer(), page_scale, 1.0f, + page_scale, 1.0f, 0.f, false); + EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); EXPECT_EQ(page_scale, - active_layer_->tilings()->tiling_at(0)->contents_scale()); - EXPECT_EQ(low_res, active_layer_->tilings()->tiling_at(1)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(low_res, active_layer()->tilings()->tiling_at(1)->contents_scale()); // Grab a current low res tile. PictureLayerTiling* old_low_res_tiling = - active_layer_->tilings()->tiling_at(1); - Tile* old_low_res_tile = active_layer_->tilings()->tiling_at(1)->TileAt(0, 0); + active_layer()->tilings()->tiling_at(1); + Tile* old_low_res_tile = + active_layer()->tilings()->tiling_at(1)->TileAt(0, 0); // The tiling knows it has low res content. - EXPECT_TRUE(active_layer_->tilings() + EXPECT_TRUE(active_layer() + ->tilings() ->tiling_at(1) ->may_contain_low_resolution_tiles()); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); // Zoom in to exactly the low res factor so that the previous low res // would be equal to the current high res. - SetupDrawPropertiesAndUpdateTiles(active_layer_, low_res, 1.0f, low_res, 1.0f, - 0.f, false); + SetupDrawPropertiesAndUpdateTiles(active_layer(), low_res, 1.0f, low_res, + 1.0f, 0.f, false); // 3 tilings. The old high res, the new high res (old low res) and the new low // res. - EXPECT_EQ(3u, active_layer_->num_tilings()); + EXPECT_EQ(3u, active_layer()->num_tilings()); - PictureLayerTilingSet* tilings = active_layer_->tilings(); + PictureLayerTilingSet* tilings = active_layer()->tilings(); EXPECT_EQ(page_scale, tilings->tiling_at(0)->contents_scale()); EXPECT_EQ(low_res, tilings->tiling_at(1)->contents_scale()); EXPECT_EQ(extra_low_res, tilings->tiling_at(2)->contents_scale()); diff --git a/chromium/cc/layers/picture_layer_unittest.cc b/chromium/cc/layers/picture_layer_unittest.cc index c57bb61e585..c616f47763d 100644 --- a/chromium/cc/layers/picture_layer_unittest.cc +++ b/chromium/cc/layers/picture_layer_unittest.cc @@ -6,7 +6,8 @@ #include <stddef.h> -#include "base/thread_task_runner_handle.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/content_layer_client.h" #include "cc/layers/empty_content_layer_client.h" @@ -20,11 +21,13 @@ #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_proxy.h" #include "cc/test/fake_recording_source.h" +#include "cc/test/layer_tree_settings_for_testing.h" #include "cc/test/skia_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/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkRefCnt.h" namespace cc { @@ -64,10 +67,10 @@ class TestSerializationPictureLayer : public PictureLayer { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings; - scoped_ptr<FakeImageSerializationProcessor> + std::unique_ptr<FakeImageSerializationProcessor> fake_image_serialization_processor = - make_scoped_ptr(new FakeImageSerializationProcessor); - scoped_ptr<FakeLayerTreeHost> host = + base::WrapUnique(new FakeImageSerializationProcessor); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner, settings, CompositorMode::SINGLE_THREADED, fake_image_serialization_processor.get()); @@ -85,7 +88,7 @@ class TestSerializationPictureLayer : public PictureLayer { private: TestSerializationPictureLayer(ContentLayerClient* client, - scoped_ptr<RecordingSource> source, + std::unique_ptr<RecordingSource> source, const gfx::Size& recording_source_viewport) : PictureLayer(client, std::move(source)), recording_source_viewport_(recording_source_viewport) {} @@ -102,10 +105,10 @@ TEST(PictureLayerTest, TestSetAllPropsSerializationDeserialization) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings; - scoped_ptr<FakeImageSerializationProcessor> + std::unique_ptr<FakeImageSerializationProcessor> fake_image_serialization_processor = - make_scoped_ptr(new FakeImageSerializationProcessor); - scoped_ptr<FakeLayerTreeHost> host = + base::WrapUnique(new FakeImageSerializationProcessor); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner, settings, CompositorMode::SINGLE_THREADED, fake_image_serialization_processor.get()); @@ -133,10 +136,10 @@ TEST(PictureLayerTest, TestSetAllPropsSerializationDeserialization) { TEST(PictureLayerTest, TestSerializationDeserialization) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeImageSerializationProcessor> + std::unique_ptr<FakeImageSerializationProcessor> fake_image_serialization_processor = - make_scoped_ptr(new FakeImageSerializationProcessor); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + base::WrapUnique(new FakeImageSerializationProcessor); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( &host_client, &task_graph_runner, LayerTreeSettings(), CompositorMode::SINGLE_THREADED, fake_image_serialization_processor.get()); @@ -158,7 +161,7 @@ TEST(PictureLayerTest, TestSerializationDeserialization) { TEST(PictureLayerTest, TestEmptySerializationDeserialization) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); gfx::Size recording_source_viewport(256, 256); @@ -175,7 +178,7 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); host->SetRootLayer(layer); layer->SetIsDrawable(true); @@ -194,15 +197,15 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) { FakeImplTaskRunnerProvider impl_task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; - scoped_ptr<FakeOutputSurface> output_surface = + std::unique_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); FakeLayerTreeHostImpl host_impl(LayerTreeSettings(), &impl_task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.InitializeRenderer(output_surface.get()); host_impl.CreatePendingTree(); - scoped_ptr<FakePictureLayerImpl> layer_impl = + std::unique_ptr<FakePictureLayerImpl> layer_impl = FakePictureLayerImpl::Create(host_impl.pending_tree(), 1); layer->PushPropertiesTo(layer_impl.get()); @@ -221,7 +224,7 @@ TEST(PictureLayerTest, InvalidateRasterAfterUpdate) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); host->SetRootLayer(layer); layer->SetIsDrawable(true); @@ -236,7 +239,7 @@ TEST(PictureLayerTest, InvalidateRasterAfterUpdate) { host->CommitComplete(); FakeImplTaskRunnerProvider impl_task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + std::unique_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); LayerTreeSettings layer_tree_settings = LayerTreeSettings(); layer_tree_settings.image_decode_tasks_enabled = true; FakeLayerTreeHostImpl host_impl(layer_tree_settings, @@ -264,7 +267,7 @@ TEST(PictureLayerTest, InvalidateRasterWithoutUpdate) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); host->SetRootLayer(layer); layer->SetIsDrawable(true); @@ -278,7 +281,7 @@ TEST(PictureLayerTest, InvalidateRasterWithoutUpdate) { host->CommitComplete(); FakeImplTaskRunnerProvider impl_task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + std::unique_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); LayerTreeSettings layer_tree_settings = LayerTreeSettings(); layer_tree_settings.image_decode_tasks_enabled = true; FakeLayerTreeHostImpl host_impl(layer_tree_settings, @@ -300,14 +303,14 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { gfx::Size layer_size(50, 50); FakeContentLayerClient client; client.set_bounds(layer_size); - skia::RefPtr<SkImage> image = CreateDiscardableImage(layer_size); - client.add_draw_image(image.get(), gfx::Point(), SkPaint()); + client.add_draw_image(CreateDiscardableImage(layer_size), gfx::Point(), + SkPaint()); scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); layer->SetBounds(gfx::Size(10, 10)); FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); host->SetRootLayer(layer); layer->SetIsDrawable(true); @@ -324,8 +327,8 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { FakeImplTaskRunnerProvider impl_task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); - LayerTreeSettings layer_tree_settings = LayerTreeSettings(); + std::unique_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + LayerTreeSettings layer_tree_settings = LayerTreeSettingsForTesting(); layer_tree_settings.image_decode_tasks_enabled = true; FakeLayerTreeHostImpl host_impl(layer_tree_settings, &impl_task_runner_provider, @@ -367,7 +370,7 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { host_impl.ActivateSyncTree(); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; host_impl.active_tree()->root_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); host_impl.active_tree()->root_layer()->AppendQuads(render_pass.get(), &data); @@ -375,7 +378,7 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { } TEST(PictureLayerTest, SuitableForGpuRasterization) { - scoped_ptr<FakeRecordingSource> recording_source_owned( + std::unique_ptr<FakeRecordingSource> recording_source_owned( new FakeRecordingSource); FakeRecordingSource* recording_source = recording_source_owned.get(); @@ -386,7 +389,7 @@ TEST(PictureLayerTest, SuitableForGpuRasterization) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner); host->SetRootLayer(layer); @@ -415,6 +418,7 @@ TEST(PictureLayerTest, NonMonotonicSourceFrameNumber) { LayerTreeSettings settings; settings.single_thread_proxy_scheduler = false; settings.use_zero_copy = true; + settings.verify_clip_tree_calculations = true; FakeLayerTreeHostClient host_client1(FakeLayerTreeHostClient::DIRECT_3D); FakeLayerTreeHostClient host_client2(FakeLayerTreeHostClient::DIRECT_3D); @@ -430,13 +434,13 @@ TEST(PictureLayerTest, NonMonotonicSourceFrameNumber) { params.settings = &settings; params.task_graph_runner = &task_graph_runner; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); - scoped_ptr<LayerTreeHost> host1 = + std::unique_ptr<LayerTreeHost> host1 = LayerTreeHost::CreateSingleThreaded(&host_client1, ¶ms); host1->SetVisible(true); host_client1.SetLayerTreeHost(host1.get()); params.client = &host_client2; - scoped_ptr<LayerTreeHost> host2 = + std::unique_ptr<LayerTreeHost> host2 = LayerTreeHost::CreateSingleThreaded(&host_client2, ¶ms); host2->SetVisible(true); host_client2.SetLayerTreeHost(host2.get()); diff --git a/chromium/cc/layers/render_pass_sink.h b/chromium/cc/layers/render_pass_sink.h index 725f1dd0902..aa5bfbcfc85 100644 --- a/chromium/cc/layers/render_pass_sink.h +++ b/chromium/cc/layers/render_pass_sink.h @@ -5,7 +5,8 @@ #ifndef CC_LAYERS_RENDER_PASS_SINK_H_ #define CC_LAYERS_RENDER_PASS_SINK_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" namespace cc { @@ -13,7 +14,7 @@ class RenderPass; class CC_EXPORT RenderPassSink { public: - virtual void AppendRenderPass(scoped_ptr<RenderPass> render_pass) = 0; + virtual void AppendRenderPass(std::unique_ptr<RenderPass> render_pass) = 0; protected: virtual ~RenderPassSink() {} diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc index 4ca32253782..ed036f3933e 100644 --- a/chromium/cc/layers/render_surface_impl.cc +++ b/chromium/cc/layers/render_surface_impl.cc @@ -40,6 +40,28 @@ RenderSurfaceImpl::RenderSurfaceImpl(LayerImpl* owning_layer) RenderSurfaceImpl::~RenderSurfaceImpl() {} +RenderSurfaceImpl* RenderSurfaceImpl::render_target() { + EffectTree& effect_tree = + owning_layer_->layer_tree_impl()->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(EffectTreeIndex()); + EffectNode* target_node = effect_tree.Node(node->data.target_id); + if (target_node->id != 0) + return target_node->data.render_surface; + else + return this; +} + +const RenderSurfaceImpl* RenderSurfaceImpl::render_target() const { + const EffectTree& effect_tree = + owning_layer_->layer_tree_impl()->property_trees()->effect_tree; + const EffectNode* node = effect_tree.Node(EffectTreeIndex()); + const EffectNode* target_node = effect_tree.Node(node->data.target_id); + if (target_node->id != 0) + return target_node->data.render_surface; + else + return this; +} + RenderSurfaceImpl::DrawProperties::DrawProperties() { draw_opacity = 1.f; is_clipped = false; @@ -48,16 +70,23 @@ RenderSurfaceImpl::DrawProperties::DrawProperties() { RenderSurfaceImpl::DrawProperties::~DrawProperties() {} gfx::RectF RenderSurfaceImpl::DrawableContentRect() const { - gfx::RectF drawable_content_rect = - MathUtil::MapClippedRect(draw_transform(), gfx::RectF(content_rect())); - if (owning_layer_->has_replica()) { - drawable_content_rect.Union(MathUtil::MapClippedRect( - replica_draw_transform(), gfx::RectF(content_rect()))); - } + if (content_rect().IsEmpty()) + return gfx::RectF(); + + gfx::Rect surface_content_rect = content_rect(); if (!owning_layer_->filters().IsEmpty()) { int left, top, right, bottom; owning_layer_->filters().GetOutsets(&top, &right, &bottom, &left); - drawable_content_rect.Inset(-left, -top, -right, -bottom); + surface_content_rect.Inset(-left, -top, -right, -bottom); + } + gfx::RectF drawable_content_rect = MathUtil::MapClippedRect( + draw_transform(), gfx::RectF(surface_content_rect)); + if (owning_layer_->has_replica()) { + drawable_content_rect.Union(MathUtil::MapClippedRect( + replica_draw_transform(), gfx::RectF(surface_content_rect))); + } else if (!owning_layer_->filters().IsEmpty() && is_clipped()) { + // Filter could move pixels around, but still need to be clipped. + drawable_content_rect.Intersect(gfx::RectF(clip_rect())); } // If the rect has a NaN coordinate, we return empty rect to avoid crashes in @@ -128,9 +157,111 @@ void RenderSurfaceImpl::SetContentRect(const gfx::Rect& content_rect) { draw_properties_.content_rect = content_rect; } -void RenderSurfaceImpl::SetAccumulatedContentRect( - const gfx::Rect& content_rect) { - accumulated_content_rect_ = content_rect; +void RenderSurfaceImpl::SetContentRectForTesting(const gfx::Rect& rect) { + SetContentRect(rect); +} + +gfx::Rect RenderSurfaceImpl::CalculateClippedAccumulatedContentRect() { + if (owning_layer_->replica_layer() || owning_layer_->HasCopyRequest() || + !is_clipped()) + return accumulated_content_rect(); + + if (accumulated_content_rect().IsEmpty()) + return gfx::Rect(); + + // Calculate projection from the target surface rect to local + // space. Non-invertible draw transforms means no able to bring clipped rect + // in target space back to local space, early out without clip. + gfx::Transform target_to_surface(gfx::Transform::kSkipInitialization); + if (!draw_transform().GetInverse(&target_to_surface)) + return accumulated_content_rect(); + + // Clip rect is in target space. Bring accumulated content rect to + // target space in preparation for clipping. + gfx::Rect accumulated_rect_in_target_space = + MathUtil::MapEnclosingClippedRect(draw_transform(), + accumulated_content_rect()); + // If accumulated content rect is contained within clip rect, early out + // without clipping. + if (clip_rect().Contains(accumulated_rect_in_target_space)) + return accumulated_content_rect(); + + gfx::Rect clipped_accumulated_rect_in_target_space = clip_rect(); + clipped_accumulated_rect_in_target_space.Intersect( + accumulated_rect_in_target_space); + + if (clipped_accumulated_rect_in_target_space.IsEmpty()) + return gfx::Rect(); + + gfx::Rect clipped_accumulated_rect_in_local_space = + MathUtil::ProjectEnclosingClippedRect( + target_to_surface, clipped_accumulated_rect_in_target_space); + // Bringing clipped accumulated rect back to local space may result + // in inflation due to axis-alignment. + clipped_accumulated_rect_in_local_space.Intersect(accumulated_content_rect()); + return clipped_accumulated_rect_in_local_space; +} + +void RenderSurfaceImpl::CalculateContentRectFromAccumulatedContentRect( + int max_texture_size) { + // Root render surface use viewport, and does not calculate content rect. + DCHECK_NE(render_target(), this); + + // Surface's content rect is the clipped accumulated content rect. By default + // use accumulated content rect, and then try to clip it. + gfx::Rect surface_content_rect = CalculateClippedAccumulatedContentRect(); + + // The RenderSurfaceImpl backing texture cannot exceed the maximum + // supported texture size. + surface_content_rect.set_width( + std::min(surface_content_rect.width(), max_texture_size)); + surface_content_rect.set_height( + std::min(surface_content_rect.height(), max_texture_size)); + + SetContentRect(surface_content_rect); +} + +void RenderSurfaceImpl::SetContentRectToViewport() { + // Only root render surface use viewport as content rect. + DCHECK_EQ(render_target(), this); + gfx::Rect viewport = gfx::ToEnclosingRect(owning_layer_->layer_tree_impl() + ->property_trees() + ->clip_tree.ViewportClip()); + SetContentRect(viewport); +} + +void RenderSurfaceImpl::ClearAccumulatedContentRect() { + accumulated_content_rect_ = gfx::Rect(); +} + +void RenderSurfaceImpl::AccumulateContentRectFromContributingLayer( + LayerImpl* layer) { + DCHECK(layer->DrawsContent()); + DCHECK_EQ(this, layer->render_target()); + + // Root render surface doesn't accumulate content rect, it always uses + // viewport for content rect. + if (render_target() == this) + return; + + accumulated_content_rect_.Union(layer->drawable_content_rect()); +} + +void RenderSurfaceImpl::AccumulateContentRectFromContributingRenderSurface( + RenderSurfaceImpl* contributing_surface) { + DCHECK_NE(this, contributing_surface); + DCHECK_EQ(this, contributing_surface->render_target()); + + // Root render surface doesn't accumulate content rect, it always uses + // viewport for content rect. + if (render_target() == this) + return; + + // The content rect of contributing surface is in its own space. Instead, we + // will use contributing surface's DrawableContentRect which is in target + // space (local space for this render surface) as required. + accumulated_content_rect_.Union( + gfx::ToEnclosedRect(contributing_surface->DrawableContentRect())); } bool RenderSurfaceImpl::SurfacePropertyChanged() const { @@ -163,7 +294,7 @@ RenderPassId RenderSurfaceImpl::GetRenderPassId() { } void RenderSurfaceImpl::AppendRenderPasses(RenderPassSink* pass_sink) { - scoped_ptr<RenderPass> pass = RenderPass::Create(layer_list_.size()); + std::unique_ptr<RenderPass> pass = RenderPass::Create(layer_list_.size()); pass->SetNew(GetRenderPassId(), content_rect(), gfx::IntersectRects(content_rect(), damage_tracker_->current_damage_rect()), diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h index de7a984da93..d4f5414a84b 100644 --- a/chromium/cc/layers/render_surface_impl.h +++ b/chromium/cc/layers/render_surface_impl.h @@ -7,11 +7,11 @@ #include <stddef.h> +#include <memory> #include <string> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_collections.h" #include "cc/quads/render_pass.h" @@ -37,9 +37,10 @@ class CC_EXPORT RenderSurfaceImpl { explicit RenderSurfaceImpl(LayerImpl* owning_layer); virtual ~RenderSurfaceImpl(); - gfx::PointF ContentRectCenter() const { - return gfx::RectF(content_rect()).CenterPoint(); - } + // Returns the RenderSurfaceImpl that this render surface contributes to. Root + // render surface's render_target is itself. + RenderSurfaceImpl* render_target(); + const RenderSurfaceImpl* render_target() const; // Returns the rect that encloses the RenderSurfaceImpl including any // reflection. @@ -50,7 +51,7 @@ class CC_EXPORT RenderSurfaceImpl { } float draw_opacity() const { return draw_properties_.draw_opacity; } - void SetNearestOcclusionImmuneAncestor(RenderSurfaceImpl* surface) { + void SetNearestOcclusionImmuneAncestor(const RenderSurfaceImpl* surface) { nearest_occlusion_immune_ancestor_ = surface; } const RenderSurfaceImpl* nearest_occlusion_immune_ancestor() const { @@ -112,10 +113,17 @@ class CC_EXPORT RenderSurfaceImpl { contributes_to_drawn_surface_ = contributes_to_drawn_surface; } - void SetContentRect(const gfx::Rect& content_rect); + void CalculateContentRectFromAccumulatedContentRect(int max_texture_size); + void SetContentRectToViewport(); + void SetContentRectForTesting(const gfx::Rect& rect); gfx::Rect content_rect() const { return draw_properties_.content_rect; } - void SetAccumulatedContentRect(const gfx::Rect& content_rect); + void ClearAccumulatedContentRect(); + void AccumulateContentRectFromContributingLayer( + LayerImpl* contributing_layer); + void AccumulateContentRectFromContributingRenderSurface( + RenderSurfaceImpl* contributing_surface); + gfx::Rect accumulated_content_rect() const { return accumulated_content_rect_; } @@ -157,6 +165,9 @@ class CC_EXPORT RenderSurfaceImpl { int EffectTreeIndex() const; private: + void SetContentRect(const gfx::Rect& content_rect); + gfx::Rect CalculateClippedAccumulatedContentRect(); + LayerImpl* owning_layer_; // Container for properties that render surfaces need to compute before they @@ -201,9 +212,9 @@ class CC_EXPORT RenderSurfaceImpl { // The nearest ancestor target surface that will contain the contents of this // surface, and that ignores outside occlusion. This can point to itself. - RenderSurfaceImpl* nearest_occlusion_immune_ancestor_; + const RenderSurfaceImpl* nearest_occlusion_immune_ancestor_; - scoped_ptr<DamageTracker> damage_tracker_; + std::unique_ptr<DamageTracker> damage_tracker_; // For LayerIteratorActions int target_render_surface_layer_index_history_; diff --git a/chromium/cc/layers/render_surface_impl_unittest.cc b/chromium/cc/layers/render_surface_impl_unittest.cc index 436eab59bef..815ebd3e3d5 100644 --- a/chromium/cc/layers/render_surface_impl_unittest.cc +++ b/chromium/cc/layers/render_surface_impl_unittest.cc @@ -24,7 +24,7 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) { LayerImpl* owning_layer_impl = impl.AddChildToRoot<LayerImpl>(); owning_layer_impl->SetBounds(layer_size); owning_layer_impl->SetDrawsContent(true); - owning_layer_impl->SetForceRenderSurface(true); + owning_layer_impl->test_properties()->force_render_surface = true; impl.CalcDrawProps(viewport_size); @@ -69,10 +69,10 @@ TEST(RenderSurfaceLayerImplTest, AppendQuadsWithScaledMask) { gfx::Size viewport_size(1000, 1000); LayerTestCommon::LayerImplTest impl; - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(impl.host_impl()->active_tree(), 2); root->SetHasRenderSurface(true); - scoped_ptr<LayerImpl> surface = + std::unique_ptr<LayerImpl> surface = LayerImpl::Create(impl.host_impl()->active_tree(), 3); surface->SetBounds(layer_size); surface->SetHasRenderSurface(true); @@ -86,7 +86,7 @@ TEST(RenderSurfaceLayerImplTest, AppendQuadsWithScaledMask) { surface->mask_layer()->SetDrawsContent(true); surface->mask_layer()->SetBounds(layer_size); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(impl.host_impl()->active_tree(), 5); child->SetDrawsContent(true); child->SetBounds(layer_size); @@ -102,7 +102,7 @@ TEST(RenderSurfaceLayerImplTest, AppendQuadsWithScaledMask) { LayerImpl* surface_raw = impl.host_impl()->active_tree()->root_layer()->children()[0]; RenderSurfaceImpl* render_surface_impl = surface_raw->render_surface(); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData append_quads_data; render_surface_impl->AppendQuads( render_pass.get(), render_surface_impl->draw_transform(), Occlusion(), diff --git a/chromium/cc/layers/render_surface_unittest.cc b/chromium/cc/layers/render_surface_unittest.cc index 2c15bf6d1c9..24652cca145 100644 --- a/chromium/cc/layers/render_surface_unittest.cc +++ b/chromium/cc/layers/render_surface_unittest.cc @@ -42,33 +42,32 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); - scoped_ptr<LayerImpl> owning_layer = + std::unique_ptr<LayerImpl> owning_layer = LayerImpl::Create(host_impl.active_tree(), 1); owning_layer->SetHasRenderSurface(true); ASSERT_TRUE(owning_layer->render_surface()); RenderSurfaceImpl* render_surface = owning_layer->render_surface(); gfx::Rect test_rect(3, 4, 5, 6); - host_impl.active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + host_impl.active_tree()->ResetAllChangeTracking(); // Currently, the content_rect, clip_rect, and // owning_layer->layerPropertyChanged() are the only sources of change. EXECUTE_AND_VERIFY_SURFACE_CHANGED(render_surface->SetClipRect(test_rect)); - EXECUTE_AND_VERIFY_SURFACE_CHANGED(render_surface->SetContentRect(test_rect)); + EXECUTE_AND_VERIFY_SURFACE_CHANGED( + render_surface->SetContentRectForTesting(test_rect)); owning_layer->SetOpacity(0.5f); EXPECT_TRUE(render_surface->SurfacePropertyChanged()); - host_impl.active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + host_impl.active_tree()->ResetAllChangeTracking(); // Setting the surface properties to the same values again should not be // considered "change". EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE( render_surface->SetClipRect(test_rect)); EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE( - render_surface->SetContentRect(test_rect)); + render_surface->SetContentRectForTesting(test_rect)); - scoped_ptr<LayerImpl> dummy_mask = + std::unique_ptr<LayerImpl> dummy_mask = LayerImpl::Create(host_impl.active_tree(), 2); gfx::Transform dummy_matrix; dummy_matrix.Translate(1.0, 2.0); @@ -91,31 +90,32 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); - scoped_ptr<LayerImpl> root_layer = + std::unique_ptr<LayerImpl> root_layer = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> owning_layer = + std::unique_ptr<LayerImpl> owning_layer = LayerImpl::Create(host_impl.active_tree(), 2); owning_layer->SetHasRenderSurface(true); ASSERT_TRUE(owning_layer->render_surface()); - owning_layer->draw_properties().render_target = owning_layer.get(); SkXfermode::Mode blend_mode = SkXfermode::kSoftLight_Mode; owning_layer->SetBlendMode(blend_mode); RenderSurfaceImpl* render_surface = owning_layer->render_surface(); root_layer->AddChild(std::move(owning_layer)); + host_impl.active_tree()->SetRootLayer(std::move(root_layer)); + host_impl.active_tree()->BuildPropertyTreesForTesting(); gfx::Rect content_rect(0, 0, 50, 50); gfx::Rect clip_rect(5, 5, 40, 40); gfx::Transform origin; origin.Translate(30, 40); - render_surface->SetContentRect(content_rect); + render_surface->SetContentRectForTesting(content_rect); render_surface->SetClipRect(clip_rect); render_surface->SetDrawOpacity(1.f); - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData append_quads_data; render_surface->AppendQuads(render_pass.get(), origin, Occlusion(), @@ -140,7 +140,7 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) { class TestRenderPassSink : public RenderPassSink { public: - void AppendRenderPass(scoped_ptr<RenderPass> render_pass) override { + void AppendRenderPass(std::unique_ptr<RenderPass> render_pass) override { render_passes_.push_back(std::move(render_pass)); } @@ -158,14 +158,13 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectRenderPass) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); - scoped_ptr<LayerImpl> root_layer = + std::unique_ptr<LayerImpl> root_layer = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> owning_layer = + std::unique_ptr<LayerImpl> owning_layer = LayerImpl::Create(host_impl.active_tree(), 2); owning_layer->SetHasRenderSurface(true); ASSERT_TRUE(owning_layer->render_surface()); - owning_layer->draw_properties().render_target = owning_layer.get(); RenderSurfaceImpl* render_surface = owning_layer->render_surface(); root_layer->AddChild(std::move(owning_layer)); @@ -175,7 +174,7 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectRenderPass) { origin.Translate(30.0, 40.0); render_surface->SetScreenSpaceTransform(origin); - render_surface->SetContentRect(content_rect); + render_surface->SetContentRectForTesting(content_rect); TestRenderPassSink pass_sink; diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.cc b/chromium/cc/layers/scrollbar_layer_impl_base.cc index e8e0f80a18c..25dd0add085 100644 --- a/chromium/cc/layers/scrollbar_layer_impl_base.cc +++ b/chromium/cc/layers/scrollbar_layer_impl_base.cc @@ -40,11 +40,6 @@ void ScrollbarLayerImplBase::PushPropertiesTo(LayerImpl* layer) { layer->ToScrollbarLayer()->SetScrollLayerId(ScrollLayerId()); } -void ScrollbarLayerImplBase::DidBecomeActive() { - LayerImpl::DidBecomeActive(); - UpdatePropertyTreeOpacity(); -} - ScrollbarLayerImplBase* ScrollbarLayerImplBase::ToScrollbarLayer() { return this; } diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.h b/chromium/cc/layers/scrollbar_layer_impl_base.h index 79a18e5a28c..5256e631eab 100644 --- a/chromium/cc/layers/scrollbar_layer_impl_base.h +++ b/chromium/cc/layers/scrollbar_layer_impl_base.h @@ -44,7 +44,6 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { bool CanScrollOrientation() const; void PushPropertiesTo(LayerImpl* layer) override; - void DidBecomeActive() override; ScrollbarLayerImplBase* ToScrollbarLayer() override; // Thumb quad rect in layer space. diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc index 0979b2f11ee..22114c8b297 100644 --- a/chromium/cc/layers/scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/scrollbar_layer_unittest.cc @@ -6,7 +6,7 @@ #include <unordered_map> -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/input/scrollbar_animation_controller.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/painted_scrollbar_layer.h" @@ -37,29 +37,6 @@ namespace cc { namespace { -LayerImpl* LayerImplForScrollAreaAndScrollbar(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> child2; - if (use_solid_color_scrollbar) { - const bool kIsLeftSideVerticalScrollbar = false; - child2 = SolidColorScrollbarLayer::Create( - scrollbar->Orientation(), thumb_thickness, track_start, - kIsLeftSideVerticalScrollbar, child1->id()); - } else { - child2 = PaintedScrollbarLayer::Create(std::move(scrollbar), child1->id()); - } - layer_tree_root->AddChild(child1); - layer_tree_root->InsertChild(child2, reverse_order ? 0 : 1); - host->SetRootLayer(layer_tree_root); - return host->CommitAndCreateLayerImplTree(); -} - class FakeResourceTrackingLayerTreeHost : public FakeLayerTreeHost { public: FakeResourceTrackingLayerTreeHost(FakeLayerTreeHostClient* client, @@ -123,6 +100,8 @@ class ScrollbarLayerTest : public testing::Test { layer_tree_settings_.single_thread_proxy_scheduler = false; layer_tree_settings_.use_zero_copy = true; + scrollbar_layer_id_ = -1; + LayerTreeHost::InitParams params; params.client = &fake_client_; params.settings = &layer_tree_settings_; @@ -137,21 +116,49 @@ class ScrollbarLayerTest : public testing::Test { EXPECT_FALSE(layer_tree_host_->output_surface_lost()); } + LayerImpl* LayerImplForScrollAreaAndScrollbar( + FakeLayerTreeHost* host, + std::unique_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> child2; + if (use_solid_color_scrollbar) { + const bool kIsLeftSideVerticalScrollbar = false; + child2 = SolidColorScrollbarLayer::Create( + scrollbar->Orientation(), thumb_thickness, track_start, + kIsLeftSideVerticalScrollbar, child1->id()); + } else { + child2 = + PaintedScrollbarLayer::Create(std::move(scrollbar), child1->id()); + } + layer_tree_root->AddChild(child1); + layer_tree_root->InsertChild(child2, reverse_order ? 0 : 1); + scrollbar_layer_id_ = reverse_order ? child1->id() : child2->id(); + host->SetRootLayer(layer_tree_root); + return host->CommitAndCreateLayerImplTree(); + } + protected: FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; LayerTreeSettings layer_tree_settings_; - scoped_ptr<FakeResourceTrackingLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeResourceTrackingLayerTreeHost> layer_tree_host_; + int scrollbar_layer_id_; }; TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { // Create and attach a non-overlay scrollbar. - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); + std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar); LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( layer_tree_host_.get(), std::move(scrollbar), false, false, 0, 0); PaintedScrollbarLayerImpl* scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - layer_impl_tree_root->children()[1]); + layer_impl_tree_root->layer_tree_impl()->LayerById( + scrollbar_layer_id_)); layer_impl_tree_root->layer_tree_impl()->BuildPropertyTreesForTesting(); ScrollTree& scroll_tree = layer_impl_tree_root->layer_tree_impl()->property_trees()->scroll_tree; @@ -173,7 +180,7 @@ TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( layer_tree_host_.get(), std::move(scrollbar), false, false, 0, 0); scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - layer_impl_tree_root->children()[1]); + layer_impl_tree_root->layer_tree_impl()->LayerById(scrollbar_layer_id_)); layer_impl_tree_root->layer_tree_impl()->BuildPropertyTreesForTesting(); scroll_tree = layer_impl_tree_root->layer_tree_impl()->property_trees()->scroll_tree; @@ -189,7 +196,7 @@ TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { } TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) { - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); + std::unique_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(); @@ -218,7 +225,8 @@ TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) { ScrollbarLayerImplBase* cc_scrollbar_layer = static_cast<PaintedScrollbarLayerImpl*>( - layer_impl_tree_root->children()[1]); + layer_impl_tree_root->layer_tree_impl()->LayerById( + scrollbar_layer->id())); EXPECT_EQ(10.f, cc_scrollbar_layer->current_pos()); EXPECT_EQ(30, cc_scrollbar_layer->scroll_layer_length() - @@ -239,7 +247,8 @@ TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) { EXPECT_EQ(300, cc_scrollbar_layer->scroll_layer_length() - cc_scrollbar_layer->clip_layer_length()); - LayerImpl* scroll_layer_impl = layer_impl_tree_root->children()[0]; + LayerImpl* scroll_layer_impl = + layer_impl_tree_root->layer_tree_impl()->LayerById(scroll_layer->id()); scroll_layer_impl->ScrollBy(gfx::Vector2d(12, 34)); EXPECT_EQ(112.f, cc_scrollbar_layer->current_pos()); @@ -252,9 +261,9 @@ TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) { scrollbar_layer->UpdateInternalContentScale(); \ scrollbar_layer->UpdateThumbAndTrackGeometry(); \ root_clip_layer_impl = layer_tree_host_->CommitAndCreateLayerImplTree(); \ - root_layer_impl = root_clip_layer_impl->children()[0]; \ scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( \ - root_layer_impl->children()[1]); \ + root_clip_layer_impl->layer_tree_impl()->LayerById( \ + scrollbar_layer->id())); \ } while (false) TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) { @@ -283,7 +292,6 @@ TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) { scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); scrollbar_layer->fake_scrollbar()->set_thumb_length(4); LayerImpl* root_clip_layer_impl = nullptr; - LayerImpl* root_layer_impl = nullptr; PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr; UPDATE_AND_EXTRACT_LAYER_POINTERS(); @@ -324,7 +332,6 @@ TEST_F(ScrollbarLayerTest, ThumbRect) { scrollbar_layer->fake_scrollbar()->set_thumb_length(4); layer_tree_host_->UpdateLayers(); LayerImpl* root_clip_layer_impl = nullptr; - LayerImpl* root_layer_impl = nullptr; PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr; // Thumb is at the edge of the scrollbar (should be inset to @@ -380,13 +387,14 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) { const int kTrackStart = 1; const int kTrackLength = 100; - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); + std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( layer_tree_host_.get(), std::move(scrollbar), false, true, kThumbThickness, kTrackStart); ScrollbarLayerImplBase* scrollbar_layer_impl = static_cast<SolidColorScrollbarLayerImpl*>( - layer_impl_tree_root->children()[1]); + layer_impl_tree_root->layer_tree_impl()->LayerById( + scrollbar_layer_id_)); scrollbar_layer_impl->SetBounds(gfx::Size(kTrackLength, kThumbThickness)); scrollbar_layer_impl->SetCurrentPos(10.f); scrollbar_layer_impl->SetClipLayerLength(200 / 3.f); @@ -394,7 +402,7 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) { // Thickness should be overridden to 3. { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; scrollbar_layer_impl->AppendQuads(render_pass.get(), &data); @@ -409,7 +417,7 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) { scrollbar_layer_impl->SetClipLayerLength(25.f); scrollbar_layer_impl->SetScrollLayerLength(125.f); { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; scrollbar_layer_impl->AppendQuads(render_pass.get(), &data); @@ -424,7 +432,7 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) { scrollbar_layer_impl->SetClipLayerLength(125.f); scrollbar_layer_impl->SetScrollLayerLength(125.f); { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; scrollbar_layer_impl->AppendQuads(render_pass.get(), &data); @@ -440,37 +448,36 @@ TEST_F(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { const int kTrackStart = 0; const int kTrackLength = 10; - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); + std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); - { - scoped_refptr<Layer> layer_tree_root = Layer::Create(); - scoped_refptr<Layer> scroll_layer = Layer::Create(); - scroll_layer->SetScrollClipLayerId(layer_tree_root->id()); - scoped_refptr<Layer> child1 = Layer::Create(); - scoped_refptr<Layer> child2; - const bool kIsLeftSideVerticalScrollbar = false; - child2 = SolidColorScrollbarLayer::Create( - scrollbar->Orientation(), kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, child1->id()); - child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id()); - scroll_layer->AddChild(child1); - scroll_layer->InsertChild(child2, 1); - layer_tree_root->AddChild(scroll_layer); - layer_tree_host_->SetRootLayer(layer_tree_root); + scoped_refptr<Layer> layer_tree_root = Layer::Create(); + scoped_refptr<Layer> scroll_layer = Layer::Create(); + scroll_layer->SetScrollClipLayerId(layer_tree_root->id()); + scoped_refptr<Layer> child1 = Layer::Create(); + scoped_refptr<Layer> child2; + const bool kIsLeftSideVerticalScrollbar = false; + child2 = SolidColorScrollbarLayer::Create( + scrollbar->Orientation(), kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar, child1->id()); + child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id()); + scroll_layer->AddChild(child1); + scroll_layer->InsertChild(child2, 1); + layer_tree_root->AddChild(scroll_layer); + layer_tree_host_->SetRootLayer(layer_tree_root); - // Choose layer bounds to give max_scroll_offset = (8, 8). - layer_tree_root->SetBounds(gfx::Size(2, 2)); - scroll_layer->SetBounds(gfx::Size(10, 10)); + // Choose layer bounds to give max_scroll_offset = (8, 8). + layer_tree_root->SetBounds(gfx::Size(2, 2)); + scroll_layer->SetBounds(gfx::Size(10, 10)); - layer_tree_host_->UpdateLayers(); - } + layer_tree_host_->UpdateLayers(); LayerImpl* layer_impl_tree_root = layer_tree_host_->CommitAndCreateLayerImplTree(); - LayerImpl* scroll_layer_impl = layer_impl_tree_root->children()[0]; + LayerImpl* scroll_layer_impl = + layer_impl_tree_root->layer_tree_impl()->LayerById(scroll_layer->id()); - auto* scrollbar_layer_impl = - static_cast<ScrollbarLayerImplBase*>(scroll_layer_impl->children()[1]); + auto* scrollbar_layer_impl = static_cast<ScrollbarLayerImplBase*>( + scroll_layer_impl->layer_tree_impl()->LayerById(child2->id())); scroll_layer_impl->ScrollBy(gfx::Vector2dF(4.f, 0.f)); @@ -478,7 +485,7 @@ TEST_F(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { scrollbar_layer_impl->SetCurrentPos(4.f); { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; scrollbar_layer_impl->AppendQuads(render_pass.get(), &data); @@ -490,6 +497,59 @@ TEST_F(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { } } +TEST_F(ScrollbarLayerTest, ScrollbarLayerOpacity) { + const int kThumbThickness = 3; + const int kTrackStart = 0; + + std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); + + scoped_refptr<Layer> layer_tree_root = Layer::Create(); + scoped_refptr<Layer> scroll_layer = Layer::Create(); + scroll_layer->SetScrollClipLayerId(layer_tree_root->id()); + scoped_refptr<Layer> child1 = Layer::Create(); + scoped_refptr<Layer> scrollbar_layer; + const bool kIsLeftSideVerticalScrollbar = false; + scrollbar_layer = SolidColorScrollbarLayer::Create( + scrollbar->Orientation(), kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar, child1->id()); + scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id()); + scroll_layer->AddChild(child1); + scroll_layer->InsertChild(scrollbar_layer, 1); + layer_tree_root->AddChild(scroll_layer); + layer_tree_host_->SetRootLayer(layer_tree_root); + + // Choose layer bounds to give max_scroll_offset = (8, 8). + layer_tree_root->SetBounds(gfx::Size(2, 2)); + scroll_layer->SetBounds(gfx::Size(10, 10)); + + layer_tree_host_->UpdateLayers(); + + LayerImpl* layer_impl_tree_root = + layer_tree_host_->CommitAndCreateLayerImplTree(); + + scrollbar_layer->SetOpacity(0.5f); + layer_tree_host_->UpdateLayers(); + EffectNode* node = layer_tree_host_->property_trees()->effect_tree.Node( + scrollbar_layer->effect_tree_index()); + EXPECT_EQ(node->data.opacity, 0.5f); + + LayerTreeHostImpl* host_impl = layer_tree_host_->host_impl(); + host_impl->CreatePendingTree(); + layer_impl_tree_root = layer_tree_host_->CommitAndCreatePendingTree(); + LayerTreeImpl* layer_tree_impl = layer_impl_tree_root->layer_tree_impl(); + EXPECT_TRUE(layer_tree_impl->IsPendingTree()); + layer_tree_impl->property_trees()->effect_tree.Node( + scrollbar_layer->effect_tree_index()); + EXPECT_EQ(node->data.opacity, 0.5f); + // The active tree opacity should not change with activation for scrollbar + // layer. + host_impl->ActivateSyncTree(); + layer_tree_impl = host_impl->active_tree(); + node = layer_tree_impl->property_trees()->effect_tree.Node( + scrollbar_layer->effect_tree_index()); + EXPECT_EQ(node->data.opacity, 1.f); +} + class ScrollbarLayerSolidColorThumbTest : public testing::Test { public: ScrollbarLayerSolidColorThumbTest() { @@ -525,9 +585,9 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { FakeImplTaskRunnerProvider task_runner_provider_; TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHostImpl> host_impl_; - scoped_ptr<SolidColorScrollbarLayerImpl> horizontal_scrollbar_layer_; - scoped_ptr<SolidColorScrollbarLayerImpl> vertical_scrollbar_layer_; + std::unique_ptr<FakeLayerTreeHostImpl> host_impl_; + std::unique_ptr<SolidColorScrollbarLayerImpl> horizontal_scrollbar_layer_; + std::unique_ptr<SolidColorScrollbarLayerImpl> vertical_scrollbar_layer_; }; TEST_F(ScrollbarLayerSolidColorThumbTest, SolidColorThumbLength) { @@ -606,7 +666,7 @@ class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest { scroll_layer_ = Layer::Create(); layer_tree_host()->root_layer()->AddChild(scroll_layer_); - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); + std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar); scrollbar_layer_ = PaintedScrollbarLayer::Create(std::move(scrollbar), scroll_layer_->id()); scrollbar_layer_->SetScrollLayer(scroll_layer_->id()); @@ -642,7 +702,7 @@ class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest { }; TEST_F(ScrollbarLayerTestMaxTextureSize, DirectRenderer) { - scoped_ptr<TestWebGraphicsContext3D> context = + std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); int max_size = 0; context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); @@ -651,7 +711,7 @@ TEST_F(ScrollbarLayerTestMaxTextureSize, DirectRenderer) { } TEST_F(ScrollbarLayerTestMaxTextureSize, DelegatingRenderer) { - scoped_ptr<TestWebGraphicsContext3D> context = + std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); int max_size = 0; context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); @@ -666,7 +726,7 @@ class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest { int expected_created, int expected_deleted, bool use_solid_color_scrollbar) { - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false)); + std::unique_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> scrollbar_layer; diff --git a/chromium/cc/layers/solid_color_layer.cc b/chromium/cc/layers/solid_color_layer.cc index 176f1e30d02..3f364a5b390 100644 --- a/chromium/cc/layers/solid_color_layer.cc +++ b/chromium/cc/layers/solid_color_layer.cc @@ -8,7 +8,7 @@ namespace cc { -scoped_ptr<LayerImpl> SolidColorLayer::CreateLayerImpl( +std::unique_ptr<LayerImpl> SolidColorLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return SolidColorLayerImpl::Create(tree_impl, id()); } diff --git a/chromium/cc/layers/solid_color_layer.h b/chromium/cc/layers/solid_color_layer.h index d1f108a6818..66a6ad8ec0e 100644 --- a/chromium/cc/layers/solid_color_layer.h +++ b/chromium/cc/layers/solid_color_layer.h @@ -18,7 +18,7 @@ class CC_EXPORT SolidColorLayer : public Layer { public: static scoped_refptr<SolidColorLayer> Create(); - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void SetBackgroundColor(SkColor color) override; diff --git a/chromium/cc/layers/solid_color_layer_impl.cc b/chromium/cc/layers/solid_color_layer_impl.cc index 76cd3fc4229..322d9c8c19f 100644 --- a/chromium/cc/layers/solid_color_layer_impl.cc +++ b/chromium/cc/layers/solid_color_layer_impl.cc @@ -22,7 +22,7 @@ SolidColorLayerImpl::SolidColorLayerImpl(LayerTreeImpl* tree_impl, int id) SolidColorLayerImpl::~SolidColorLayerImpl() {} -scoped_ptr<LayerImpl> SolidColorLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> SolidColorLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return SolidColorLayerImpl::Create(tree_impl, id()); } diff --git a/chromium/cc/layers/solid_color_layer_impl.h b/chromium/cc/layers/solid_color_layer_impl.h index a56b69b909b..1f6aaf5a267 100644 --- a/chromium/cc/layers/solid_color_layer_impl.h +++ b/chromium/cc/layers/solid_color_layer_impl.h @@ -5,8 +5,10 @@ #ifndef CC_LAYERS_SOLID_COLOR_LAYER_IMPL_H_ #define CC_LAYERS_SOLID_COLOR_LAYER_IMPL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" @@ -14,9 +16,9 @@ namespace cc { class CC_EXPORT SolidColorLayerImpl : public LayerImpl { public: - static scoped_ptr<SolidColorLayerImpl> Create(LayerTreeImpl* tree_impl, - int id) { - return make_scoped_ptr(new SolidColorLayerImpl(tree_impl, id)); + static std::unique_ptr<SolidColorLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new SolidColorLayerImpl(tree_impl, id)); } static void AppendSolidQuads(RenderPass* render_pass, @@ -29,7 +31,7 @@ class CC_EXPORT SolidColorLayerImpl : public LayerImpl { ~SolidColorLayerImpl() override; // LayerImpl overrides. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void AppendQuads(RenderPass* render_pass, AppendQuadsData* append_quads_data) override; diff --git a/chromium/cc/layers/solid_color_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_layer_impl_unittest.cc index 5a9b11d6db5..4ba8393810d 100644 --- a/chromium/cc/layers/solid_color_layer_impl_unittest.cc +++ b/chromium/cc/layers/solid_color_layer_impl_unittest.cc @@ -24,7 +24,7 @@ namespace cc { namespace { TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_size = gfx::Size(800, 600); gfx::Rect visible_layer_rect = gfx::Rect(layer_size); @@ -33,12 +33,11 @@ TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, &task_graph_runner); - scoped_ptr<SolidColorLayerImpl> layer = + std::unique_ptr<SolidColorLayerImpl> layer = SolidColorLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->SetForceRenderSurface(true); - layer->draw_properties().render_target = layer.get(); + layer->test_properties()->force_render_surface = true; AppendQuadsData data; layer->AppendQuads(render_pass.get(), &data); @@ -50,7 +49,7 @@ TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) { TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { SkColor test_color = 0xFFA55AFF; - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_size = gfx::Size(100, 100); gfx::Rect visible_layer_rect = gfx::Rect(layer_size); @@ -59,13 +58,12 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, &task_graph_runner); - scoped_ptr<SolidColorLayerImpl> layer = + std::unique_ptr<SolidColorLayerImpl> layer = SolidColorLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); layer->SetBackgroundColor(test_color); - layer->SetForceRenderSurface(true); - layer->draw_properties().render_target = layer.get(); + layer->test_properties()->force_render_surface = true; AppendQuadsData data; layer->AppendQuads(render_pass.get(), &data); @@ -79,7 +77,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { const float opacity = 0.5f; - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_size = gfx::Size(100, 100); gfx::Rect visible_layer_rect = gfx::Rect(layer_size); @@ -88,13 +86,12 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, &task_graph_runner); - scoped_ptr<SolidColorLayerImpl> layer = + std::unique_ptr<SolidColorLayerImpl> layer = SolidColorLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); layer->draw_properties().opacity = opacity; - layer->SetForceRenderSurface(true); - layer->draw_properties().render_target = layer.get(); + layer->test_properties()->force_render_surface = true; AppendQuadsData data; layer->AppendQuads(render_pass.get(), &data); @@ -108,7 +105,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { TEST(SolidColorLayerImplTest, VerifyCorrectBlendModeInQuad) { const SkXfermode::Mode blend_mode = SkXfermode::kMultiply_Mode; - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); gfx::Size layer_size = gfx::Size(100, 100); gfx::Rect visible_layer_rect = gfx::Rect(layer_size); @@ -117,7 +114,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBlendModeInQuad) { TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, &task_graph_runner); - scoped_ptr<SolidColorLayerImpl> layer = + std::unique_ptr<SolidColorLayerImpl> layer = SolidColorLayerImpl::Create(host_impl.active_tree(), 1); layer->SetBounds(layer_size); layer->set_draw_blend_mode(blend_mode); @@ -136,14 +133,14 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) { scoped_refptr<SolidColorLayer> layer = SolidColorLayer::Create(); layer->SetBounds(layer_size); - layer->SetForceRenderSurface(true); + layer->SetForceRenderSurfaceForTesting(true); scoped_refptr<Layer> root = Layer::Create(); root->AddChild(layer); FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client, &task_graph_runner); host->SetRootLayer(root); @@ -155,7 +152,7 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) { layer->SetBackgroundColor(SkColorSetARGBInline(255, 10, 20, 30)); EXPECT_TRUE(layer->contents_opaque()); { - scoped_ptr<SolidColorLayerImpl> layer_impl = + std::unique_ptr<SolidColorLayerImpl> layer_impl = SolidColorLayerImpl::Create(host->host_impl()->active_tree(), layer->id()); layer->PushPropertiesTo(layer_impl.get()); @@ -167,7 +164,7 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) { // should be the full tile. layer_impl->draw_properties().opacity = 1; - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; layer_impl->AppendQuads(render_pass.get(), &data); @@ -181,7 +178,7 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) { layer->SetBackgroundColor(SkColorSetARGBInline(254, 10, 20, 30)); EXPECT_FALSE(layer->contents_opaque()); { - scoped_ptr<SolidColorLayerImpl> layer_impl = + std::unique_ptr<SolidColorLayerImpl> layer_impl = SolidColorLayerImpl::Create(host->host_impl()->active_tree(), layer->id()); layer->PushPropertiesTo(layer_impl.get()); @@ -193,7 +190,7 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) { // should be empty. layer_impl->draw_properties().opacity = 1; - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; layer_impl->AppendQuads(render_pass.get(), &data); diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.cc b/chromium/cc/layers/solid_color_scrollbar_layer.cc index 9df9167c62a..131e7735cb1 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer.cc +++ b/chromium/cc/layers/solid_color_scrollbar_layer.cc @@ -4,13 +4,16 @@ #include "cc/layers/solid_color_scrollbar_layer.h" -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/layers/layer_impl.h" #include "cc/layers/solid_color_scrollbar_layer_impl.h" +#include "cc/proto/cc_conversions.h" +#include "cc/proto/layer.pb.h" namespace cc { -scoped_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl( +std::unique_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { const bool kIsOverlayScrollbar = true; return SolidColorScrollbarLayerImpl::Create(tree_impl, @@ -67,6 +70,10 @@ bool SolidColorScrollbarLayer::OpacityCanAnimateOnImplThread() const { return true; } +bool SolidColorScrollbarLayer::AlwaysUseActiveTreeOpacity() const { + return true; +} + int SolidColorScrollbarLayer::ScrollLayerId() const { return scroll_layer_id_; } @@ -83,4 +90,37 @@ ScrollbarOrientation SolidColorScrollbarLayer::orientation() const { return orientation_; } +void SolidColorScrollbarLayer::SetTypeForProtoSerialization( + proto::LayerNode* proto) const { + proto->set_type(proto::LayerNode::SOLID_COLOR_SCROLLBAR_LAYER); +} + +void SolidColorScrollbarLayer::LayerSpecificPropertiesToProto( + proto::LayerProperties* proto) { + Layer::LayerSpecificPropertiesToProto(proto); + + proto::SolidColorScrollbarLayerProperties* scrollbar = + proto->mutable_solid_scrollbar(); + scrollbar->set_scroll_layer_id(scroll_layer_id_); + scrollbar->set_thumb_thickness(thumb_thickness_); + scrollbar->set_track_start(track_start_); + scrollbar->set_is_left_side_vertical_scrollbar( + is_left_side_vertical_scrollbar_); + scrollbar->set_orientation(ScrollbarOrientationToProto(orientation_)); +} + +void SolidColorScrollbarLayer::FromLayerSpecificPropertiesProto( + const proto::LayerProperties& proto) { + Layer::FromLayerSpecificPropertiesProto(proto); + + const proto::SolidColorScrollbarLayerProperties& scrollbar = + proto.solid_scrollbar(); + scroll_layer_id_ = scrollbar.scroll_layer_id(); + thumb_thickness_ = scrollbar.thumb_thickness(); + track_start_ = scrollbar.track_start(); + is_left_side_vertical_scrollbar_ = + scrollbar.is_left_side_vertical_scrollbar(); + orientation_ = ScrollbarOrientationFromProto(scrollbar.orientation()); +} + } // namespace cc diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.h b/chromium/cc/layers/solid_color_scrollbar_layer.h index 1ed52ef7fee..57404ebb9b2 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer.h +++ b/chromium/cc/layers/solid_color_scrollbar_layer.h @@ -15,7 +15,7 @@ namespace cc { class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, public Layer { public: - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; static scoped_refptr<SolidColorScrollbarLayer> Create( ScrollbarOrientation orientation, @@ -26,6 +26,7 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, // Layer overrides. bool OpacityCanAnimateOnImplThread() const override; + bool AlwaysUseActiveTreeOpacity() const override; ScrollbarLayerInterface* ToScrollbarLayer() override; void PushPropertiesTo(LayerImpl* layer) override; @@ -46,7 +47,15 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, int scroll_layer_id); ~SolidColorScrollbarLayer() override; + // Layer overrides for proto conversions. + void SetTypeForProtoSerialization(proto::LayerNode* proto) const override; + void LayerSpecificPropertiesToProto(proto::LayerProperties* proto) override; + void FromLayerSpecificPropertiesProto( + const proto::LayerProperties& proto) override; + private: + friend class LayerSerializationTest; + int scroll_layer_id_; ScrollbarOrientation orientation_; int thumb_thickness_; diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc index 0b0a24e037f..40e47de4237 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc +++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "cc/layers/solid_color_scrollbar_layer_impl.h" + +#include "base/memory/ptr_util.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/layer_tree_settings.h" @@ -10,27 +12,22 @@ namespace cc { -scoped_ptr<SolidColorScrollbarLayerImpl> SolidColorScrollbarLayerImpl::Create( - LayerTreeImpl* tree_impl, - int id, - ScrollbarOrientation orientation, - int thumb_thickness, - int track_start, - bool is_left_side_vertical_scrollbar, - bool is_overlay) { - return make_scoped_ptr( - new SolidColorScrollbarLayerImpl(tree_impl, - id, - orientation, - thumb_thickness, - track_start, - is_left_side_vertical_scrollbar, - is_overlay)); +std::unique_ptr<SolidColorScrollbarLayerImpl> +SolidColorScrollbarLayerImpl::Create(LayerTreeImpl* tree_impl, + int id, + ScrollbarOrientation orientation, + int thumb_thickness, + int track_start, + bool is_left_side_vertical_scrollbar, + bool is_overlay) { + return base::WrapUnique(new SolidColorScrollbarLayerImpl( + tree_impl, id, orientation, thumb_thickness, track_start, + is_left_side_vertical_scrollbar, is_overlay)); } SolidColorScrollbarLayerImpl::~SolidColorScrollbarLayerImpl() {} -scoped_ptr<LayerImpl> SolidColorScrollbarLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> SolidColorScrollbarLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return SolidColorScrollbarLayerImpl::Create(tree_impl, id(), diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.h b/chromium/cc/layers/solid_color_scrollbar_layer_impl.h index 1cb03c76269..2ecba03fd86 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.h +++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.h @@ -12,7 +12,7 @@ namespace cc { class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { public: - static scoped_ptr<SolidColorScrollbarLayerImpl> Create( + static std::unique_ptr<SolidColorScrollbarLayerImpl> Create( LayerTreeImpl* tree_impl, int id, ScrollbarOrientation orientation, @@ -23,7 +23,7 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { ~SolidColorScrollbarLayerImpl() override; // LayerImpl overrides. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; void AppendQuads(RenderPass* render_pass, diff --git a/chromium/cc/layers/surface_layer.cc b/chromium/cc/layers/surface_layer.cc index f31a8aebcb1..8f0e0512af8 100644 --- a/chromium/cc/layers/surface_layer.cc +++ b/chromium/cc/layers/surface_layer.cc @@ -70,7 +70,8 @@ void SurfaceLayer::SetSurfaceId(SurfaceId surface_id, SetNeedsPushProperties(); } -scoped_ptr<LayerImpl> SurfaceLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { +std::unique_ptr<LayerImpl> SurfaceLayer::CreateLayerImpl( + LayerTreeImpl* tree_impl) { return SurfaceLayerImpl::Create(tree_impl, id()); } @@ -111,7 +112,7 @@ void SurfaceLayer::SatisfyDestroySequence() { if (!layer_tree_host()) return; DCHECK(!destroy_sequence_.is_null()); - scoped_ptr<SatisfySwapPromise> satisfy( + std::unique_ptr<SatisfySwapPromise> satisfy( new SatisfySwapPromise(destroy_sequence_, satisfy_callback_)); layer_tree_host()->QueueSwapPromise(std::move(satisfy)); destroy_sequence_ = SurfaceSequence(); diff --git a/chromium/cc/layers/surface_layer.h b/chromium/cc/layers/surface_layer.h index b4166d32e0f..583625fe92f 100644 --- a/chromium/cc/layers/surface_layer.h +++ b/chromium/cc/layers/surface_layer.h @@ -34,7 +34,7 @@ class CC_EXPORT SurfaceLayer : public Layer { void SetSurfaceId(SurfaceId surface_id, float scale, const gfx::Size& size); // Layer overrides. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void SetLayerTreeHost(LayerTreeHost* host) override; void PushPropertiesTo(LayerImpl* layer) override; diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc index a8a50f33fde..429d928de67 100644 --- a/chromium/cc/layers/surface_layer_impl.cc +++ b/chromium/cc/layers/surface_layer_impl.cc @@ -24,7 +24,7 @@ SurfaceLayerImpl::~SurfaceLayerImpl() { layer_tree_impl()->RemoveSurfaceLayer(this); } -scoped_ptr<LayerImpl> SurfaceLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> SurfaceLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return SurfaceLayerImpl::Create(tree_impl, id()); } diff --git a/chromium/cc/layers/surface_layer_impl.h b/chromium/cc/layers/surface_layer_impl.h index 819ee738e34..d67efd86055 100644 --- a/chromium/cc/layers/surface_layer_impl.h +++ b/chromium/cc/layers/surface_layer_impl.h @@ -5,8 +5,10 @@ #ifndef CC_LAYERS_SURFACE_LAYER_IMPL_H_ #define CC_LAYERS_SURFACE_LAYER_IMPL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" #include "cc/surfaces/surface_id.h" @@ -15,8 +17,9 @@ namespace cc { class CC_EXPORT SurfaceLayerImpl : public LayerImpl { public: - static scoped_ptr<SurfaceLayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr(new SurfaceLayerImpl(tree_impl, id)); + static std::unique_ptr<SurfaceLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new SurfaceLayerImpl(tree_impl, id)); } ~SurfaceLayerImpl() override; @@ -26,7 +29,7 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl { SurfaceId surface_id() const { return surface_id_; } // LayerImpl overrides. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; void AppendQuads(RenderPass* render_pass, AppendQuadsData* append_quads_data) override; diff --git a/chromium/cc/layers/surface_layer_unittest.cc b/chromium/cc/layers/surface_layer_unittest.cc index 0c15b5c35af..b7db7abd641 100644 --- a/chromium/cc/layers/surface_layer_unittest.cc +++ b/chromium/cc/layers/surface_layer_unittest.cc @@ -9,7 +9,7 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/surface_layer.h" #include "cc/test/fake_impl_task_runner_provider.h" @@ -48,7 +48,7 @@ class SurfaceLayerTest : public testing::Test { FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; void SatisfyCallback(SurfaceSequence* out, SurfaceSequence in) { @@ -77,7 +77,7 @@ TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) { layer_tree_host_->set_surface_id_namespace(1); layer_tree_host_->SetRootLayer(layer); - scoped_ptr<FakeLayerTreeHost> layer_tree_host2 = + std::unique_ptr<FakeLayerTreeHost> layer_tree_host2 = FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); scoped_refptr<SurfaceLayer> layer2(SurfaceLayer::Create( base::Bind(&SatisfyCallback, &blank_change), diff --git a/chromium/cc/layers/texture_layer.cc b/chromium/cc/layers/texture_layer.cc index a656955272b..b5b31732ac8 100644 --- a/chromium/cc/layers/texture_layer.cc +++ b/chromium/cc/layers/texture_layer.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/location.h" +#include "base/memory/ptr_util.h" #include "base/synchronization/lock.h" #include "base/trace_event/trace_event.h" #include "cc/base/simple_enclosed_region.h" @@ -52,7 +53,8 @@ void TextureLayer::ClearTexture() { SetTextureMailbox(TextureMailbox(), nullptr); } -scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { +std::unique_ptr<LayerImpl> TextureLayer::CreateLayerImpl( + LayerTreeImpl* tree_impl) { return TextureLayerImpl::Create(tree_impl, id()); } @@ -115,7 +117,7 @@ void TextureLayer::SetBlendBackgroundColor(bool blend) { void TextureLayer::SetTextureMailboxInternal( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback, + std::unique_ptr<SingleReleaseCallback> release_callback, bool requires_commit, bool allow_mailbox_reuse) { DCHECK(!mailbox.IsValid() || !holder_ref_ || @@ -145,7 +147,7 @@ void TextureLayer::SetTextureMailboxInternal( void TextureLayer::SetTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) { + std::unique_ptr<SingleReleaseCallback> release_callback) { bool requires_commit = true; bool allow_mailbox_reuse = false; SetTextureMailboxInternal(mailbox, std::move(release_callback), @@ -163,7 +165,7 @@ void TextureLayer::SetTextureMailboxWithoutReleaseCallback( DCHECK(!mailbox.IsValid() || !holder_ref_ || !mailbox.Equals(holder_ref_->holder()->mailbox()) || mailbox.sync_token() != holder_ref_->holder()->mailbox().sync_token()); - scoped_ptr<SingleReleaseCallback> release; + std::unique_ptr<SingleReleaseCallback> release; bool requires_commit = true; bool allow_mailbox_reuse = true; if (mailbox.IsValid()) @@ -202,7 +204,7 @@ bool TextureLayer::Update() { bool updated = Layer::Update(); if (client_) { TextureMailbox mailbox; - scoped_ptr<SingleReleaseCallback> release_callback; + std::unique_ptr<SingleReleaseCallback> release_callback; if (client_->PrepareTextureMailbox( &mailbox, &release_callback, @@ -236,7 +238,7 @@ void TextureLayer::PushPropertiesTo(LayerImpl* layer) { texture_layer->SetBlendBackgroundColor(blend_background_color_); if (needs_set_mailbox_) { TextureMailbox texture_mailbox; - scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl; + std::unique_ptr<SingleReleaseCallbackImpl> release_callback_impl; if (holder_ref_) { TextureMailboxHolder* holder = holder_ref_->holder(); texture_mailbox = holder->mailbox(); @@ -261,7 +263,7 @@ TextureLayer::TextureMailboxHolder::MainThreadReference:: TextureLayer::TextureMailboxHolder::TextureMailboxHolder( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) + std::unique_ptr<SingleReleaseCallback> release_callback) : internal_references_(0), mailbox_(mailbox), release_callback_(std::move(release_callback)), @@ -272,11 +274,11 @@ TextureLayer::TextureMailboxHolder::~TextureMailboxHolder() { DCHECK_EQ(0u, internal_references_); } -scoped_ptr<TextureLayer::TextureMailboxHolder::MainThreadReference> +std::unique_ptr<TextureLayer::TextureMailboxHolder::MainThreadReference> TextureLayer::TextureMailboxHolder::Create( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) { - return make_scoped_ptr(new MainThreadReference( + std::unique_ptr<SingleReleaseCallback> release_callback) { + return base::WrapUnique(new MainThreadReference( new TextureMailboxHolder(mailbox, std::move(release_callback)))); } @@ -288,7 +290,7 @@ void TextureLayer::TextureMailboxHolder::Return( is_lost_ = is_lost; } -scoped_ptr<SingleReleaseCallbackImpl> +std::unique_ptr<SingleReleaseCallbackImpl> TextureLayer::TextureMailboxHolder::GetCallbackForImplThread() { // We can't call GetCallbackForImplThread if we released the main thread // reference. diff --git a/chromium/cc/layers/texture_layer.h b/chromium/cc/layers/texture_layer.h index 3601b23732a..4fa239f83af 100644 --- a/chromium/cc/layers/texture_layer.h +++ b/chromium/cc/layers/texture_layer.h @@ -47,15 +47,15 @@ class CC_EXPORT TextureLayer : public Layer { // Gets a ReleaseCallback that can be called from another thread. Note: the // caller must ensure the callback is called. - scoped_ptr<SingleReleaseCallbackImpl> GetCallbackForImplThread(); + std::unique_ptr<SingleReleaseCallbackImpl> GetCallbackForImplThread(); protected: friend class TextureLayer; // Protected visiblity so only TextureLayer and unit tests can create these. - static scoped_ptr<MainThreadReference> Create( + static std::unique_ptr<MainThreadReference> Create( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback); + std::unique_ptr<SingleReleaseCallback> release_callback); virtual ~TextureMailboxHolder(); private: @@ -63,7 +63,7 @@ class CC_EXPORT TextureLayer : public Layer { friend class MainThreadReference; explicit TextureMailboxHolder( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback); + std::unique_ptr<SingleReleaseCallback> release_callback); void InternalAddRef(); void InternalRelease(); @@ -76,7 +76,7 @@ class CC_EXPORT TextureLayer : public Layer { // during commit where the main thread is blocked. unsigned internal_references_; TextureMailbox mailbox_; - scoped_ptr<SingleReleaseCallback> release_callback_; + std::unique_ptr<SingleReleaseCallback> release_callback_; // This lock guards the sync_token_ and is_lost_ fields because they can be // accessed on both the impl and main thread. We do this to ensure that the @@ -99,7 +99,7 @@ class CC_EXPORT TextureLayer : public Layer { // Resets the texture. void ClearTexture(); - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; // Sets whether this texture should be Y-flipped at draw time. Defaults to // true. @@ -129,8 +129,9 @@ class CC_EXPORT TextureLayer : public Layer { void SetBlendBackgroundColor(bool blend); // Code path for plugins which supply their own mailbox. - void SetTextureMailbox(const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback); + void SetTextureMailbox( + const TextureMailbox& mailbox, + std::unique_ptr<SingleReleaseCallback> release_callback); // Use this for special cases where the same texture is used to back the // TextureLayer across all frames. @@ -152,7 +153,7 @@ class CC_EXPORT TextureLayer : public Layer { private: void SetTextureMailboxInternal( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback, + std::unique_ptr<SingleReleaseCallback> release_callback, bool requires_commit, bool allow_mailbox_reuse); @@ -167,7 +168,7 @@ class CC_EXPORT TextureLayer : public Layer { bool premultiplied_alpha_; bool blend_background_color_; - scoped_ptr<TextureMailboxHolder::MainThreadReference> holder_ref_; + std::unique_ptr<TextureMailboxHolder::MainThreadReference> holder_ref_; bool needs_set_mailbox_; DISALLOW_COPY_AND_ASSIGN(TextureLayer); diff --git a/chromium/cc/layers/texture_layer_client.h b/chromium/cc/layers/texture_layer_client.h index 0b8b2256fd8..46b7efc2c9d 100644 --- a/chromium/cc/layers/texture_layer_client.h +++ b/chromium/cc/layers/texture_layer_client.h @@ -18,7 +18,7 @@ class TextureLayerClient { // and the old mailbox is to be reused. virtual bool PrepareTextureMailbox( TextureMailbox* mailbox, - scoped_ptr<SingleReleaseCallback>* release_callback, + std::unique_ptr<SingleReleaseCallback>* release_callback, bool use_shared_memory) = 0; protected: diff --git a/chromium/cc/layers/texture_layer_impl.cc b/chromium/cc/layers/texture_layer_impl.cc index 27d3c971f64..200dad4a261 100644 --- a/chromium/cc/layers/texture_layer_impl.cc +++ b/chromium/cc/layers/texture_layer_impl.cc @@ -43,7 +43,7 @@ TextureLayerImpl::~TextureLayerImpl() { FreeTextureMailbox(); } void TextureLayerImpl::SetTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallbackImpl> release_callback) { + std::unique_ptr<SingleReleaseCallbackImpl> release_callback) { DCHECK_EQ(mailbox.IsValid(), !!release_callback); FreeTextureMailbox(); texture_mailbox_ = mailbox; @@ -53,7 +53,7 @@ void TextureLayerImpl::SetTextureMailbox( SetNeedsPushProperties(); } -scoped_ptr<LayerImpl> TextureLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> TextureLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return TextureLayerImpl::Create(tree_impl, id()); } @@ -165,25 +165,22 @@ void TextureLayerImpl::AppendQuads(RenderPass* render_pass, if (visible_quad_rect.IsEmpty()) return; - if (!texture_mailbox_.secure_output_only() || - (layer_tree_impl()->OutputIsSecure() && !InsideCopyRequest())) { - TextureDrawQuad* quad = - render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); - ResourceId id = - valid_texture_copy_ ? texture_copy_->id() : external_texture_resource_; - quad->SetNew(shared_quad_state, quad_rect, opaque_rect, visible_quad_rect, - id, premultiplied_alpha_, uv_top_left_, uv_bottom_right_, - bg_color, vertex_opacity_, flipped_, nearest_neighbor_); - if (!valid_texture_copy_) { - quad->set_resource_size_in_pixels(texture_mailbox_.size_in_pixels()); - } - ValidateQuadResources(quad); - } else { - SolidColorDrawQuad* quad = - render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); - quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, SK_ColorBLACK, - false); + if (!vertex_opacity_[0] && !vertex_opacity_[1] && !vertex_opacity_[2] && + !vertex_opacity_[3]) + return; + + TextureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); + ResourceId id = + valid_texture_copy_ ? texture_copy_->id() : external_texture_resource_; + quad->SetNew(shared_quad_state, quad_rect, opaque_rect, visible_quad_rect, id, + premultiplied_alpha_, uv_top_left_, uv_bottom_right_, bg_color, + vertex_opacity_, flipped_, nearest_neighbor_, + texture_mailbox_.secure_output_only()); + if (!valid_texture_copy_) { + quad->set_resource_size_in_pixels(texture_mailbox_.size_in_pixels()); } + ValidateQuadResources(quad); } SimpleEnclosedRegion TextureLayerImpl::VisibleOpaqueRegion() const { diff --git a/chromium/cc/layers/texture_layer_impl.h b/chromium/cc/layers/texture_layer_impl.h index e799eff5a2d..233c14e1f6a 100644 --- a/chromium/cc/layers/texture_layer_impl.h +++ b/chromium/cc/layers/texture_layer_impl.h @@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" @@ -18,12 +19,13 @@ class ScopedResource; class CC_EXPORT TextureLayerImpl : public LayerImpl { public: - static scoped_ptr<TextureLayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr(new TextureLayerImpl(tree_impl, id)); + static std::unique_ptr<TextureLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new TextureLayerImpl(tree_impl, id)); } ~TextureLayerImpl() override; - scoped_ptr<LayerImpl> CreateLayerImpl( + std::unique_ptr<LayerImpl> CreateLayerImpl( LayerTreeImpl* layer_tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; @@ -52,7 +54,7 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { void SetTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallbackImpl> release_callback); + std::unique_ptr<SingleReleaseCallbackImpl> release_callback); private: TextureLayerImpl(LayerTreeImpl* tree_impl, int id); @@ -69,10 +71,10 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { gfx::PointF uv_bottom_right_; float vertex_opacity_[4]; // This is a resource that's a GL copy of a software texture mailbox. - scoped_ptr<ScopedResource> texture_copy_; + std::unique_ptr<ScopedResource> texture_copy_; TextureMailbox texture_mailbox_; - scoped_ptr<SingleReleaseCallbackImpl> release_callback_; + std::unique_ptr<SingleReleaseCallbackImpl> release_callback_; bool own_mailbox_; bool valid_texture_copy_; diff --git a/chromium/cc/layers/texture_layer_impl_unittest.cc b/chromium/cc/layers/texture_layer_impl_unittest.cc index 997a5c07356..4665691931f 100644 --- a/chromium/cc/layers/texture_layer_impl_unittest.cc +++ b/chromium/cc/layers/texture_layer_impl_unittest.cc @@ -9,6 +9,7 @@ #include "cc/output/context_provider.h" #include "cc/output/output_surface.h" #include "cc/quads/draw_quad.h" +#include "cc/quads/texture_draw_quad.h" #include "cc/test/layer_test_common.h" #include "testing/gtest/include/gtest/gtest.h" @@ -116,7 +117,7 @@ TEST(TextureLayerImplTest, OutputIsSecure) { mailbox, gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, 0x123, gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456), - GL_TEXTURE_2D, layer_size, false, true); + GL_TEXTURE_2D, layer_size, gfx::GpuMemoryBufferId(), false, true); TextureLayerImpl* texture_layer_impl = impl.AddChildToRoot<TextureLayerImpl>(); @@ -133,29 +134,11 @@ TEST(TextureLayerImplTest, OutputIsSecure) { impl.AppendQuadsWithOcclusion(texture_layer_impl, occluded); EXPECT_EQ(1u, impl.quad_list().size()); - EXPECT_EQ(DrawQuad::Material::SOLID_COLOR, - impl.quad_list().front()->material); - } - - { - impl.SetOutputIsSecure(true); - gfx::Rect occluded; - impl.AppendQuadsWithOcclusion(texture_layer_impl, occluded); - - EXPECT_EQ(1u, impl.quad_list().size()); - EXPECT_NE(DrawQuad::Material::SOLID_COLOR, - impl.quad_list().front()->material); - } - - { - impl.SetOutputIsSecure(false); - impl.RequestCopyOfOutput(); - gfx::Rect occluded; - impl.AppendQuadsWithOcclusion(texture_layer_impl, occluded); - - EXPECT_EQ(1u, impl.quad_list().size()); - EXPECT_EQ(DrawQuad::Material::SOLID_COLOR, + ASSERT_EQ(DrawQuad::Material::TEXTURE_CONTENT, impl.quad_list().front()->material); + const TextureDrawQuad* quad = + TextureDrawQuad::MaterialCast(impl.quad_list().front()); + EXPECT_TRUE(quad->secure_output_only); } } diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc index b02dd52c0bc..d8df840c0f2 100644 --- a/chromium/cc/layers/texture_layer_unittest.cc +++ b/chromium/cc/layers/texture_layer_unittest.cc @@ -14,11 +14,12 @@ #include "base/callback.h" #include "base/location.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" -#include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/texture_layer_client.h" @@ -64,7 +65,7 @@ gpu::SyncToken SyncTokenFromUInt(uint32_t value) { class MockLayerTreeHost : public LayerTreeHost { public: - static scoped_ptr<MockLayerTreeHost> Create( + static std::unique_ptr<MockLayerTreeHost> Create( FakeLayerTreeHostClient* client, TaskGraphRunner* task_graph_runner) { LayerTreeHost::InitParams params; @@ -72,7 +73,7 @@ class MockLayerTreeHost : public LayerTreeHost { params.task_graph_runner = task_graph_runner; LayerTreeSettings settings; params.settings = &settings; - return make_scoped_ptr(new MockLayerTreeHost(client, ¶ms)); + return base::WrapUnique(new MockLayerTreeHost(client, ¶ms)); } MOCK_METHOD0(SetNeedsCommit, void()); @@ -95,7 +96,7 @@ class FakeTextureLayerClient : public TextureLayerClient { bool PrepareTextureMailbox( TextureMailbox* mailbox, - scoped_ptr<SingleReleaseCallback>* release_callback, + std::unique_ptr<SingleReleaseCallback>* release_callback, bool use_shared_memory) override { if (!mailbox_changed_) return false; @@ -107,7 +108,7 @@ class FakeTextureLayerClient : public TextureLayerClient { } void set_mailbox(const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) { + std::unique_ptr<SingleReleaseCallback> release_callback) { mailbox_ = mailbox; release_callback_ = std::move(release_callback); mailbox_changed_ = true; @@ -115,7 +116,7 @@ class FakeTextureLayerClient : public TextureLayerClient { private: TextureMailbox mailbox_; - scoped_ptr<SingleReleaseCallback> release_callback_; + std::unique_ptr<SingleReleaseCallback> release_callback_; bool mailbox_changed_; DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient); }; @@ -196,7 +197,7 @@ struct CommonMailboxObjects { TextureMailbox mailbox3_; gpu::SyncToken sync_token1_; gpu::SyncToken sync_token2_; - scoped_ptr<SharedBitmap> shared_bitmap_; + std::unique_ptr<SharedBitmap> shared_bitmap_; }; class TextureLayerTest : public testing::Test { @@ -227,12 +228,12 @@ class TextureLayerTest : public testing::Test { layer_tree_host_ = nullptr; } - scoped_ptr<MockLayerTreeHost> layer_tree_host_; + std::unique_ptr<MockLayerTreeHost> layer_tree_host_; FakeImplTaskRunnerProvider task_runner_provider_; FakeLayerTreeHostClient fake_client_; TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<OutputSurface> output_surface_; + std::unique_ptr<OutputSurface> output_surface_; FakeLayerTreeHostImpl host_impl_; CommonMailboxObjects test_data_; }; @@ -387,7 +388,7 @@ class TextureLayerMailboxHolderTest : public TextureLayerTest { void ReleaseMainRef() { main_ref_ = nullptr; } - void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) { + void CreateImplRef(std::unique_ptr<SingleReleaseCallbackImpl>* impl_ref) { *impl_ref = main_ref_->holder()->GetCallbackForImplThread(); } @@ -407,10 +408,9 @@ class TextureLayerMailboxHolderTest : public TextureLayerTest { BlockingTaskRunner::Create(main_thread_.task_runner()); } - scoped_ptr<TestMailboxHolder::MainThreadReference> - main_ref_; + std::unique_ptr<TestMailboxHolder::MainThreadReference> main_ref_; base::Thread main_thread_; - scoped_ptr<BlockingTaskRunner> main_thread_task_runner_; + std::unique_ptr<BlockingTaskRunner> main_thread_task_runner_; }; TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) { @@ -426,14 +426,14 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor1; + std::unique_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor1)); // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor2; + std::unique_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor2)); @@ -479,14 +479,14 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor1; + std::unique_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor1)); // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor2; + std::unique_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor2)); @@ -533,14 +533,14 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor1; + std::unique_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor1)); // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor2; + std::unique_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor2)); @@ -587,14 +587,14 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor1; + std::unique_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor1)); // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallbackImpl> compositor2; + std::unique_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->task_runner()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, base::Unretained(this), &compositor2)); @@ -664,8 +664,8 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { void SetMailbox(char mailbox_char) { EXPECT_EQ(true, main_thread_.CalledOnValidThread()); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind( + std::unique_ptr<SingleReleaseCallback> callback = + SingleReleaseCallback::Create(base::Bind( &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback, base::Unretained(this))); layer_->SetTextureMailbox( @@ -786,9 +786,10 @@ class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest { void SetMailbox(char mailbox_char) { const gpu::SyncToken sync_token = SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(&TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback, - sync_token)); + std::unique_ptr<SingleReleaseCallback> callback = + SingleReleaseCallback::Create(base::Bind( + &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback, + sync_token)); layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char), sync_token, GL_TEXTURE_2D), std::move(callback)); @@ -898,7 +899,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { .Times(AnyNumber()); // Hardware mode. { - scoped_ptr<TextureLayerImpl> impl_layer = + std::unique_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox1_, @@ -907,7 +908,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { } { - scoped_ptr<TextureLayerImpl> impl_layer = + std::unique_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox(TextureMailbox(), nullptr); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); @@ -915,7 +916,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { { // Software resource. - scoped_ptr<TextureLayerImpl> impl_layer = + std::unique_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox3_, @@ -925,7 +926,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { // Software mode. { - scoped_ptr<TextureLayerImpl> impl_layer = + std::unique_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox1_, @@ -934,7 +935,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { } { - scoped_ptr<TextureLayerImpl> impl_layer = + std::unique_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox(TextureMailbox(), nullptr); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); @@ -942,7 +943,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { { // Software resource. - scoped_ptr<TextureLayerImpl> impl_layer = + std::unique_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox3_, @@ -952,7 +953,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { // Resourceless software mode. { - scoped_ptr<TextureLayerImpl> impl_layer = + std::unique_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox1_, @@ -963,11 +964,11 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { host_impl_.CreatePendingTree(); - scoped_ptr<TextureLayerImpl> pending_layer; + std::unique_ptr<TextureLayerImpl> pending_layer; pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1); ASSERT_TRUE(pending_layer); - scoped_ptr<LayerImpl> active_layer( + std::unique_ptr<LayerImpl> active_layer( pending_layer->CreateLayerImpl(host_impl_.active_tree())); ASSERT_TRUE(active_layer); @@ -1021,7 +1022,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { TEST_F(TextureLayerImplWithMailboxTest, TestDestructorCallbackOnCreatedResource) { - scoped_ptr<TextureLayerImpl> impl_layer; + std::unique_ptr<TextureLayerImpl> impl_layer; impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); ASSERT_TRUE(impl_layer); @@ -1069,7 +1070,7 @@ class TextureLayerNoExtraCommitForMailboxTest // TextureLayerClient implementation. bool PrepareTextureMailbox( TextureMailbox* texture_mailbox, - scoped_ptr<SingleReleaseCallback>* release_callback, + std::unique_ptr<SingleReleaseCallback>* release_callback, bool use_shared_memory) override { if (layer_tree_host()->source_frame_number() == 1) { // Once this has been committed, the mailbox will be released. @@ -1168,7 +1169,7 @@ class TextureLayerChangeInvisibleMailboxTest // TextureLayerClient implementation. bool PrepareTextureMailbox( TextureMailbox* mailbox, - scoped_ptr<SingleReleaseCallback>* release_callback, + std::unique_ptr<SingleReleaseCallback>* release_callback, bool use_shared_memory) override { ++prepare_called_; if (!mailbox_changed_) @@ -1243,7 +1244,7 @@ class TextureLayerChangeInvisibleMailboxTest // So the old mailbox isn't returned yet. EXPECT_EQ(0, mailbox_returned_); // Make layer visible again. - parent_layer_->SetOpacity(1.f); + parent_layer_->SetOpacity(0.9f); break; case 4: // Layer should have been updated. @@ -1305,7 +1306,7 @@ class TextureLayerReleaseResourcesBase // TextureLayerClient implementation. bool PrepareTextureMailbox( TextureMailbox* mailbox, - scoped_ptr<SingleReleaseCallback>* release_callback, + std::unique_ptr<SingleReleaseCallback>* release_callback, bool use_shared_memory) override { *mailbox = TextureMailbox(MailboxFromChar('1'), SyncTokenFromUInt(1), GL_TEXTURE_2D); @@ -1328,6 +1329,7 @@ class TextureLayerReleaseResourcesBase texture_layer->SetIsDrawable(true); layer_tree_host()->root_layer()->AddChild(texture_layer); + texture_layer_id_ = texture_layer->id(); } void BeginTest() override { @@ -1339,6 +1341,9 @@ class TextureLayerReleaseResourcesBase void AfterTest() override { EXPECT_TRUE(mailbox_released_); } + protected: + int texture_layer_id_; + private: bool mailbox_released_; }; @@ -1349,7 +1354,7 @@ class TextureLayerReleaseResourcesAfterCommit void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { LayerTreeImpl* tree = nullptr; tree = host_impl->sync_tree(); - tree->root_layer()->children()[0]->ReleaseResources(); + tree->LayerById(texture_layer_id_)->ReleaseResources(); } }; @@ -1359,7 +1364,7 @@ class TextureLayerReleaseResourcesAfterActivate : public TextureLayerReleaseResourcesBase { public: void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources(); + host_impl->active_tree()->LayerById(texture_layer_id_)->ReleaseResources(); } }; @@ -1376,8 +1381,8 @@ class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest { void SetMailbox(char mailbox_char) { EXPECT_EQ(true, main_thread_.CalledOnValidThread()); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind( + std::unique_ptr<SingleReleaseCallback> callback = + SingleReleaseCallback::Create(base::Bind( &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback, base::Unretained(this))); layer_->SetTextureMailbox( @@ -1447,8 +1452,8 @@ class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest { void SetMailbox(char mailbox_char) { EXPECT_EQ(true, main_thread_.CalledOnValidThread()); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind( + std::unique_ptr<SingleReleaseCallback> callback = + SingleReleaseCallback::Create(base::Bind( &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback, base::Unretained(this))); layer_->SetTextureMailbox( diff --git a/chromium/cc/layers/ui_resource_layer.cc b/chromium/cc/layers/ui_resource_layer.cc index 68428519129..de86098ad71 100644 --- a/chromium/cc/layers/ui_resource_layer.cc +++ b/chromium/cc/layers/ui_resource_layer.cc @@ -4,6 +4,7 @@ #include "cc/layers/ui_resource_layer.h" +#include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "cc/layers/ui_resource_layer_impl.h" #include "cc/resources/scoped_ui_resource.h" @@ -17,9 +18,10 @@ namespace { class ScopedUIResourceHolder : public UIResourceLayer::UIResourceHolder { public: - static scoped_ptr<ScopedUIResourceHolder> Create(LayerTreeHost* host, - const SkBitmap& skbitmap) { - return make_scoped_ptr(new ScopedUIResourceHolder(host, skbitmap)); + static std::unique_ptr<ScopedUIResourceHolder> Create( + LayerTreeHost* host, + const SkBitmap& skbitmap) { + return base::WrapUnique(new ScopedUIResourceHolder(host, skbitmap)); } UIResourceId id() override { return resource_->id(); } @@ -28,13 +30,13 @@ class ScopedUIResourceHolder : public UIResourceLayer::UIResourceHolder { resource_ = ScopedUIResource::Create(host, UIResourceBitmap(skbitmap)); } - scoped_ptr<ScopedUIResource> resource_; + std::unique_ptr<ScopedUIResource> resource_; }; class SharedUIResourceHolder : public UIResourceLayer::UIResourceHolder { public: - static scoped_ptr<SharedUIResourceHolder> Create(UIResourceId id) { - return make_scoped_ptr(new SharedUIResourceHolder(id)); + static std::unique_ptr<SharedUIResourceHolder> Create(UIResourceId id) { + return base::WrapUnique(new SharedUIResourceHolder(id)); } UIResourceId id() override { return id_; } @@ -63,7 +65,7 @@ UIResourceLayer::UIResourceLayer() UIResourceLayer::~UIResourceLayer() {} -scoped_ptr<LayerImpl> UIResourceLayer::CreateLayerImpl( +std::unique_ptr<LayerImpl> UIResourceLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return UIResourceLayerImpl::Create(tree_impl, id()); } diff --git a/chromium/cc/layers/ui_resource_layer.h b/chromium/cc/layers/ui_resource_layer.h index 794a86c88aa..8004d1e51a0 100644 --- a/chromium/cc/layers/ui_resource_layer.h +++ b/chromium/cc/layers/ui_resource_layer.h @@ -5,8 +5,9 @@ #ifndef CC_LAYERS_UI_RESOURCE_LAYER_H_ #define CC_LAYERS_UI_RESOURCE_LAYER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/layers/layer.h" #include "cc/resources/ui_resource_client.h" @@ -54,7 +55,7 @@ class CC_EXPORT UIResourceLayer : public Layer { bool HasDrawableContent() const override; - scoped_ptr<UIResourceHolder> ui_resource_holder_; + std::unique_ptr<UIResourceHolder> ui_resource_holder_; SkBitmap bitmap_; gfx::PointF uv_top_left_; @@ -62,7 +63,7 @@ class CC_EXPORT UIResourceLayer : public Layer { float vertex_opacity_[4]; private: - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void RecreateUIResourceHolder(); DISALLOW_COPY_AND_ASSIGN(UIResourceLayer); diff --git a/chromium/cc/layers/ui_resource_layer_impl.cc b/chromium/cc/layers/ui_resource_layer_impl.cc index 9fb703ef6fe..5e3768df806 100644 --- a/chromium/cc/layers/ui_resource_layer_impl.cc +++ b/chromium/cc/layers/ui_resource_layer_impl.cc @@ -27,7 +27,7 @@ UIResourceLayerImpl::UIResourceLayerImpl(LayerTreeImpl* tree_impl, int id) UIResourceLayerImpl::~UIResourceLayerImpl() {} -scoped_ptr<LayerImpl> UIResourceLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> UIResourceLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { return UIResourceLayerImpl::Create(tree_impl, id()); } @@ -129,18 +129,10 @@ void UIResourceLayerImpl::AppendQuads( TextureDrawQuad* quad = render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); - quad->SetNew(shared_quad_state, - quad_rect, - opaque_rect, - visible_quad_rect, - resource, - premultiplied_alpha, - uv_top_left_, - uv_bottom_right_, - SK_ColorTRANSPARENT, - vertex_opacity_, - flipped, - nearest_neighbor); + quad->SetNew(shared_quad_state, quad_rect, opaque_rect, visible_quad_rect, + resource, premultiplied_alpha, uv_top_left_, uv_bottom_right_, + SK_ColorTRANSPARENT, vertex_opacity_, flipped, nearest_neighbor, + false); ValidateQuadResources(quad); } diff --git a/chromium/cc/layers/ui_resource_layer_impl.h b/chromium/cc/layers/ui_resource_layer_impl.h index 05293e67778..129c5cd2cce 100644 --- a/chromium/cc/layers/ui_resource_layer_impl.h +++ b/chromium/cc/layers/ui_resource_layer_impl.h @@ -8,6 +8,7 @@ #include <string> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" #include "cc/resources/resource_provider.h" @@ -23,9 +24,9 @@ namespace cc { class CC_EXPORT UIResourceLayerImpl : public LayerImpl { public: - static scoped_ptr<UIResourceLayerImpl> Create(LayerTreeImpl* tree_impl, - int id) { - return make_scoped_ptr(new UIResourceLayerImpl(tree_impl, id)); + static std::unique_ptr<UIResourceLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new UIResourceLayerImpl(tree_impl, id)); } ~UIResourceLayerImpl() override; @@ -40,7 +41,7 @@ class CC_EXPORT UIResourceLayerImpl : public LayerImpl { // opacity value. void SetVertexOpacity(const float vertex_opacity[4]); - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; bool WillDraw(DrawMode draw_mode, diff --git a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc index 92419452c37..b86fadaca2f 100644 --- a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc +++ b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc @@ -24,19 +24,18 @@ namespace cc { namespace { -scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer( +std::unique_ptr<UIResourceLayerImpl> GenerateUIResourceLayer( FakeUIResourceLayerTreeHostImpl* host_impl, const gfx::Size& bitmap_size, const gfx::Size& layer_size, bool opaque, UIResourceId uid) { gfx::Rect visible_layer_rect(layer_size); - scoped_ptr<UIResourceLayerImpl> layer = + std::unique_ptr<UIResourceLayerImpl> layer = UIResourceLayerImpl::Create(host_impl->active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->SetForceRenderSurface(true); - layer->draw_properties().render_target = layer.get(); + layer->test_properties()->force_render_surface = true; UIResourceBitmap bitmap(bitmap_size, opaque); @@ -46,9 +45,9 @@ scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer( return layer; } -void QuadSizeTest(scoped_ptr<UIResourceLayerImpl> layer, +void QuadSizeTest(std::unique_ptr<UIResourceLayerImpl> layer, size_t expected_quad_size) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; layer->AppendQuads(render_pass.get(), &data); @@ -62,7 +61,7 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeUIResourceLayerTreeHostImpl host_impl( &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); @@ -74,11 +73,8 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) { size_t expected_quad_size = 1; bool opaque = true; UIResourceId uid = 1; - scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl, - bitmap_size, - layer_size, - opaque, - uid); + std::unique_ptr<UIResourceLayerImpl> layer = + GenerateUIResourceLayer(&host_impl, bitmap_size, layer_size, opaque, uid); QuadSizeTest(std::move(layer), expected_quad_size); // Make sure we're not appending quads when there are invalid values. @@ -92,9 +88,9 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) { QuadSizeTest(std::move(layer), expected_quad_size); } -void OpaqueBoundsTest(scoped_ptr<UIResourceLayerImpl> layer, - const gfx::Rect& expected_opaque_bounds) { - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); +void OpaqueBoundsTest(std::unique_ptr<UIResourceLayerImpl> layer, + const gfx::Rect& expected_opaque_bounds) { + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; layer->AppendQuads(render_pass.get(), &data); @@ -110,7 +106,7 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeUIResourceLayerTreeHostImpl host_impl( &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); @@ -120,11 +116,8 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) { gfx::Size layer_size(100, 100); bool opaque = false; UIResourceId uid = 1; - scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl, - bitmap_size, - layer_size, - opaque, - uid); + std::unique_ptr<UIResourceLayerImpl> layer = + GenerateUIResourceLayer(&host_impl, bitmap_size, layer_size, opaque, uid); gfx::Rect expected_opaque_bounds; OpaqueBoundsTest(std::move(layer), expected_opaque_bounds); @@ -142,7 +135,7 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeUIResourceLayerTreeHostImpl host_impl( &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.SetVisible(true); @@ -152,7 +145,7 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) { gfx::Size layer_size(100, 100); bool skbitmap_opaque = false; UIResourceId uid = 1; - scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer( + std::unique_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer( &host_impl, bitmap_size, layer_size, skbitmap_opaque, uid); layer->SetContentsOpaque(false); gfx::Rect expected_opaque_bounds; diff --git a/chromium/cc/layers/ui_resource_layer_unittest.cc b/chromium/cc/layers/ui_resource_layer_unittest.cc index 94efef486f5..7163828d609 100644 --- a/chromium/cc/layers/ui_resource_layer_unittest.cc +++ b/chromium/cc/layers/ui_resource_layer_unittest.cc @@ -4,7 +4,7 @@ #include "cc/layers/ui_resource_layer.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_ui_resource.h" #include "cc/test/fake_layer_tree_host.h" @@ -62,7 +62,7 @@ class UIResourceLayerTest : public testing::Test { FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; TEST_F(UIResourceLayerTest, SetBitmap) { @@ -104,7 +104,7 @@ TEST_F(UIResourceLayerTest, SetUIResourceId) { EXPECT_FALSE(test_layer->DrawsContent()); bool is_opaque = false; - scoped_ptr<ScopedUIResource> resource = ScopedUIResource::Create( + std::unique_ptr<ScopedUIResource> resource = ScopedUIResource::Create( layer_tree_host_.get(), UIResourceBitmap(gfx::Size(10, 10), is_opaque)); test_layer->SetUIResourceId(resource->id()); test_layer->Update(); @@ -113,7 +113,7 @@ TEST_F(UIResourceLayerTest, SetUIResourceId) { // ID is preserved even when you set ID first and attach it to the tree. layer_tree_host_->SetRootLayer(nullptr); - scoped_ptr<ScopedUIResource> shared_resource = ScopedUIResource::Create( + std::unique_ptr<ScopedUIResource> shared_resource = ScopedUIResource::Create( layer_tree_host_.get(), UIResourceBitmap(gfx::Size(5, 5), is_opaque)); test_layer->SetUIResourceId(shared_resource->id()); layer_tree_host_->SetRootLayer(test_layer); diff --git a/chromium/cc/layers/video_frame_provider.h b/chromium/cc/layers/video_frame_provider.h index e7619a3fb7a..a6789c11166 100644 --- a/chromium/cc/layers/video_frame_provider.h +++ b/chromium/cc/layers/video_frame_provider.h @@ -43,8 +43,6 @@ class CC_EXPORT VideoFrameProvider { virtual void StopRendering() = 0; // Notifies the client that GetCurrentFrame() will return new data. - // TODO(dalecurtis): Nuke this once VideoFrameProviderClientImpl is using a - // BeginFrameObserver based approach. http://crbug.com/336733 virtual void DidReceiveFrame() = 0; protected: @@ -75,9 +73,6 @@ class CC_EXPORT VideoFrameProvider { // // Clients should call this in response to UpdateCurrentFrame() returning true // or in response to a DidReceiveFrame() call. - // - // TODO(dalecurtis): Remove text about DidReceiveFrame() once the old path - // has been removed. http://crbug.com/439548 virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() = 0; // Called in response to DidReceiveFrame() or a return value of true from diff --git a/chromium/cc/layers/video_frame_provider_client_impl.cc b/chromium/cc/layers/video_frame_provider_client_impl.cc index 5e9fd332b39..6f9cb8f00c4 100644 --- a/chromium/cc/layers/video_frame_provider_client_impl.cc +++ b/chromium/cc/layers/video_frame_provider_client_impl.cc @@ -27,11 +27,14 @@ VideoFrameProviderClientImpl::VideoFrameProviderClientImpl( stopped_(false), rendering_(false), needs_put_current_frame_(false) { - // This only happens during a commit on the compositor thread while the main - // thread is blocked. That makes this a thread-safe call to set the video - // frame provider client that does not require a lock. The same is true of - // the call to Stop(). - provider_->SetVideoFrameProviderClient(this); + // |provider_| may be null if destructed before the layer. + if (provider_) { + // This only happens during a commit on the compositor thread while the main + // thread is blocked. That makes this a thread-safe call to set the video + // frame provider client that does not require a lock. The same is true of + // the call to Stop(). + provider_->SetVideoFrameProviderClient(this); + } // This matrix is the default transformation for stream textures, and flips // on the Y axis. diff --git a/chromium/cc/layers/video_layer.cc b/chromium/cc/layers/video_layer.cc index b55d82acfcc..fe4f2eda268 100644 --- a/chromium/cc/layers/video_layer.cc +++ b/chromium/cc/layers/video_layer.cc @@ -22,7 +22,8 @@ VideoLayer::VideoLayer(VideoFrameProvider* provider, VideoLayer::~VideoLayer() {} -scoped_ptr<LayerImpl> VideoLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { +std::unique_ptr<LayerImpl> VideoLayer::CreateLayerImpl( + LayerTreeImpl* tree_impl) { return VideoLayerImpl::Create(tree_impl, id(), provider_, video_rotation_); } @@ -39,4 +40,8 @@ bool VideoLayer::Update() { return updated; } +void VideoLayer::StopUsingProvider() { + provider_ = nullptr; +} + } // namespace cc diff --git a/chromium/cc/layers/video_layer.h b/chromium/cc/layers/video_layer.h index 4828468ece6..9bd75655cb8 100644 --- a/chromium/cc/layers/video_layer.h +++ b/chromium/cc/layers/video_layer.h @@ -24,10 +24,13 @@ class CC_EXPORT VideoLayer : public Layer { static scoped_refptr<VideoLayer> Create(VideoFrameProvider* provider, media::VideoRotation video_rotation); - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; bool Update() override; + // Clears |provider_| to ensure it is not used after destruction. + void StopUsingProvider(); + private: VideoLayer(VideoFrameProvider* provider, media::VideoRotation video_rotation); ~VideoLayer() override; diff --git a/chromium/cc/layers/video_layer_impl.cc b/chromium/cc/layers/video_layer_impl.cc index f22860c746c..299c446ff60 100644 --- a/chromium/cc/layers/video_layer_impl.cc +++ b/chromium/cc/layers/video_layer_impl.cc @@ -8,8 +8,8 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "cc/layers/video_frame_provider_client_impl.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/stream_video_draw_quad.h" #include "cc/quads/texture_draw_quad.h" #include "cc/quads/yuv_video_draw_quad.h" @@ -27,7 +27,7 @@ namespace cc { // static -scoped_ptr<VideoLayerImpl> VideoLayerImpl::Create( +std::unique_ptr<VideoLayerImpl> VideoLayerImpl::Create( LayerTreeImpl* tree_impl, int id, VideoFrameProvider* provider, @@ -39,7 +39,7 @@ scoped_ptr<VideoLayerImpl> VideoLayerImpl::Create( VideoFrameProviderClientImpl::Create( provider, tree_impl->GetVideoFrameControllerClient()); - return make_scoped_ptr(new VideoLayerImpl( + return base::WrapUnique(new VideoLayerImpl( tree_impl, id, std::move(provider_client_impl), video_rotation)); } @@ -66,9 +66,9 @@ VideoLayerImpl::~VideoLayerImpl() { } } -scoped_ptr<LayerImpl> VideoLayerImpl::CreateLayerImpl( +std::unique_ptr<LayerImpl> VideoLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { - return make_scoped_ptr(new VideoLayerImpl( + return base::WrapUnique(new VideoLayerImpl( tree_impl, id(), provider_client_impl_, video_rotation_)); } @@ -216,24 +216,15 @@ 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, - software_resources_[0], - premultiplied_alpha, - uv_top_left, - uv_bottom_right, - SK_ColorTRANSPARENT, - opacity, - flipped, - nearest_neighbor); + texture_quad->SetNew(shared_quad_state, quad_rect, opaque_rect, + visible_quad_rect, software_resources_[0], + premultiplied_alpha, uv_top_left, uv_bottom_right, + SK_ColorTRANSPARENT, opacity, flipped, + nearest_neighbor, false); ValidateQuadResources(texture_quad); break; } case VideoFrameExternalResources::YUV_RESOURCE: { - DCHECK_GE(frame_resources_.size(), 3u); - YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601; int videoframe_color_space; if (frame_->metadata()->GetInteger(media::VideoFrameMetadata::COLOR_SPACE, @@ -250,12 +241,18 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass, frame_->format(), media::VideoFrame::kUPlane, coded_size); if (frame_->HasTextures()) { - DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_->format()); - DCHECK_EQ(3u, frame_resources_.size()); // Alpha is not supported yet. + if (frame_->format() == media::PIXEL_FORMAT_NV12) { + DCHECK_EQ(2u, frame_resources_.size()); + } else { + DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_->format()); + DCHECK_EQ(3u, + frame_resources_.size()); // Alpha is not supported yet. + } } else { DCHECK(uv_tex_size == media::VideoFrame::PlaneSize( frame_->format(), media::VideoFrame::kVPlane, coded_size)); + DCHECK_GE(frame_resources_.size(), 3u); DCHECK(frame_resources_.size() <= 3 || ya_tex_size == media::VideoFrame::PlaneSize( frame_->format(), media::VideoFrame::kAPlane, @@ -281,7 +278,8 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass, 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].id, frame_resources_[1].id, - frame_resources_[2].id, + frame_resources_.size() > 2 ? frame_resources_[2].id + : frame_resources_[1].id, frame_resources_.size() > 3 ? frame_resources_[3].id : 0, color_space, frame_resource_offset_, frame_resource_multiplier_); ValidateQuadResources(yuv_video_quad); @@ -307,7 +305,7 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass, visible_quad_rect, frame_resources_[0].id, premultiplied_alpha, uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT, opacity, flipped, - nearest_neighbor); + nearest_neighbor, false); ValidateQuadResources(texture_quad); break; } @@ -326,19 +324,6 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass, ValidateQuadResources(stream_video_quad); break; } - case VideoFrameExternalResources::IO_SURFACE: { - DCHECK_EQ(frame_resources_.size(), 1u); - if (frame_resources_.size() < 1u) - 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].id, - IOSurfaceDrawQuad::UNFLIPPED); - ValidateQuadResources(io_surface_quad); - break; - } #if defined(VIDEO_HOLE) // This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not // maintained by the general compositor team. Please contact the following diff --git a/chromium/cc/layers/video_layer_impl.h b/chromium/cc/layers/video_layer_impl.h index 6db19302c2a..4a2480acdf2 100644 --- a/chromium/cc/layers/video_layer_impl.h +++ b/chromium/cc/layers/video_layer_impl.h @@ -26,14 +26,15 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { public: // Must be called on the impl thread while the main thread is blocked. This is // so that |provider| stays alive while this is being created. - static scoped_ptr<VideoLayerImpl> Create(LayerTreeImpl* tree_impl, - int id, - VideoFrameProvider* provider, - media::VideoRotation video_rotation); + static std::unique_ptr<VideoLayerImpl> Create( + LayerTreeImpl* tree_impl, + int id, + VideoFrameProvider* provider, + media::VideoRotation video_rotation); ~VideoLayerImpl() override; // LayerImpl implementation. - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; bool WillDraw(DrawMode draw_mode, ResourceProvider* resource_provider) override; void AppendQuads(RenderPass* render_pass, @@ -61,7 +62,7 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { media::VideoRotation video_rotation_; - scoped_ptr<VideoResourceUpdater> updater_; + std::unique_ptr<VideoResourceUpdater> updater_; VideoFrameExternalResources::ResourceType frame_resource_type_; float frame_resource_offset_; float frame_resource_multiplier_; diff --git a/chromium/cc/layers/video_layer_impl_unittest.cc b/chromium/cc/layers/video_layer_impl_unittest.cc index 355837601ac..38ea21d01b3 100644 --- a/chromium/cc/layers/video_layer_impl_unittest.cc +++ b/chromium/cc/layers/video_layer_impl_unittest.cc @@ -94,14 +94,14 @@ TEST(VideoLayerImplTest, OccludesOtherLayers) { auto active_tree = impl.host_impl()->active_tree(); // Create a video layer with no frame on top of another layer. - scoped_ptr<LayerImpl> layer_impl = LayerImpl::Create(active_tree, 3); - layer_impl->SetForceRenderSurface(true); + std::unique_ptr<LayerImpl> layer_impl = LayerImpl::Create(active_tree, 3); + layer_impl->test_properties()->force_render_surface = true; layer_impl->SetBounds(layer_size); layer_impl->SetDrawsContent(true); const auto& draw_properties = layer_impl->draw_properties(); FakeVideoFrameProvider provider; - scoped_ptr<VideoLayerImpl> video_layer_impl = VideoLayerImpl::Create( + std::unique_ptr<VideoLayerImpl> video_layer_impl = VideoLayerImpl::Create( active_tree, 4, &provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); @@ -312,6 +312,7 @@ TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) { impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); @@ -335,14 +336,16 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) { LayerTestCommon::LayerImplTest impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); - gpu::MailboxHolder mailbox_holder; - mailbox_holder.mailbox.name[0] = 1; + gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes]; + mailbox_holders[0].mailbox.name[0] = 1; + mailbox_holders[1].mailbox.name[0] = 1; + mailbox_holders[2].mailbox.name[0] = 1; scoped_refptr<media::VideoFrame> video_frame = - 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()); + media::VideoFrame::WrapNativeTextures( + media::PIXEL_FORMAT_I420, mailbox_holders, base::Bind(EmptyCallback), + gfx::Size(10, 10), gfx::Rect(10, 10), gfx::Size(10, 10), + base::TimeDelta()); ASSERT_TRUE(video_frame); video_frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, true); @@ -353,6 +356,7 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) { impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc index b54c9cce2d6..d80d40c9f25 100644 --- a/chromium/cc/layers/viewport.cc +++ b/chromium/cc/layers/viewport.cc @@ -5,6 +5,7 @@ #include "cc/layers/viewport.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "cc/input/top_controls_manager.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" @@ -14,9 +15,8 @@ namespace cc { // static -scoped_ptr<Viewport> Viewport::Create( - LayerTreeHostImpl* host_impl) { - return make_scoped_ptr(new Viewport(host_impl)); +std::unique_ptr<Viewport> Viewport::Create(LayerTreeHostImpl* host_impl) { + return base::WrapUnique(new Viewport(host_impl)); } Viewport::Viewport(LayerTreeHostImpl* host_impl) diff --git a/chromium/cc/layers/viewport.h b/chromium/cc/layers/viewport.h index 0c928818ac6..2d603f253f2 100644 --- a/chromium/cc/layers/viewport.h +++ b/chromium/cc/layers/viewport.h @@ -5,9 +5,10 @@ #ifndef CC_LAYERS_VIEWPORT_H_ #define CC_LAYERS_VIEWPORT_H_ +#include <memory> + #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/layers/layer_impl.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -34,7 +35,7 @@ class CC_EXPORT Viewport { gfx::Vector2dF content_scrolled_delta; }; - static scoped_ptr<Viewport> Create(LayerTreeHostImpl* host_impl); + static std::unique_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. diff --git a/chromium/cc/output/begin_frame_args.cc b/chromium/cc/output/begin_frame_args.cc index 98f0a3e446f..e25d2f55c27 100644 --- a/chromium/cc/output/begin_frame_args.cc +++ b/chromium/cc/output/begin_frame_args.cc @@ -98,9 +98,9 @@ BeginFrameArgs BeginFrameArgs::Create(BeginFrameArgs::CreationLocation location, #endif } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> BeginFrameArgs::AsValue() const { - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); AsValueInto(state.get()); return std::move(state); diff --git a/chromium/cc/output/begin_frame_args.h b/chromium/cc/output/begin_frame_args.h index 274963103ca..c8c7b2f2277 100644 --- a/chromium/cc/output/begin_frame_args.h +++ b/chromium/cc/output/begin_frame_args.h @@ -5,9 +5,10 @@ #ifndef CC_OUTPUT_BEGIN_FRAME_ARGS_H_ #define CC_OUTPUT_BEGIN_FRAME_ARGS_H_ +#include <memory> + #include "base/location.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "base/values.h" #include "cc/base/cc_export.h" @@ -83,7 +84,7 @@ struct CC_EXPORT BeginFrameArgs { bool IsValid() const { return interval >= base::TimeDelta(); } - scoped_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; void AsValueInto(base::trace_event::TracedValue* dict) const; void ToProtobuf(proto::BeginFrameArgs* proto) const; diff --git a/chromium/cc/output/bsp_tree.cc b/chromium/cc/output/bsp_tree.cc index 6f0b99ea204..300ba2aebb9 100644 --- a/chromium/cc/output/bsp_tree.cc +++ b/chromium/cc/output/bsp_tree.cc @@ -4,25 +4,27 @@ #include "cc/output/bsp_tree.h" +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "cc/base/container_util.h" #include "cc/output/bsp_compare_result.h" #include "cc/quads/draw_polygon.h" namespace cc { -BspNode::BspNode(scoped_ptr<DrawPolygon> data) : node_data(std::move(data)) {} +BspNode::BspNode(std::unique_ptr<DrawPolygon> data) + : node_data(std::move(data)) {} BspNode::~BspNode() { } -BspTree::BspTree(std::deque<scoped_ptr<DrawPolygon>>* list) { +BspTree::BspTree(std::deque<std::unique_ptr<DrawPolygon>>* list) { if (list->size() == 0) return; - root_ = make_scoped_ptr(new BspNode(PopFront(list))); + root_ = base::WrapUnique(new BspNode(PopFront(list))); BuildTree(root_.get(), list); } @@ -32,76 +34,50 @@ BspTree::BspTree(std::deque<scoped_ptr<DrawPolygon>>* list) { // front when the heuristic decides that they're a better choice. This way we // can always simply just take from the front of the deque for our node's // data. -void BspTree::BuildTree(BspNode* node, - std::deque<scoped_ptr<DrawPolygon>>* polygon_list) { - std::deque<scoped_ptr<DrawPolygon>> front_list; - std::deque<scoped_ptr<DrawPolygon>> back_list; +void BspTree::BuildTree( + BspNode* node, + std::deque<std::unique_ptr<DrawPolygon>>* polygon_list) { + std::deque<std::unique_ptr<DrawPolygon>> front_list; + std::deque<std::unique_ptr<DrawPolygon>> back_list; // We take in a list of polygons at this level of the tree, and have to // find a splitting plane, then classify polygons as either in front of // or behind that splitting plane. while (!polygon_list->empty()) { - // Is this particular polygon in front of or behind our splitting polygon. - BspCompareResult comparer_result = - GetNodePositionRelative(*polygon_list->front(), *(node->node_data)); - - // If it's clearly behind or in front of the splitting plane, we use the - // heuristic to decide whether or not we should put it at the back - // or front of the list. - switch (comparer_result) { - case BSP_FRONT: - front_list.push_back(PopFront(polygon_list)); - break; - case BSP_BACK: - back_list.push_back(PopFront(polygon_list)); - break; - case BSP_SPLIT: - { - scoped_ptr<DrawPolygon> polygon; - scoped_ptr<DrawPolygon> new_front; - scoped_ptr<DrawPolygon> new_back; - // Time to split this geometry, *it needs to be split by node_data. - polygon = PopFront(polygon_list); - bool split_result = - polygon->Split(*(node->node_data), &new_front, &new_back); - DCHECK(split_result); - if (!split_result) { - break; - } + std::unique_ptr<DrawPolygon> polygon; + std::unique_ptr<DrawPolygon> new_front; + std::unique_ptr<DrawPolygon> new_back; + // Time to split this geometry, *it needs to be split by node_data. + polygon = PopFront(polygon_list); + bool is_coplanar; + node->node_data->SplitPolygon(std::move(polygon), &new_front, &new_back, + &is_coplanar); + if (is_coplanar) { + if (new_front) + node->coplanars_front.push_back(std::move(new_front)); + if (new_back) + node->coplanars_back.push_back(std::move(new_back)); + } else { + if (new_front) front_list.push_back(std::move(new_front)); + if (new_back) back_list.push_back(std::move(new_back)); - break; - } - case BSP_COPLANAR_FRONT: - node->coplanars_front.push_back(PopFront(polygon_list)); - break; - case BSP_COPLANAR_BACK: - node->coplanars_back.push_back(PopFront(polygon_list)); - break; - default: - NOTREACHED(); - break; } } // Build the back subtree using the front of the back_list as our splitter. if (back_list.size() > 0) { - node->back_child = make_scoped_ptr(new BspNode(PopFront(&back_list))); + node->back_child = base::WrapUnique(new BspNode(PopFront(&back_list))); BuildTree(node->back_child.get(), &back_list); } // Build the front subtree using the front of the front_list as our splitter. if (front_list.size() > 0) { - node->front_child = make_scoped_ptr(new BspNode(PopFront(&front_list))); + node->front_child = base::WrapUnique(new BspNode(PopFront(&front_list))); BuildTree(node->front_child.get(), &front_list); } } -BspCompareResult BspTree::GetNodePositionRelative(const DrawPolygon& node_a, - const DrawPolygon& node_b) { - return DrawPolygon::SideCompare(node_a, node_b); -} - // The base comparer with 0,0,0 as camera position facing forward BspCompareResult BspTree::GetCameraPositionRelative(const DrawPolygon& node) { if (node.normal().z() > 0.0f) { diff --git a/chromium/cc/output/bsp_tree.h b/chromium/cc/output/bsp_tree.h index 695c47e5b9f..65c601b4a94 100644 --- a/chromium/cc/output/bsp_tree.h +++ b/chromium/cc/output/bsp_tree.h @@ -8,9 +8,9 @@ #include <stddef.h> #include <deque> +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" #include "cc/output/bsp_compare_result.h" #include "cc/quads/draw_polygon.h" @@ -18,22 +18,22 @@ namespace cc { struct BspNode { // This represents the splitting plane. - scoped_ptr<DrawPolygon> node_data; + std::unique_ptr<DrawPolygon> node_data; // This represents any coplanar geometry we found while building the BSP. - std::vector<scoped_ptr<DrawPolygon>> coplanars_front; - std::vector<scoped_ptr<DrawPolygon>> coplanars_back; + std::vector<std::unique_ptr<DrawPolygon>> coplanars_front; + std::vector<std::unique_ptr<DrawPolygon>> coplanars_back; - scoped_ptr<BspNode> back_child; - scoped_ptr<BspNode> front_child; + std::unique_ptr<BspNode> back_child; + std::unique_ptr<BspNode> front_child; - explicit BspNode(scoped_ptr<DrawPolygon> data); + explicit BspNode(std::unique_ptr<DrawPolygon> data); ~BspNode(); }; class CC_EXPORT BspTree { public: - explicit BspTree(std::deque<scoped_ptr<DrawPolygon>>* list); - scoped_ptr<BspNode>& root() { return root_; } + explicit BspTree(std::deque<std::unique_ptr<DrawPolygon>>* list); + std::unique_ptr<BspNode>& root() { return root_; } template <typename ActionHandlerType> void TraverseWithActionHandler(ActionHandlerType* action_handler) const { @@ -45,10 +45,10 @@ class CC_EXPORT BspTree { ~BspTree(); private: - scoped_ptr<BspNode> root_; + std::unique_ptr<BspNode> root_; - void FromList(std::vector<scoped_ptr<DrawPolygon>>* list); - void BuildTree(BspNode* node, std::deque<scoped_ptr<DrawPolygon>>* data); + void FromList(std::vector<std::unique_ptr<DrawPolygon>>* list); + void BuildTree(BspNode* node, std::deque<std::unique_ptr<DrawPolygon>>* data); template <typename ActionHandlerType> void WalkInOrderAction(ActionHandlerType* action_handler, @@ -62,8 +62,8 @@ class CC_EXPORT BspTree { const BspNode* node, const BspNode* first_child, const BspNode* second_child, - const std::vector<scoped_ptr<DrawPolygon>>& first_coplanars, - const std::vector<scoped_ptr<DrawPolygon>>& second_coplanars) const { + const std::vector<std::unique_ptr<DrawPolygon>>& first_coplanars, + const std::vector<std::unique_ptr<DrawPolygon>>& second_coplanars) const { if (first_child) { WalkInOrderRecursion(action_handler, first_child); } @@ -101,10 +101,6 @@ class CC_EXPORT BspTree { } } - // Returns whether or not nodeA is on one or the other side of nodeB, - // coplanar, or whether it crosses nodeB's plane and needs to be split - static BspCompareResult GetNodePositionRelative(const DrawPolygon& node_a, - const DrawPolygon& node_b); // Returns whether or not our viewer is in front of or behind the plane // defined by this polygon/node static BspCompareResult GetCameraPositionRelative(const DrawPolygon& node); diff --git a/chromium/cc/output/bsp_tree_unittest.cc b/chromium/cc/output/bsp_tree_unittest.cc index 1d71413cd4d..c787d3e7c49 100644 --- a/chromium/cc/output/bsp_tree_unittest.cc +++ b/chromium/cc/output/bsp_tree_unittest.cc @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/output/bsp_tree.h" + #include <stddef.h> #include <deque> +#include <memory> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "cc/output/bsp_tree.h" #include "cc/output/bsp_walk_action.h" #include "cc/quads/draw_polygon.h" #include "testing/gtest/include/gtest/gtest.h" @@ -32,7 +33,7 @@ namespace { class BspTreeTest { public: - static void RunTest(std::deque<scoped_ptr<DrawPolygon>>* test_polygons, + static void RunTest(std::deque<std::unique_ptr<DrawPolygon>>* test_polygons, const std::vector<int>& compare_list) { BspTree bsp_tree(test_polygons); @@ -44,15 +45,41 @@ class BspTreeTest { EXPECT_TRUE(VerifySidedness(bsp_tree.root())); } - static bool VerifySidedness(const scoped_ptr<BspNode>& node) { + static BspCompareResult SideCompare(const DrawPolygon& a, + const DrawPolygon& b) { + const float split_threshold = 0.05f; + bool pos = false; + bool neg = false; + for (const auto& pt : a.points()) { + float dist = b.SignedPointDistance(pt); + neg |= dist < -split_threshold; + pos |= dist > split_threshold; + } + if (pos && neg) + return BSP_SPLIT; + if (neg) + return BSP_BACK; + if (pos) + return BSP_FRONT; + double dot = gfx::DotProduct(a.normal(), b.normal()); + if ((dot >= 0.0f && a.order_index() >= b.order_index()) || + (dot <= 0.0f && a.order_index() <= b.order_index())) { + // The sign of the dot product of the normals along with document order + // determine which side it goes on, the vertices are ambiguous. + return BSP_COPLANAR_BACK; + } + return BSP_COPLANAR_FRONT; + } + + static bool VerifySidedness(const std::unique_ptr<BspNode>& node) { // We check if both the front and back child nodes have geometry that is // completely on the expected side of the current node. bool front_ok = true; bool back_ok = true; if (node->back_child) { // Make sure the back child lies entirely behind this node. - BspCompareResult result = DrawPolygon::SideCompare( - *(node->back_child->node_data), *(node->node_data)); + BspCompareResult result = + SideCompare(*(node->back_child->node_data), *(node->node_data)); if (result != BSP_BACK) { return false; } @@ -60,8 +87,8 @@ class BspTreeTest { } // Make sure the front child lies entirely in front of this node. if (node->front_child) { - BspCompareResult result = DrawPolygon::SideCompare( - *(node->front_child->node_data), *(node->node_data)); + BspCompareResult result = + SideCompare(*(node->front_child->node_data), *(node->node_data)); if (result != BSP_FRONT) { return false; } @@ -73,15 +100,15 @@ class BspTreeTest { // Now we need to make sure our coplanar geometry is all actually coplanar. for (size_t i = 0; i < node->coplanars_front.size(); i++) { - BspCompareResult result = DrawPolygon::SideCompare( - *(node->coplanars_front[i]), *(node->node_data)); + BspCompareResult result = + SideCompare(*(node->coplanars_front[i]), *(node->node_data)); if (result != BSP_COPLANAR_FRONT) { return false; } } for (size_t i = 0; i < node->coplanars_back.size(); i++) { - BspCompareResult result = DrawPolygon::SideCompare( - *(node->coplanars_back[i]), *(node->node_data)); + BspCompareResult result = + SideCompare(*(node->coplanars_back[i]), *(node->node_data)); if (result != BSP_COPLANAR_BACK) { return false; } @@ -108,14 +135,14 @@ TEST(BspTreeTest, NoSplit) { vertices_c.push_back(gfx::Point3F(10.0f, 0.0f, 5.0f)); vertices_c.push_back(gfx::Point3F(10.0f, 10.0f, 5.0f)); - scoped_ptr<DrawPolygon> polygon_a( + std::unique_ptr<DrawPolygon> polygon_a( CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0)); - scoped_ptr<DrawPolygon> polygon_b( + std::unique_ptr<DrawPolygon> polygon_b( CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 1)); - scoped_ptr<DrawPolygon> polygon_c( + std::unique_ptr<DrawPolygon> polygon_c( CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 2)); - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_a)); polygon_list.push_back(std::move(polygon_b)); polygon_list.push_back(std::move(polygon_c)); @@ -138,12 +165,12 @@ TEST(BspTreeTest, BasicSplit) { vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, 5.0f)); vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, 5.0f)); - scoped_ptr<DrawPolygon> polygon_a( + std::unique_ptr<DrawPolygon> polygon_a( CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0)); - scoped_ptr<DrawPolygon> polygon_b( + std::unique_ptr<DrawPolygon> polygon_b( CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1)); - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_a)); polygon_list.push_back(std::move(polygon_b)); @@ -167,12 +194,12 @@ TEST(BspTreeTest, QuadOffset) { vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -10.0f)); vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -10.0f)); - scoped_ptr<DrawPolygon> polygon_a( + std::unique_ptr<DrawPolygon> polygon_a( CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0)); - scoped_ptr<DrawPolygon> polygon_b( + std::unique_ptr<DrawPolygon> polygon_b( CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1)); - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_a)); polygon_list.push_back(std::move(polygon_b)); @@ -196,12 +223,12 @@ TEST(BspTreeTest, QuadOffsetSplit) { vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -10.0f)); vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -10.0f)); - scoped_ptr<DrawPolygon> polygon_a( + std::unique_ptr<DrawPolygon> polygon_a( CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0)); - scoped_ptr<DrawPolygon> polygon_b( + std::unique_ptr<DrawPolygon> polygon_b( CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1)); - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_b)); polygon_list.push_back(std::move(polygon_a)); @@ -230,14 +257,14 @@ TEST(BspTreeTest, ThreeWaySplit) { vertices_c.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f)); vertices_c.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f)); - scoped_ptr<DrawPolygon> polygon_a( + std::unique_ptr<DrawPolygon> polygon_a( CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0)); - scoped_ptr<DrawPolygon> polygon_b( + std::unique_ptr<DrawPolygon> polygon_b( CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1)); - scoped_ptr<DrawPolygon> polygon_c( + std::unique_ptr<DrawPolygon> polygon_c( CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 1.0f, 0.0f), 2)); - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_a)); polygon_list.push_back(std::move(polygon_b)); polygon_list.push_back(std::move(polygon_c)); @@ -266,19 +293,19 @@ TEST(BspTreeTest, Coplanar) { vertices_c.push_back(gfx::Point3F(3.0f, 3.0f, 0.0f)); vertices_c.push_back(gfx::Point3F(3.0f, -3.0f, 0.0f)); - scoped_ptr<DrawPolygon> polygon_a( + std::unique_ptr<DrawPolygon> polygon_a( CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0)); - scoped_ptr<DrawPolygon> polygon_b( + std::unique_ptr<DrawPolygon> polygon_b( CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 1)); - scoped_ptr<DrawPolygon> polygon_c( + std::unique_ptr<DrawPolygon> polygon_c( CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 2)); - scoped_ptr<DrawPolygon> polygon_d = polygon_a->CreateCopy(); - scoped_ptr<DrawPolygon> polygon_e = polygon_b->CreateCopy(); - scoped_ptr<DrawPolygon> polygon_f = polygon_c->CreateCopy(); + std::unique_ptr<DrawPolygon> polygon_d = polygon_a->CreateCopy(); + std::unique_ptr<DrawPolygon> polygon_e = polygon_b->CreateCopy(); + std::unique_ptr<DrawPolygon> polygon_f = polygon_c->CreateCopy(); { - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_a)); polygon_list.push_back(std::move(polygon_b)); polygon_list.push_back(std::move(polygon_c)); @@ -290,7 +317,7 @@ TEST(BspTreeTest, Coplanar) { // Now check a different order and ensure we get that back as well { - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_f)); polygon_list.push_back(std::move(polygon_d)); polygon_list.push_back(std::move(polygon_e)); @@ -326,16 +353,16 @@ TEST(BspTreeTest, CoplanarSplit) { vertices_d.push_back(gfx::Point3F(0.0f, 15.0f, 15.0f)); vertices_d.push_back(gfx::Point3F(0.0f, -15.0f, 15.0f)); - scoped_ptr<DrawPolygon> polygon_a( + std::unique_ptr<DrawPolygon> polygon_a( CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0)); - scoped_ptr<DrawPolygon> polygon_b( + std::unique_ptr<DrawPolygon> polygon_b( CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 1)); - scoped_ptr<DrawPolygon> polygon_c( + std::unique_ptr<DrawPolygon> polygon_c( CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 2)); - scoped_ptr<DrawPolygon> polygon_d( + std::unique_ptr<DrawPolygon> polygon_d( CREATE_DRAW_POLYGON(vertices_d, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 3)); - std::deque<scoped_ptr<DrawPolygon>> polygon_list; + std::deque<std::unique_ptr<DrawPolygon>> polygon_list; polygon_list.push_back(std::move(polygon_a)); polygon_list.push_back(std::move(polygon_b)); polygon_list.push_back(std::move(polygon_c)); diff --git a/chromium/cc/output/bsp_walk_action.cc b/chromium/cc/output/bsp_walk_action.cc index 8a3369416ce..56fca47852d 100644 --- a/chromium/cc/output/bsp_walk_action.cc +++ b/chromium/cc/output/bsp_walk_action.cc @@ -4,9 +4,9 @@ #include "cc/output/bsp_walk_action.h" +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" #include "cc/output/direct_renderer.h" #include "cc/quads/draw_polygon.h" #include "cc/quads/draw_quad.h" diff --git a/chromium/cc/output/bsp_walk_action.h b/chromium/cc/output/bsp_walk_action.h index a89d8eab364..3f605dabbdf 100644 --- a/chromium/cc/output/bsp_walk_action.h +++ b/chromium/cc/output/bsp_walk_action.h @@ -5,9 +5,9 @@ #ifndef CC_OUTPUT_BSP_WALK_ACTION_H_ #define CC_OUTPUT_BSP_WALK_ACTION_H_ +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" #include "cc/output/direct_renderer.h" #include "cc/quads/draw_polygon.h" diff --git a/chromium/cc/output/ca_layer_overlay.cc b/chromium/cc/output/ca_layer_overlay.cc index e418934fd65..3e53dd4d5d6 100644 --- a/chromium/cc/output/ca_layer_overlay.cc +++ b/chromium/cc/output/ca_layer_overlay.cc @@ -5,7 +5,6 @@ #include "cc/output/ca_layer_overlay.h" #include "base/metrics/histogram.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/stream_video_draw_quad.h" #include "cc/quads/texture_draw_quad.h" @@ -39,17 +38,6 @@ enum CALayerResult { CA_LAYER_FAILED_COUNT, }; -CALayerResult FromIOSurfaceQuad(ResourceProvider* resource_provider, - const IOSurfaceDrawQuad* quad, - CALayerOverlay* ca_layer_overlay) { - unsigned resource_id = quad->io_surface_resource_id(); - if (!resource_provider->IsOverlayCandidate(resource_id)) - return CA_LAYER_FAILED_IO_SURFACE_NOT_CANDIDATE; - ca_layer_overlay->contents_resource_id = resource_id; - ca_layer_overlay->contents_rect = gfx::RectF(0, 0, 1, 1); - return CA_LAYER_SUCCESS; -} - CALayerResult FromStreamVideoQuad(ResourceProvider* resource_provider, const StreamVideoDrawQuad* quad, CALayerOverlay* ca_layer_overlay) { @@ -83,11 +71,6 @@ CALayerResult FromTextureQuad(ResourceProvider* resource_provider, unsigned resource_id = quad->resource_id(); if (!resource_provider->IsOverlayCandidate(resource_id)) return CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE; - // The filter has not yet been plumbed through the CoreAnimation compositor, - // so we can't use it for non-default minification/magnification filters. - // https://crbug.com/602103 - if (quad->nearest_neighbor) - return CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE; if (quad->y_flipped) { // The anchor point is at the bottom-left corner of the CALayer. The // transformation that flips the contents of the layer without changing its @@ -106,6 +89,7 @@ CALayerResult FromTextureQuad(ResourceProvider* resource_provider, return CA_LAYER_FAILED_UNKNOWN; } ca_layer_overlay->opacity *= quad->vertex_opacity[0]; + ca_layer_overlay->filter = quad->nearest_neighbor ? GL_NEAREST : GL_LINEAR; return CA_LAYER_SUCCESS; } @@ -159,10 +143,6 @@ CALayerResult FromDrawQuad(ResourceProvider* resource_provider, quad->shared_quad_state->quad_to_target_transform.matrix(); switch (quad->material) { - case DrawQuad::IO_SURFACE_CONTENT: - return FromIOSurfaceQuad(resource_provider, - IOSurfaceDrawQuad::MaterialCast(quad), - ca_layer_overlay); case DrawQuad::TEXTURE_CONTENT: return FromTextureQuad(resource_provider, TextureDrawQuad::MaterialCast(quad), @@ -196,7 +176,7 @@ CALayerResult FromDrawQuad(ResourceProvider* resource_provider, } // namespace -CALayerOverlay::CALayerOverlay() {} +CALayerOverlay::CALayerOverlay() : filter(GL_LINEAR) {} CALayerOverlay::CALayerOverlay(const CALayerOverlay& other) = default; diff --git a/chromium/cc/output/ca_layer_overlay.h b/chromium/cc/output/ca_layer_overlay.h index 00a4039f136..09dc7f83bb6 100644 --- a/chromium/cc/output/ca_layer_overlay.h +++ b/chromium/cc/output/ca_layer_overlay.h @@ -7,7 +7,7 @@ #include "cc/quads/render_pass.h" #include "third_party/skia/include/core/SkColor.h" -#include "third_party/skia/include/utils/SkMatrix44.h" +#include "third_party/skia/include/core/SkMatrix44.h" #include "ui/gfx/geometry/rect_f.h" namespace cc { @@ -42,6 +42,8 @@ class CC_EXPORT CALayerOverlay { gfx::RectF bounds_rect; // The transform to apply to the CALayer. SkMatrix44 transform = SkMatrix44(SkMatrix44::kIdentity_Constructor); + // The minification and magnification filters for the CALayer. + unsigned filter; }; typedef std::vector<CALayerOverlay> CALayerOverlayList; diff --git a/chromium/cc/output/compositor_frame.h b/chromium/cc/output/compositor_frame.h index 8a95fffe271..e5e0c660f6f 100644 --- a/chromium/cc/output/compositor_frame.h +++ b/chromium/cc/output/compositor_frame.h @@ -5,8 +5,9 @@ #ifndef CC_OUTPUT_COMPOSITOR_FRAME_H_ #define CC_OUTPUT_COMPOSITOR_FRAME_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/output/delegated_frame_data.h" @@ -23,8 +24,8 @@ class CC_EXPORT CompositorFrame { ~CompositorFrame(); CompositorFrameMetadata metadata; - scoped_ptr<DelegatedFrameData> delegated_frame_data; - scoped_ptr<GLFrameData> gl_frame_data; + std::unique_ptr<DelegatedFrameData> delegated_frame_data; + std::unique_ptr<GLFrameData> gl_frame_data; void AssignTo(CompositorFrame* target); diff --git a/chromium/cc/output/compositor_frame_ack.h b/chromium/cc/output/compositor_frame_ack.h index a4e161b3d8d..55ca7f1ccb0 100644 --- a/chromium/cc/output/compositor_frame_ack.h +++ b/chromium/cc/output/compositor_frame_ack.h @@ -5,8 +5,9 @@ #ifndef CC_OUTPUT_COMPOSITOR_FRAME_ACK_H_ #define CC_OUTPUT_COMPOSITOR_FRAME_ACK_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/gl_frame_data.h" #include "cc/resources/returned_resource.h" @@ -19,7 +20,7 @@ class CC_EXPORT CompositorFrameAck { ~CompositorFrameAck(); ReturnedResourceArray resources; - scoped_ptr<GLFrameData> gl_frame_data; + std::unique_ptr<GLFrameData> gl_frame_data; private: DISALLOW_COPY_AND_ASSIGN(CompositorFrameAck); diff --git a/chromium/cc/output/context_provider.cc b/chromium/cc/output/context_provider.cc deleted file mode 100644 index 5ff7f930617..00000000000 --- a/chromium/cc/output/context_provider.cc +++ /dev/null @@ -1,16 +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/output/context_provider.h" - -#include <stddef.h> - -#include <limits> - -namespace cc { - -ContextProvider::Capabilities::Capabilities() - : max_transfer_buffer_usage_bytes(std::numeric_limits<size_t>::max()) {} - -} // namespace cc diff --git a/chromium/cc/output/context_provider.h b/chromium/cc/output/context_provider.h index c560ad0fa69..2245b643e13 100644 --- a/chromium/cc/output/context_provider.h +++ b/chromium/cc/output/context_provider.h @@ -30,6 +30,11 @@ struct ManagedMemoryPolicy; class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { public: + // Hold an instance of this lock while using a context across multiple + // threads. This only works for ContextProviders that will return a valid + // lock from GetLock(), so is not always supported. Most use of + // ContextProvider should be single-thread only on the thread that + // BindToCurrentThread is run on. class ScopedContextLock { public: explicit ScopedContextLock(ContextProvider* context_provider) @@ -51,6 +56,7 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { ContextProvider* const context_provider_; base::AutoLock context_lock_; }; + // Bind the 3d context to the current thread. This should be called before // accessing the contexts. Calling it more than once should have no effect. // Once this function has been called, the class should only be accessed @@ -58,34 +64,17 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { // rules for access on a different thread. See SetupLockOnMainThread(), which // can be used to provide access from multiple threads. virtual bool BindToCurrentThread() = 0; - virtual void DetachFromThread() {} virtual gpu::gles2::GLES2Interface* ContextGL() = 0; virtual gpu::ContextSupport* ContextSupport() = 0; virtual class GrContext* GrContext() = 0; - struct Capabilities { - gpu::Capabilities gpu; - size_t max_transfer_buffer_usage_bytes; - - CC_EXPORT Capabilities(); - }; - // Invalidates the cached OpenGL state in GrContext. // See skia GrContext::resetContext for details. virtual void InvalidateGrContext(uint32_t state) = 0; - // Sets up a lock so this context can be used from multiple threads. After - // calling this, all functions without explicit thread usage constraints can - // be used on any thread while the lock returned by GetLock() is acquired. - virtual void SetupLock() = 0; - - // Returns the lock that should be held if using this context from multiple - // threads. This can be called on any thread. - virtual base::Lock* GetLock() = 0; - // Returns the capabilities of the currently bound 3d context. - virtual Capabilities ContextCapabilities() = 0; + virtual gpu::Capabilities ContextCapabilities() = 0; // Delete all cached gpu resources. virtual void DeleteCachedResources() = 0; @@ -97,6 +86,16 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { virtual void SetLostContextCallback( const LostContextCallback& lost_context_callback) = 0; + // Below are helper methods for ScopedContextLock. Use that instead of calling + // these directly. + // + // Detaches debugging thread checkers to allow use of the provider from the + // current thread. This can be called on any thread. + virtual void DetachFromThread() {} + // Returns the lock that should be held if using this context from multiple + // threads. This can be called on any thread. + virtual base::Lock* GetLock() = 0; + protected: friend class base::RefCountedThreadSafe<ContextProvider>; virtual ~ContextProvider() {} diff --git a/chromium/cc/output/copy_output_request.cc b/chromium/cc/output/copy_output_request.cc index 0018edd9a69..05f15ae1727 100644 --- a/chromium/cc/output/copy_output_request.cc +++ b/chromium/cc/output/copy_output_request.cc @@ -15,10 +15,10 @@ namespace cc { // static -scoped_ptr<CopyOutputRequest> CopyOutputRequest::CreateRelayRequest( +std::unique_ptr<CopyOutputRequest> CopyOutputRequest::CreateRelayRequest( const CopyOutputRequest& original_request, const CopyOutputRequestCallback& result_callback) { - scoped_ptr<CopyOutputRequest> relay = CreateRequest(result_callback); + std::unique_ptr<CopyOutputRequest> relay = CreateRequest(result_callback); relay->force_bitmap_result_ = original_request.force_bitmap_result_; relay->has_area_ = original_request.has_area_; relay->area_ = original_request.area_; @@ -50,7 +50,7 @@ CopyOutputRequest::~CopyOutputRequest() { SendResult(CopyOutputResult::CreateEmptyResult()); } -void CopyOutputRequest::SendResult(scoped_ptr<CopyOutputResult> result) { +void CopyOutputRequest::SendResult(std::unique_ptr<CopyOutputResult> result) { bool success = !result->IsEmpty(); base::ResetAndReturn(&result_callback_).Run(std::move(result)); TRACE_EVENT_ASYNC_END1("cc", "CopyOutputRequest", this, "success", success); @@ -60,14 +60,14 @@ void CopyOutputRequest::SendEmptyResult() { SendResult(CopyOutputResult::CreateEmptyResult()); } -void CopyOutputRequest::SendBitmapResult(scoped_ptr<SkBitmap> bitmap) { +void CopyOutputRequest::SendBitmapResult(std::unique_ptr<SkBitmap> bitmap) { SendResult(CopyOutputResult::CreateBitmapResult(std::move(bitmap))); } void CopyOutputRequest::SendTextureResult( const gfx::Size& size, const TextureMailbox& texture_mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) { + std::unique_ptr<SingleReleaseCallback> release_callback) { DCHECK(texture_mailbox.IsTexture()); SendResult(CopyOutputResult::CreateTextureResult( size, texture_mailbox, std::move(release_callback))); diff --git a/chromium/cc/output/copy_output_request.h b/chromium/cc/output/copy_output_request.h index c634db44dda..4ce583ac48d 100644 --- a/chromium/cc/output/copy_output_request.h +++ b/chromium/cc/output/copy_output_request.h @@ -5,8 +5,10 @@ #ifndef CC_OUTPUT_COPY_OUTPUT_REQUEST_H_ #define CC_OUTPUT_COPY_OUTPUT_REQUEST_H_ +#include <memory> + #include "base/callback.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" @@ -19,21 +21,21 @@ class CopyOutputResult; class CC_EXPORT CopyOutputRequest { public: - typedef base::Callback<void(scoped_ptr<CopyOutputResult> result)> + typedef base::Callback<void(std::unique_ptr<CopyOutputResult> result)> CopyOutputRequestCallback; - static scoped_ptr<CopyOutputRequest> CreateEmptyRequest() { - return make_scoped_ptr(new CopyOutputRequest); + static std::unique_ptr<CopyOutputRequest> CreateEmptyRequest() { + return base::WrapUnique(new CopyOutputRequest); } - static scoped_ptr<CopyOutputRequest> CreateRequest( + static std::unique_ptr<CopyOutputRequest> CreateRequest( const CopyOutputRequestCallback& result_callback) { - return make_scoped_ptr(new CopyOutputRequest(false, result_callback)); + return base::WrapUnique(new CopyOutputRequest(false, result_callback)); } - static scoped_ptr<CopyOutputRequest> CreateBitmapRequest( + static std::unique_ptr<CopyOutputRequest> CreateBitmapRequest( const CopyOutputRequestCallback& result_callback) { - return make_scoped_ptr(new CopyOutputRequest(true, result_callback)); + return base::WrapUnique(new CopyOutputRequest(true, result_callback)); } - static scoped_ptr<CopyOutputRequest> CreateRelayRequest( + static std::unique_ptr<CopyOutputRequest> CreateRelayRequest( const CopyOutputRequest& original_request, const CopyOutputRequestCallback& result_callback); @@ -67,12 +69,13 @@ class CC_EXPORT CopyOutputRequest { const TextureMailbox& texture_mailbox() const { return texture_mailbox_; } void SendEmptyResult(); - void SendBitmapResult(scoped_ptr<SkBitmap> bitmap); - void SendTextureResult(const gfx::Size& size, - const TextureMailbox& texture_mailbox, - scoped_ptr<SingleReleaseCallback> release_callback); + void SendBitmapResult(std::unique_ptr<SkBitmap> bitmap); + void SendTextureResult( + const gfx::Size& size, + const TextureMailbox& texture_mailbox, + std::unique_ptr<SingleReleaseCallback> release_callback); - void SendResult(scoped_ptr<CopyOutputResult> result); + void SendResult(std::unique_ptr<CopyOutputResult> result); private: CopyOutputRequest(); diff --git a/chromium/cc/output/copy_output_result.cc b/chromium/cc/output/copy_output_result.cc index 84e9ef83420..3a349f27fb8 100644 --- a/chromium/cc/output/copy_output_result.cc +++ b/chromium/cc/output/copy_output_result.cc @@ -12,7 +12,7 @@ namespace cc { CopyOutputResult::CopyOutputResult() {} -CopyOutputResult::CopyOutputResult(scoped_ptr<SkBitmap> bitmap) +CopyOutputResult::CopyOutputResult(std::unique_ptr<SkBitmap> bitmap) : size_(bitmap->width(), bitmap->height()), bitmap_(std::move(bitmap)) { DCHECK(bitmap_); } @@ -20,7 +20,7 @@ CopyOutputResult::CopyOutputResult(scoped_ptr<SkBitmap> bitmap) CopyOutputResult::CopyOutputResult( const gfx::Size& size, const TextureMailbox& texture_mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) + std::unique_ptr<SingleReleaseCallback> release_callback) : size_(size), texture_mailbox_(texture_mailbox), release_callback_(std::move(release_callback)) { @@ -32,13 +32,13 @@ CopyOutputResult::~CopyOutputResult() { release_callback_->Run(gpu::SyncToken(), false); } -scoped_ptr<SkBitmap> CopyOutputResult::TakeBitmap() { +std::unique_ptr<SkBitmap> CopyOutputResult::TakeBitmap() { return std::move(bitmap_); } void CopyOutputResult::TakeTexture( TextureMailbox* texture_mailbox, - scoped_ptr<SingleReleaseCallback>* release_callback) { + std::unique_ptr<SingleReleaseCallback>* release_callback) { *texture_mailbox = texture_mailbox_; *release_callback = std::move(release_callback_); diff --git a/chromium/cc/output/copy_output_result.h b/chromium/cc/output/copy_output_result.h index 57f0cca66ef..a64fc5108ef 100644 --- a/chromium/cc/output/copy_output_result.h +++ b/chromium/cc/output/copy_output_result.h @@ -5,7 +5,9 @@ #ifndef CC_OUTPUT_COPY_OUTPUT_RESULT_H_ #define CC_OUTPUT_COPY_OUTPUT_RESULT_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" @@ -18,19 +20,19 @@ class TextureMailbox; class CC_EXPORT CopyOutputResult { public: - static scoped_ptr<CopyOutputResult> CreateEmptyResult() { - return make_scoped_ptr(new CopyOutputResult); + static std::unique_ptr<CopyOutputResult> CreateEmptyResult() { + return base::WrapUnique(new CopyOutputResult); } - static scoped_ptr<CopyOutputResult> CreateBitmapResult( - scoped_ptr<SkBitmap> bitmap) { - return make_scoped_ptr(new CopyOutputResult(std::move(bitmap))); + static std::unique_ptr<CopyOutputResult> CreateBitmapResult( + std::unique_ptr<SkBitmap> bitmap) { + return base::WrapUnique(new CopyOutputResult(std::move(bitmap))); } - static scoped_ptr<CopyOutputResult> CreateTextureResult( + static std::unique_ptr<CopyOutputResult> CreateTextureResult( const gfx::Size& size, const TextureMailbox& texture_mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) { - return make_scoped_ptr(new CopyOutputResult(size, texture_mailbox, - std::move(release_callback))); + std::unique_ptr<SingleReleaseCallback> release_callback) { + return base::WrapUnique(new CopyOutputResult(size, texture_mailbox, + std::move(release_callback))); } ~CopyOutputResult(); @@ -40,21 +42,22 @@ class CC_EXPORT CopyOutputResult { bool HasTexture() const { return texture_mailbox_.IsValid(); } gfx::Size size() const { return size_; } - scoped_ptr<SkBitmap> TakeBitmap(); + std::unique_ptr<SkBitmap> TakeBitmap(); void TakeTexture(TextureMailbox* texture_mailbox, - scoped_ptr<SingleReleaseCallback>* release_callback); + std::unique_ptr<SingleReleaseCallback>* release_callback); private: CopyOutputResult(); - explicit CopyOutputResult(scoped_ptr<SkBitmap> bitmap); - explicit CopyOutputResult(const gfx::Size& size, - const TextureMailbox& texture_mailbox, - scoped_ptr<SingleReleaseCallback> release_callback); + explicit CopyOutputResult(std::unique_ptr<SkBitmap> bitmap); + explicit CopyOutputResult( + const gfx::Size& size, + const TextureMailbox& texture_mailbox, + std::unique_ptr<SingleReleaseCallback> release_callback); gfx::Size size_; - scoped_ptr<SkBitmap> bitmap_; + std::unique_ptr<SkBitmap> bitmap_; TextureMailbox texture_mailbox_; - scoped_ptr<SingleReleaseCallback> release_callback_; + std::unique_ptr<SingleReleaseCallback> release_callback_; }; } // namespace cc diff --git a/chromium/cc/output/delegating_renderer.cc b/chromium/cc/output/delegating_renderer.cc index 1bd7d0a300e..c063c7f608d 100644 --- a/chromium/cc/output/delegating_renderer.cc +++ b/chromium/cc/output/delegating_renderer.cc @@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "cc/output/compositor_frame_ack.h" #include "cc/output/context_provider.h" @@ -20,12 +21,12 @@ namespace cc { -scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create( +std::unique_ptr<DelegatingRenderer> DelegatingRenderer::Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, ResourceProvider* resource_provider) { - return make_scoped_ptr(new DelegatingRenderer( + return base::WrapUnique(new DelegatingRenderer( client, settings, output_surface, resource_provider)); } @@ -47,22 +48,22 @@ DelegatingRenderer::DelegatingRenderer(RendererClient* client, if (!output_surface_->context_provider()) { capabilities_.using_shared_memory_resources = true; } else { - const ContextProvider::Capabilities& caps = + const auto& caps = output_surface_->context_provider()->ContextCapabilities(); - DCHECK(!caps.gpu.iosurface || caps.gpu.texture_rectangle); + DCHECK(!caps.iosurface || caps.texture_rectangle); - capabilities_.using_egl_image = caps.gpu.egl_image_external; - capabilities_.using_image = caps.gpu.image; + capabilities_.using_egl_image = caps.egl_image_external; + capabilities_.using_image = caps.image; capabilities_.allow_rasterize_on_demand = false; // If MSAA is slow, we want this renderer to behave as though MSAA is not // available. Set samples to 0 to achieve this. - if (caps.gpu.msaa_is_slow) + if (caps.msaa_is_slow) capabilities_.max_msaa_samples = 0; else - capabilities_.max_msaa_samples = caps.gpu.max_samples; + capabilities_.max_msaa_samples = caps.max_samples; } } @@ -81,7 +82,7 @@ void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, DCHECK(!delegated_frame_data_); - delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData); + delegated_frame_data_ = base::WrapUnique(new DelegatedFrameData); DelegatedFrameData& out_data = *delegated_frame_data_; out_data.device_scale_factor = device_scale_factor; // Move the render passes and resources into the |out_frame|. diff --git a/chromium/cc/output/delegating_renderer.h b/chromium/cc/output/delegating_renderer.h index 4b0c9cc6b24..2ad09ce4861 100644 --- a/chromium/cc/output/delegating_renderer.h +++ b/chromium/cc/output/delegating_renderer.h @@ -5,8 +5,9 @@ #ifndef CC_OUTPUT_DELEGATING_RENDERER_H_ #define CC_OUTPUT_DELEGATING_RENDERER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/compositor_frame.h" #include "cc/output/renderer.h" @@ -18,7 +19,7 @@ class ResourceProvider; class CC_EXPORT DelegatingRenderer : public Renderer { public: - static scoped_ptr<DelegatingRenderer> Create( + static std::unique_ptr<DelegatingRenderer> Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, @@ -49,7 +50,7 @@ class CC_EXPORT DelegatingRenderer : public Renderer { OutputSurface* output_surface_; ResourceProvider* resource_provider_; RendererCapabilitiesImpl capabilities_; - scoped_ptr<DelegatedFrameData> delegated_frame_data_; + std::unique_ptr<DelegatedFrameData> delegated_frame_data_; DISALLOW_COPY_AND_ASSIGN(DelegatingRenderer); }; diff --git a/chromium/cc/output/delegating_renderer_unittest.cc b/chromium/cc/output/delegating_renderer_unittest.cc index 63b4e0c6df0..86e9e31f32b 100644 --- a/chromium/cc/output/delegating_renderer_unittest.cc +++ b/chromium/cc/output/delegating_renderer_unittest.cc @@ -18,8 +18,8 @@ class DelegatingRendererTest : public LayerTreeTest { DelegatingRendererTest() : LayerTreeTest(), output_surface_(NULL) {} ~DelegatingRendererTest() override {} - scoped_ptr<OutputSurface> CreateOutputSurface() override { - scoped_ptr<FakeOutputSurface> output_surface = + std::unique_ptr<OutputSurface> CreateOutputSurface() override { + std::unique_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::CreateDelegating3d(); output_surface_ = output_surface.get(); return std::move(output_surface); @@ -116,12 +116,12 @@ class DelegatingRendererTestResources : public DelegatingRendererTest { ASSERT_TRUE(last_frame.delegated_frame_data); EXPECT_EQ(2u, last_frame.delegated_frame_data->render_pass_list.size()); - // Each render pass has 11 resources in it. And the root render pass has a + // Each render pass has 10 resources in it. And the root render pass has a // mask resource used when drawing the child render pass, as well as its - // replica (it's added twice). The number 11 may change if + // replica (it's added twice). The number 10 may change if // AppendOneOfEveryQuadType() is updated, and the value here should be // updated accordingly. - EXPECT_EQ(24u, last_frame.delegated_frame_data->resource_list.size()); + EXPECT_EQ(22u, last_frame.delegated_frame_data->resource_list.size()); EndTest(); } diff --git a/chromium/cc/output/direct_renderer.cc b/chromium/cc/output/direct_renderer.cc index 7446afdc1c2..aaf1fcca4f7 100644 --- a/chromium/cc/output/direct_renderer.cc +++ b/chromium/cc/output/direct_renderer.cc @@ -181,7 +181,7 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame( for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) { if (render_pass_textures_.count(render_passes_in_draw_order[i]->id) == 0) { - scoped_ptr<ScopedResource> texture = + std::unique_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider_); render_pass_textures_[render_passes_in_draw_order[i]->id] = std::move(texture); @@ -278,23 +278,18 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass( const DrawingFrame* frame) { - gfx::Rect render_pass_scissor = frame->current_render_pass->output_rect; - - if (frame->root_damage_rect == frame->root_render_pass->output_rect || - !frame->current_render_pass->copy_requests.empty()) - return render_pass_scissor; - - gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); - if (frame->current_render_pass->transform_to_root_target.GetInverse( - &inverse_transform)) { - // Only intersect inverse-projected damage if the transform is invertible. - gfx::Rect damage_rect_in_render_pass_space = - MathUtil::ProjectEnclosingClippedRect(inverse_transform, - frame->root_damage_rect); - render_pass_scissor.Intersect(damage_rect_in_render_pass_space); - } + if (frame->current_render_pass == frame->root_render_pass) + return frame->root_damage_rect; + + // If the root damage rect has been expanded due to overlays, all the other + // damage rect calculations are incorrect. + if (!frame->root_render_pass->damage_rect.Contains(frame->root_damage_rect)) + return frame->current_render_pass->output_rect; - return render_pass_scissor; + DCHECK(frame->current_render_pass->copy_requests.empty() || + (frame->current_render_pass->damage_rect == + frame->current_render_pass->output_rect)); + return frame->current_render_pass->damage_rect; } bool DirectRenderer::NeedDeviceClip(const DrawingFrame* frame) const { @@ -397,7 +392,7 @@ void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, } void DirectRenderer::FlushPolygons( - std::deque<scoped_ptr<DrawPolygon>>* poly_list, + std::deque<std::unique_ptr<DrawPolygon>>* poly_list, DrawingFrame* frame, const gfx::Rect& render_pass_scissor, bool use_render_pass_scissor) { @@ -482,7 +477,7 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame, MoveFromDrawToWindowSpace(frame, render_pass_scissor_in_draw_space)); const QuadList& quad_list = render_pass->quad_list; - std::deque<scoped_ptr<DrawPolygon>> poly_list; + std::deque<std::unique_ptr<DrawPolygon>> poly_list; int next_polygon_id = 0; int last_sorting_context_id = 0; @@ -504,7 +499,7 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame, // This layer is in a 3D sorting context so we add it to the list of // polygons to go into the BSP tree. if (quad.shared_quad_state->sorting_context_id != 0) { - scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon( + std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon( *it, gfx::RectF(quad.visible_rect), quad.shared_quad_state->quad_to_target_transform, next_polygon_id++)); if (new_polygon->points().size() > 2u) { diff --git a/chromium/cc/output/direct_renderer.h b/chromium/cc/output/direct_renderer.h index 1328a3df56d..88fff7bf844 100644 --- a/chromium/cc/output/direct_renderer.h +++ b/chromium/cc/output/direct_renderer.h @@ -106,7 +106,7 @@ class CC_EXPORT DirectRenderer : public Renderer { static gfx::Size RenderPassTextureSize(const RenderPass* render_pass); - void FlushPolygons(std::deque<scoped_ptr<DrawPolygon>>* poly_list, + void FlushPolygons(std::deque<std::unique_ptr<DrawPolygon>>* poly_list, DrawingFrame* frame, const gfx::Rect& render_pass_scissor, bool use_render_pass_scissor); @@ -140,14 +140,16 @@ class CC_EXPORT DirectRenderer : public Renderer { virtual void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - scoped_ptr<CopyOutputRequest> request) = 0; + std::unique_ptr<CopyOutputRequest> request) = 0; // TODO(danakj): Just use a vector of pairs here? Hash map is way overkill. - std::unordered_map<RenderPassId, scoped_ptr<ScopedResource>, RenderPassIdHash> + std::unordered_map<RenderPassId, + std::unique_ptr<ScopedResource>, + RenderPassIdHash> render_pass_textures_; OutputSurface* output_surface_; ResourceProvider* resource_provider_; - scoped_ptr<OverlayProcessor> overlay_processor_; + std::unique_ptr<OverlayProcessor> overlay_processor_; // For use in coordinate conversion, this stores the output rect, viewport // rect (= unflipped version of glViewport rect), the size of target diff --git a/chromium/cc/output/filter_operation.cc b/chromium/cc/output/filter_operation.cc index a37d27d3b2b..a9c52a2e801 100644 --- a/chromium/cc/output/filter_operation.cc +++ b/chromium/cc/output/filter_operation.cc @@ -11,6 +11,9 @@ #include "cc/base/math_util.h" #include "cc/output/filter_operation.h" #include "ui/gfx/animation/tween.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/skia_util.h" namespace cc { @@ -83,15 +86,14 @@ FilterOperation::FilterOperation(FilterType type, float amount, int inset) memset(matrix_, 0, sizeof(matrix_)); } -FilterOperation::FilterOperation( - FilterType type, - const skia::RefPtr<SkImageFilter>& image_filter) +FilterOperation::FilterOperation(FilterType type, + sk_sp<SkImageFilter> image_filter) : type_(type), amount_(0), outer_threshold_(0), drop_shadow_offset_(0, 0), drop_shadow_color_(0), - image_filter_(image_filter), + image_filter_(std::move(image_filter)), zoom_inset_(0) { DCHECK_EQ(type_, REFERENCE); memset(matrix_, 0, sizeof(matrix_)); @@ -161,8 +163,7 @@ static FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) { case FilterOperation::SATURATING_BRIGHTNESS: return FilterOperation::CreateSaturatingBrightnessFilter(0.f); case FilterOperation::REFERENCE: - return FilterOperation::CreateReferenceFilter( - skia::RefPtr<SkImageFilter>()); + return FilterOperation::CreateReferenceFilter(nullptr); case FilterOperation::ALPHA_THRESHOLD: return FilterOperation::CreateAlphaThresholdFilter(SkRegion(), 1.f, 0.f); } @@ -290,20 +291,17 @@ void FilterOperation::AsValueInto(base::trace_event::TracedValue* value) const { break; case FilterOperation::REFERENCE: { int count_inputs = 0; - bool can_filter_image_gpu = false; if (image_filter_) { count_inputs = image_filter_->countInputs(); - can_filter_image_gpu = image_filter_->canFilterImageGPU(); } value->SetBoolean("is_null", !image_filter_); value->SetInteger("count_inputs", count_inputs); - value->SetBoolean("can_filter_image_gpu", can_filter_image_gpu); break; } case FilterOperation::ALPHA_THRESHOLD: { value->SetDouble("inner_threshold", amount_); value->SetDouble("outer_threshold", outer_threshold_); - scoped_ptr<base::ListValue> region_value(new base::ListValue()); + std::unique_ptr<base::ListValue> region_value(new base::ListValue()); value->BeginArray("region"); for (SkRegion::Iterator it(region_); !it.done(); it.next()) { value->AppendInteger(it.rect().x()); @@ -317,4 +315,40 @@ void FilterOperation::AsValueInto(base::trace_event::TracedValue* value) const { } } +static SkVector MapStdDeviation(float std_deviation, const SkMatrix& matrix) { + SkVector sigma = SkVector::Make(std_deviation, std_deviation); + matrix.mapVectors(&sigma, 1); + return sigma * SkIntToScalar(3); +} + +gfx::Rect FilterOperation::MapRect(const gfx::Rect& rect, + const SkMatrix& matrix) const { + switch (type_) { + case FilterOperation::BLUR: { + SkVector spread = MapStdDeviation(amount(), matrix); + gfx::Rect result = rect; + result.Inset(-spread.x(), -spread.y(), -spread.x(), -spread.y()); + return result; + } + case FilterOperation::DROP_SHADOW: { + SkVector spread = MapStdDeviation(amount(), matrix); + gfx::Rect result = rect; + result.Inset(-spread.x(), -spread.y(), -spread.x(), -spread.y()); + result += drop_shadow_offset().OffsetFromOrigin(); + result.Union(rect); + return result; + } + case FilterOperation::REFERENCE: { + if (!image_filter()) + return rect; + SkIRect in_rect = gfx::RectToSkIRect(rect); + SkIRect out_rect = image_filter()->filterBounds( + in_rect, matrix, SkImageFilter::kForward_MapDirection); + return gfx::SkIRectToRect(out_rect); + } + default: + return rect; + } +} + } // namespace cc diff --git a/chromium/cc/output/filter_operation.h b/chromium/cc/output/filter_operation.h index 44590c233ba..8f9c2f027b6 100644 --- a/chromium/cc/output/filter_operation.h +++ b/chromium/cc/output/filter_operation.h @@ -5,10 +5,10 @@ #ifndef CC_OUTPUT_FILTER_OPERATION_H_ #define CC_OUTPUT_FILTER_OPERATION_H_ +#include <memory> + #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" -#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkRegion.h" @@ -22,6 +22,10 @@ class TracedValue; class Value; } +namespace gfx { +class Rect; +} + namespace cc { class CC_EXPORT FilterOperation { @@ -72,7 +76,7 @@ class CC_EXPORT FilterOperation { return drop_shadow_color_; } - skia::RefPtr<SkImageFilter> image_filter() const { + const sk_sp<SkImageFilter>& image_filter() const { DCHECK_EQ(type_, REFERENCE); return image_filter_; } @@ -143,8 +147,8 @@ class CC_EXPORT FilterOperation { } static FilterOperation CreateReferenceFilter( - const skia::RefPtr<SkImageFilter>& image_filter) { - return FilterOperation(REFERENCE, image_filter); + sk_sp<SkImageFilter> image_filter) { + return FilterOperation(REFERENCE, std::move(image_filter)); } static FilterOperation CreateSaturatingBrightnessFilter(float amount) { @@ -192,9 +196,9 @@ class CC_EXPORT FilterOperation { drop_shadow_color_ = color; } - void set_image_filter(const skia::RefPtr<SkImageFilter>& image_filter) { + void set_image_filter(sk_sp<SkImageFilter> image_filter) { DCHECK_EQ(type_, REFERENCE); - image_filter_ = image_filter; + image_filter_ = std::move(image_filter); } void set_matrix(const SkScalar matrix[20]) { @@ -225,6 +229,10 @@ class CC_EXPORT FilterOperation { void AsValueInto(base::trace_event::TracedValue* value) const; + // Maps "forward" to determine which pixels in a destination rect are affected + // by pixels in the source rect. + gfx::Rect MapRect(const gfx::Rect& rect, const SkMatrix& matrix) const; + private: FilterOperation(FilterType type, float amount); @@ -237,8 +245,7 @@ class CC_EXPORT FilterOperation { FilterOperation(FilterType type, float amount, int inset); - FilterOperation(FilterType type, - const skia::RefPtr<SkImageFilter>& image_filter); + FilterOperation(FilterType type, sk_sp<SkImageFilter> image_filter); FilterOperation(FilterType type, const SkRegion& region, @@ -250,7 +257,7 @@ class CC_EXPORT FilterOperation { float outer_threshold_; gfx::Point drop_shadow_offset_; SkColor drop_shadow_color_; - skia::RefPtr<SkImageFilter> image_filter_; + sk_sp<SkImageFilter> image_filter_; SkScalar matrix_[20]; int zoom_inset_; SkRegion region_; diff --git a/chromium/cc/output/filter_operations.cc b/chromium/cc/output/filter_operations.cc index 396e239698a..c5f18dec8d6 100644 --- a/chromium/cc/output/filter_operations.cc +++ b/chromium/cc/output/filter_operations.cc @@ -7,10 +7,12 @@ #include <stddef.h> #include <cmath> +#include <numeric> #include "base/trace_event/trace_event_argument.h" #include "base/values.h" #include "cc/output/filter_operation.h" +#include "ui/gfx/geometry/rect.h" namespace cc { @@ -56,6 +58,16 @@ static int SpreadForStdDeviation(float std_deviation) { return static_cast<int>(ceilf(d * 3.f / 2.f)); } +gfx::Rect FilterOperations::MapRect(const gfx::Rect& rect, + const SkMatrix& matrix) const { + auto accumulate_rect = [matrix](const gfx::Rect& rect, + const FilterOperation& op) { + return op.MapRect(rect, matrix); + }; + return std::accumulate(operations_.begin(), operations_.end(), rect, + accumulate_rect); +} + void FilterOperations::GetOutsets(int* top, int* right, int* bottom, diff --git a/chromium/cc/output/filter_operations.h b/chromium/cc/output/filter_operations.h index 67699692399..589b2f5f5bb 100644 --- a/chromium/cc/output/filter_operations.h +++ b/chromium/cc/output/filter_operations.h @@ -7,10 +7,10 @@ #include <stddef.h> +#include <memory> #include <vector> #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "cc/output/filter_operation.h" namespace base { @@ -20,6 +20,10 @@ class TracedValue; class Value; } +namespace gfx { +class Rect; +} + namespace cc { // An ordered list of filter operations. @@ -46,6 +50,10 @@ class CC_EXPORT FilterOperations { bool IsEmpty() const; + // Maps "forward" to determine which pixels in a destination rect are affected + // by pixels in the source rect. + gfx::Rect MapRect(const gfx::Rect& rect, const SkMatrix& matrix) const; + void GetOutsets(int* top, int* right, int* bottom, int* left) const; bool HasFilterThatMovesPixels() const; bool HasFilterThatAffectsOpacity() const; diff --git a/chromium/cc/output/filter_operations_unittest.cc b/chromium/cc/output/filter_operations_unittest.cc index 05c0289ea9f..a866141858c 100644 --- a/chromium/cc/output/filter_operations_unittest.cc +++ b/chromium/cc/output/filter_operations_unittest.cc @@ -5,11 +5,12 @@ #include <stddef.h> #include "cc/output/filter_operations.h" -#include "skia/ext/refptr.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/effects/SkBlurImageFilter.h" #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" +#include "third_party/skia/include/effects/SkOffsetImageFilter.h" #include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" namespace cc { namespace { @@ -26,16 +27,23 @@ TEST(FilterOperationsTest, GetOutsetsBlur) { EXPECT_EQ(57, left); } +TEST(FilterOperationsTest, MapRectBlur) { + FilterOperations ops; + ops.Append(FilterOperation::CreateBlurFilter(20)); + EXPECT_EQ(gfx::Rect(-60, -60, 130, 130), + ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); +} + TEST(FilterOperationsTest, GetOutsetsDropShadowReferenceFilter) { // TODO(hendrikw): We need to make outsets for reference filters be in line // with non-reference filters. See crbug.com/523534 - skia::RefPtr<SkImageFilter> filter = - skia::AdoptRef(SkDropShadowImageFilter::Create( + FilterOperations ops; + ops.Append( + FilterOperation::CreateReferenceFilter(SkDropShadowImageFilter::Make( SkIntToScalar(3), SkIntToScalar(8), SkIntToScalar(4), SkIntToScalar(9), SK_ColorBLACK, - SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode)); - FilterOperations ops; - ops.Append(FilterOperation::CreateReferenceFilter(filter)); + SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, + nullptr))); int top, right, bottom, left; top = right = bottom = left = 0; @@ -46,6 +54,26 @@ TEST(FilterOperationsTest, GetOutsetsDropShadowReferenceFilter) { EXPECT_EQ(15, left); } +TEST(FilterOperationsTest, MapRectDropShadowReferenceFilter) { + FilterOperations ops; + ops.Append( + FilterOperation::CreateReferenceFilter(SkDropShadowImageFilter::Make( + SkIntToScalar(3), SkIntToScalar(8), SkIntToScalar(4), + SkIntToScalar(9), SK_ColorBLACK, + SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, + nullptr))); + EXPECT_EQ(gfx::Rect(-9, -19, 34, 64), + ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); +} + +TEST(FilterOperationsTest, MapRectOffsetReferenceFilter) { + sk_sp<SkImageFilter> filter = SkOffsetImageFilter::Make(30, 40, nullptr); + FilterOperations ops; + ops.Append(FilterOperation::CreateReferenceFilter(std::move(filter))); + EXPECT_EQ(gfx::Rect(30, 40, 10, 10), + ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); +} + TEST(FilterOperationsTest, GetOutsetsNullReferenceFilter) { FilterOperations ops; ops.Append(FilterOperation::CreateReferenceFilter(nullptr)); @@ -59,6 +87,13 @@ TEST(FilterOperationsTest, GetOutsetsNullReferenceFilter) { EXPECT_EQ(0, left); } +TEST(FilterOperationsTest, MapRectNullReferenceFilter) { + FilterOperations ops; + ops.Append(FilterOperation::CreateReferenceFilter(nullptr)); + EXPECT_EQ(gfx::Rect(0, 0, 10, 10), + ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); +} + TEST(FilterOperationsTest, GetOutsetsDropShadow) { FilterOperations ops; ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 20, 0)); @@ -71,6 +106,13 @@ TEST(FilterOperationsTest, GetOutsetsDropShadow) { EXPECT_EQ(54, left); } +TEST(FilterOperationsTest, MapRectDropShadow) { + FilterOperations ops; + ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 20, 0)); + EXPECT_EQ(gfx::Rect(-57, -52, 130, 130), + ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); +} + #define SAVE_RESTORE_AMOUNT(filter_name, filter_type, a) \ { \ FilterOperation op = FilterOperation::Create##filter_name##Filter(a); \ @@ -541,12 +583,12 @@ TEST(FilterOperationsTest, BlendSaturatingBrightnessWithNull) { } TEST(FilterOperationsTest, BlendReferenceFilters) { - skia::RefPtr<SkImageFilter> from_filter = - skia::AdoptRef(SkBlurImageFilter::Create(1.f, 1.f)); - skia::RefPtr<SkImageFilter> to_filter = - skia::AdoptRef(SkBlurImageFilter::Create(2.f, 2.f)); - FilterOperation from = FilterOperation::CreateReferenceFilter(from_filter); - FilterOperation to = FilterOperation::CreateReferenceFilter(to_filter); + sk_sp<SkImageFilter> from_filter(SkBlurImageFilter::Make(1.f, 1.f, nullptr)); + sk_sp<SkImageFilter> to_filter(SkBlurImageFilter::Make(2.f, 2.f, nullptr)); + FilterOperation from = + FilterOperation::CreateReferenceFilter(std::move(from_filter)); + FilterOperation to = + FilterOperation::CreateReferenceFilter(std::move(to_filter)); FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75); EXPECT_EQ(from, blended); @@ -562,11 +604,10 @@ TEST(FilterOperationsTest, BlendReferenceFilters) { } TEST(FilterOperationsTest, BlendReferenceWithNull) { - skia::RefPtr<SkImageFilter> image_filter = - skia::AdoptRef(SkBlurImageFilter::Create(1.f, 1.f)); - FilterOperation filter = FilterOperation::CreateReferenceFilter(image_filter); - FilterOperation null_filter = - FilterOperation::CreateReferenceFilter(skia::RefPtr<SkImageFilter>()); + sk_sp<SkImageFilter> image_filter(SkBlurImageFilter::Make(1.f, 1.f, nullptr)); + FilterOperation filter = + FilterOperation::CreateReferenceFilter(std::move(image_filter)); + FilterOperation null_filter = FilterOperation::CreateReferenceFilter(nullptr); FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25); EXPECT_EQ(filter, blended); diff --git a/chromium/cc/output/gl_renderer.cc b/chromium/cc/output/gl_renderer.cc index f618cfd6ae9..b9cf3256b6c 100644 --- a/chromium/cc/output/gl_renderer.cc +++ b/chromium/cc/output/gl_renderer.cc @@ -9,13 +9,14 @@ #include <algorithm> #include <limits> +#include <memory> #include <set> #include <string> #include <vector> #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -140,6 +141,16 @@ BlendMode BlendModeFromSkXfermode(SkXfermode::Mode mode) { } } +void RoundUpToPow2(gfx::RectF* rect) { + float w, h; + for (w = 1.f; w < rect->width(); w *= 2.f) { + } + for (h = 1.f; h < rect->height(); h *= 2.f) { + } + rect->set_width(w); + rect->set_height(h); +} + // Smallest unit that impact anti-aliasing output. We use this to // determine when anti-aliasing is unnecessary. const float kAntiAliasingEpsilon = 1.0f / 1024.0f; @@ -158,14 +169,14 @@ static GLint GetActiveTextureUnit(GLES2Interface* gl) { class GLRenderer::ScopedUseGrContext { public: - static scoped_ptr<ScopedUseGrContext> Create(GLRenderer* renderer, - DrawingFrame* frame) { + static std::unique_ptr<ScopedUseGrContext> Create(GLRenderer* renderer, + DrawingFrame* frame) { // GrContext for filters is created lazily, and may fail if the context // is lost. // TODO(vmiura,bsalomon): crbug.com/487850 Ensure that // ContextProvider::GrContext() does not return NULL. if (renderer->output_surface_->context_provider()->GrContext()) - return make_scoped_ptr(new ScopedUseGrContext(renderer, frame)); + return base::WrapUnique(new ScopedUseGrContext(renderer, frame)); return nullptr; } @@ -189,7 +200,7 @@ class GLRenderer::ScopedUseGrContext { // scoped_gpu_raster_ passes context control to Skia. } - scoped_ptr<ScopedGpuRaster> scoped_gpu_raster_; + std::unique_ptr<ScopedGpuRaster> scoped_gpu_raster_; GLRenderer* renderer_; DrawingFrame* frame_; @@ -199,7 +210,7 @@ class GLRenderer::ScopedUseGrContext { struct GLRenderer::PendingAsyncReadPixels { PendingAsyncReadPixels() : buffer(0) {} - scoped_ptr<CopyOutputRequest> copy_request; + std::unique_ptr<CopyOutputRequest> copy_request; base::CancelableClosure finished_read_pixels_callback; unsigned buffer; @@ -299,19 +310,16 @@ class GLRenderer::SyncQuery { DISALLOW_COPY_AND_ASSIGN(SyncQuery); }; -scoped_ptr<GLRenderer> GLRenderer::Create( +std::unique_ptr<GLRenderer> GLRenderer::Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, ResourceProvider* resource_provider, TextureMailboxDeleter* texture_mailbox_deleter, int highp_threshold_min) { - return make_scoped_ptr(new GLRenderer(client, - settings, - output_surface, - resource_provider, - texture_mailbox_deleter, - highp_threshold_min)); + return base::WrapUnique( + new GLRenderer(client, settings, output_surface, resource_provider, + texture_mailbox_deleter, highp_threshold_min)); } GLRenderer::GLRenderer(RendererClient* client, @@ -339,17 +347,17 @@ GLRenderer::GLRenderer(RendererClient* client, DCHECK(gl_); DCHECK(context_support_); - ContextProvider::Capabilities context_caps = + const auto& context_caps = output_surface_->context_provider()->ContextCapabilities(); capabilities_.using_partial_swap = - settings_->partial_swap_enabled && context_caps.gpu.post_sub_buffer; - capabilities_.allow_empty_swap = capabilities_.using_partial_swap || - context_caps.gpu.commit_overlay_planes; + settings_->partial_swap_enabled && context_caps.post_sub_buffer; + capabilities_.allow_empty_swap = + capabilities_.using_partial_swap || context_caps.commit_overlay_planes; - DCHECK(!context_caps.gpu.iosurface || context_caps.gpu.texture_rectangle); + DCHECK(!context_caps.iosurface || context_caps.texture_rectangle); - capabilities_.using_egl_image = context_caps.gpu.egl_image_external; + capabilities_.using_egl_image = context_caps.egl_image_external; capabilities_.max_texture_size = resource_provider_->max_texture_size(); capabilities_.best_texture_format = resource_provider_->best_texture_format(); @@ -357,24 +365,23 @@ GLRenderer::GLRenderer(RendererClient* client, // The updater can access textures while the GLRenderer is using them. capabilities_.allow_partial_texture_updates = true; - capabilities_.using_image = context_caps.gpu.image; + capabilities_.using_image = context_caps.image; - capabilities_.using_discard_framebuffer = - context_caps.gpu.discard_framebuffer; + capabilities_.using_discard_framebuffer = context_caps.discard_framebuffer; capabilities_.allow_rasterize_on_demand = true; // If MSAA is slow, we want this renderer to behave as though MSAA is not // available. Set samples to 0 to achieve this. - if (context_caps.gpu.msaa_is_slow) + if (context_caps.msaa_is_slow) capabilities_.max_msaa_samples = 0; else - capabilities_.max_msaa_samples = context_caps.gpu.max_samples; + capabilities_.max_msaa_samples = context_caps.max_samples; - use_sync_query_ = context_caps.gpu.sync_query; - use_blend_equation_advanced_ = context_caps.gpu.blend_equation_advanced; + use_sync_query_ = context_caps.sync_query; + use_blend_equation_advanced_ = context_caps.blend_equation_advanced; use_blend_equation_advanced_coherent_ = - context_caps.gpu.blend_equation_advanced_coherent; + context_caps.blend_equation_advanced_coherent; InitializeSharedObjects(); } @@ -480,7 +487,7 @@ void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { } current_sync_query_ = available_sync_queries_.empty() - ? make_scoped_ptr(new SyncQuery(gl_)) + ? base::WrapUnique(new SyncQuery(gl_)) : PopFront(&available_sync_queries_); read_lock_fence = current_sync_query_->Begin(); @@ -519,10 +526,6 @@ void GLRenderer::DoDrawQuad(DrawingFrame* frame, case DrawQuad::DEBUG_BORDER: DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad)); break; - case DrawQuad::IO_SURFACE_CONTENT: - DrawIOSurfaceQuad(frame, IOSurfaceDrawQuad::MaterialCast(quad), - clip_region); - break; case DrawQuad::PICTURE_CONTENT: // PictureDrawQuad should only be used for resourceless software draws. NOTREACHED(); @@ -597,19 +600,19 @@ void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame, gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0); } -static skia::RefPtr<SkImage> ApplyImageFilter( - scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, +static sk_sp<SkImage> ApplyImageFilter( + std::unique_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, ResourceProvider* resource_provider, const gfx::RectF& src_rect, const gfx::RectF& dst_rect, const gfx::Vector2dF& scale, - SkImageFilter* filter, + sk_sp<SkImageFilter> filter, ScopedResource* source_texture_resource) { if (!filter) - return skia::RefPtr<SkImage>(); + return nullptr; if (!use_gr_context) - return skia::RefPtr<SkImage>(); + return nullptr; ResourceProvider::ScopedReadLockGL lock(resource_provider, source_texture_resource->id()); @@ -627,13 +630,13 @@ static skia::RefPtr<SkImage> ApplyImageFilter( skia::GrGLTextureInfoToGrBackendObject(texture_info); backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin; - skia::RefPtr<SkImage> srcImage = skia::AdoptRef(SkImage::NewFromTexture( - use_gr_context->context(), backend_texture_description)); - if (!srcImage.get()) { + sk_sp<SkImage> src_image = SkImage::MakeFromTexture( + use_gr_context->context(), backend_texture_description); + if (!src_image) { TRACE_EVENT_INSTANT0("cc", "ApplyImageFilter wrap background texture failed", TRACE_EVENT_SCOPE_THREAD); - return skia::RefPtr<SkImage>(); + return nullptr; } // Create surface to draw into. @@ -644,7 +647,7 @@ static skia::RefPtr<SkImage> ApplyImageFilter( if (!surface) { TRACE_EVENT_INSTANT0("cc", "ApplyImageFilter surface allocation failed", TRACE_EVENT_SCOPE_THREAD); - return skia::RefPtr<SkImage>(); + return nullptr; } SkMatrix local_matrix; @@ -653,16 +656,16 @@ static skia::RefPtr<SkImage> ApplyImageFilter( SkPaint paint; paint.setImageFilter(filter->makeWithLocalMatrix(local_matrix)); surface->getCanvas()->translate(-dst_rect.x(), -dst_rect.y()); - surface->getCanvas()->drawImage(srcImage.get(), src_rect.x(), src_rect.y(), + surface->getCanvas()->drawImage(src_image, src_rect.x(), src_rect.y(), &paint); // Flush the drawing before source texture read lock goes out of scope. // Skia API does not guarantee that when the SkImage goes out of scope, // its externally referenced resources would force the rendering to be // flushed. surface->getCanvas()->flush(); - skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot()); + sk_sp<SkImage> image = surface->makeImageSnapshot(); if (!image || !image->isTextureBacked()) { - return skia::RefPtr<SkImage>(); + return nullptr; } CHECK(image->isTextureBacked()); @@ -835,9 +838,9 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad( return backdrop_rect; } -scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture( +std::unique_ptr<ScopedResource> GLRenderer::GetBackdropTexture( const gfx::Rect& bounding_rect) { - scoped_ptr<ScopedResource> device_background_texture = + std::unique_ptr<ScopedResource> device_background_texture = ScopedResource::Create(resource_provider_); // CopyTexImage2D fails when called on a texture having immutable storage. device_background_texture->Allocate( @@ -851,18 +854,18 @@ scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture( return device_background_texture; } -skia::RefPtr<SkImage> GLRenderer::ApplyBackgroundFilters( +sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters( DrawingFrame* frame, const RenderPassDrawQuad* quad, ScopedResource* background_texture, const gfx::RectF& rect) { DCHECK(ShouldApplyBackgroundFilters(quad)); - skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( + sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( quad->background_filters, gfx::SizeF(background_texture->size())); - skia::RefPtr<SkImage> background_with_filters = ApplyImageFilter( + sk_sp<SkImage> background_with_filters = ApplyImageFilter( ScopedUseGrContext::Create(this, frame), resource_provider_, rect, rect, - quad->filters_scale, filter.get(), background_texture); + quad->filters_scale, std::move(filter), background_texture); return background_with_filters; } @@ -892,10 +895,13 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, DCHECK(contents_texture); DCHECK(contents_texture->id()); + SkMatrix scale_matrix; + scale_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); + gfx::RectF dst_rect(quad->filters.MapRect(quad->rect, scale_matrix)); gfx::Transform quad_rect_matrix; QuadRectTransform(&quad_rect_matrix, quad->shared_quad_state->quad_to_target_transform, - gfx::RectF(quad->rect)); + dst_rect); gfx::Transform contents_device_transform = frame->window_matrix * frame->projection_matrix * quad_rect_matrix; contents_device_transform.FlattenTo2d(); @@ -927,8 +933,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, ShouldApplyBackgroundFilters(quad) || settings_->force_blending_with_shaders; - scoped_ptr<ScopedResource> background_texture; - skia::RefPtr<SkImage> background_image; + std::unique_ptr<ScopedResource> background_texture; + sk_sp<SkImage> background_image; GLuint background_image_id = 0; gfx::Rect background_rect; if (use_shaders_for_blending) { @@ -988,31 +994,27 @@ 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; + sk_sp<SkImage> filter_image; GLuint filter_image_id = 0; SkScalar color_matrix[20]; bool use_color_matrix = false; gfx::RectF rect = gfx::RectF(quad->rect); if (!quad->filters.IsEmpty()) { - skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( + sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( quad->filters, gfx::SizeF(contents_texture->size())); if (filter) { SkColorFilter* colorfilter_rawptr = NULL; filter->asColorFilter(&colorfilter_rawptr); sk_sp<SkColorFilter> cf(colorfilter_rawptr); - if (cf && cf->asColorMatrix(color_matrix) && !filter->getInput(0)) { - // We have a single color matrix as a filter; apply it locally - // in the compositor. + if (cf && cf->asColorMatrix(color_matrix)) { + // We have a color matrix at the root of the filter DAG; apply it + // locally in the compositor and process the rest of the DAG (if any) + // in Skia. use_color_matrix = true; - } else { - gfx::Vector2dF scale = quad->filters_scale; - SkMatrix scale_matrix; - scale_matrix.setScale(scale.x(), scale.y()); - SkIRect result_rect = - filter->filterBounds(gfx::RectToSkIRect(quad->rect), scale_matrix, - SkImageFilter::kForward_MapDirection); - gfx::RectF dst_rect = gfx::SkRectToRectF(SkRect::Make(result_rect)); + filter = sk_ref_sp(filter->getInput(0)); + } + if (filter) { gfx::Rect clip_rect = quad->shared_quad_state->clip_rect; if (clip_rect.IsEmpty()) { clip_rect = current_draw_rect_; @@ -1027,21 +1029,24 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, if (dst_rect.IsEmpty()) { return; } - filter_image = ApplyImageFilter(ScopedUseGrContext::Create(this, frame), - resource_provider_, rect, dst_rect, - scale, filter.get(), contents_texture); - if (filter_image) { - filter_image_id = skia::GrBackendObjectToGrGLTextureInfo( - filter_image->getTextureHandle(true)) - ->fID; - DCHECK(filter_image_id); - rect = dst_rect; + // Expand dst_rect size to the nearest power of 2, in order to get + // more cache hits in Skia's texture cache. + RoundUpToPow2(&dst_rect); + filter_image = ApplyImageFilter( + ScopedUseGrContext::Create(this, frame), resource_provider_, rect, + dst_rect, quad->filters_scale, std::move(filter), contents_texture); + if (!filter_image) { + return; } + filter_image_id = skia::GrBackendObjectToGrGLTextureInfo( + filter_image->getTextureHandle(true)) + ->fID; + DCHECK(filter_image_id); } } } - scoped_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock; + std::unique_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock; unsigned mask_texture_id = 0; SamplerType mask_sampler = SAMPLER_TYPE_NA; if (quad->mask_resource_id()) { @@ -1051,13 +1056,15 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, mask_sampler = SamplerTypeFromTextureTarget(mask_resource_lock->target()); } - scoped_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock; + std::unique_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock; if (filter_image_id) { DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_)); gl_->BindTexture(GL_TEXTURE_2D, filter_image_id); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { contents_resource_lock = - make_scoped_ptr(new ResourceProvider::ScopedSamplerGL( + base::WrapUnique(new ResourceProvider::ScopedSamplerGL( resource_provider_, contents_texture->id(), GL_LINEAR)); DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), contents_resource_lock->target()); @@ -1220,7 +1227,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, gl_->Uniform4fv(locations.color_offset, 1, offset); } - scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_background_sampler_lock; + std::unique_ptr<ResourceProvider::ScopedSamplerGL> + shader_background_sampler_lock; if (locations.backdrop != -1) { DCHECK(background_texture || background_image_id); DCHECK_NE(locations.backdrop, 0); @@ -1240,11 +1248,10 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, gl_->Uniform1i(locations.original_backdrop, ++last_texture_unit); } if (background_texture) { - shader_background_sampler_lock = make_scoped_ptr( - new ResourceProvider::ScopedSamplerGL(resource_provider_, - background_texture->id(), - GL_TEXTURE0 + last_texture_unit, - GL_LINEAR)); + shader_background_sampler_lock = + base::WrapUnique(new ResourceProvider::ScopedSamplerGL( + resource_provider_, background_texture->id(), + GL_TEXTURE0 + last_texture_unit, GL_LINEAR)); DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), shader_background_sampler_lock->target()); } @@ -1253,7 +1260,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, SetShaderOpacity(quad->shared_quad_state->opacity, locations.alpha); SetShaderQuadF(surface_quad, locations.quad); DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform, - rect, locations.matrix); + dst_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. @@ -1959,16 +1966,24 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, quad->shared_quad_state->visible_quad_layer_rect.bottom_right()); bool use_alpha_plane = quad->a_plane_resource_id() != 0; + bool use_nv12 = quad->v_plane_resource_id() == quad->u_plane_resource_id(); + + DCHECK(!(use_nv12 && use_alpha_plane)); ResourceProvider::ScopedSamplerGL y_plane_lock( 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); 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); - DCHECK_EQ(y_plane_lock.target(), v_plane_lock.target()); - scoped_ptr<ResourceProvider::ScopedSamplerGL> a_plane_lock; + // TODO(jbauman): Use base::Optional when available. + std::unique_ptr<ResourceProvider::ScopedSamplerGL> v_plane_lock; + if (!use_nv12) { + v_plane_lock.reset(new ResourceProvider::ScopedSamplerGL( + resource_provider_, quad->v_plane_resource_id(), GL_TEXTURE3, + GL_LINEAR)); + DCHECK_EQ(y_plane_lock.target(), v_plane_lock->target()); + } + std::unique_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, @@ -2014,7 +2029,7 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, uv_clamp_rect_location = program->fragment_shader().uv_clamp_rect_location(); alpha_location = program->fragment_shader().alpha_location(); - } else { + } else if (!use_nv12) { const VideoYUVProgram* program = GetVideoYUVProgram(tex_coord_precision, sampler); DCHECK(program && (program->initialized() || IsContextLost())); @@ -2034,6 +2049,25 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, uv_clamp_rect_location = program->fragment_shader().uv_clamp_rect_location(); alpha_location = program->fragment_shader().alpha_location(); + } else { + const VideoNV12Program* program = + GetVideoNV12Program(tex_coord_precision, sampler); + DCHECK(program && (program->initialized() || IsContextLost())); + SetUseProgram(program->program()); + matrix_location = program->vertex_shader().matrix_location(); + ya_tex_scale_location = program->vertex_shader().ya_tex_scale_location(); + ya_tex_offset_location = program->vertex_shader().ya_tex_offset_location(); + uv_tex_scale_location = program->vertex_shader().uv_tex_scale_location(); + uv_tex_offset_location = program->vertex_shader().uv_tex_offset_location(); + y_texture_location = program->fragment_shader().y_texture_location(); + u_texture_location = program->fragment_shader().uv_texture_location(); + yuv_matrix_location = program->fragment_shader().yuv_matrix_location(); + yuv_adj_location = program->fragment_shader().yuv_adj_location(); + ya_clamp_rect_location = + program->fragment_shader().ya_clamp_rect_location(); + uv_clamp_rect_location = + program->fragment_shader().uv_clamp_rect_location(); + alpha_location = program->fragment_shader().alpha_location(); } gfx::SizeF ya_tex_scale(1.0f, 1.0f); @@ -2089,7 +2123,8 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, gl_->Uniform1i(y_texture_location, 1); gl_->Uniform1i(u_texture_location, 2); - gl_->Uniform1i(v_texture_location, 3); + if (!use_nv12) + gl_->Uniform1i(v_texture_location, 3); if (use_alpha_plane) gl_->Uniform1i(a_texture_location, 4); @@ -2441,55 +2476,6 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, } } -void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame, - const IOSurfaceDrawQuad* quad, - const gfx::QuadF* clip_region) { - SetBlendEnabled(quad->ShouldDrawWithBlending()); - - TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( - 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)); - - SetUseProgram(binding.program_id); - gl_->Uniform1i(binding.sampler_location, 0); - if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) { - gl_->Uniform4f( - binding.tex_transform_location, 0, quad->io_surface_size.height(), - quad->io_surface_size.width(), quad->io_surface_size.height() * -1.0f); - } else { - gl_->Uniform4f(binding.tex_transform_location, 0, 0, - quad->io_surface_size.width(), - quad->io_surface_size.height()); - } - - 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()); - DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_)); - gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, lock.texture_id()); - - if (!clip_region) { - DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform, - gfx::RectF(quad->rect), binding.matrix_location); - } else { - float uvs[8] = {0}; - GetScaledUVs(quad->visible_rect, clip_region, uvs); - DrawQuadGeometryClippedByQuadF( - frame, quad->shared_quad_state->quad_to_target_transform, - gfx::RectF(quad->rect), *clip_region, binding.matrix_location, uvs); - } - - gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); -} - void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) { if (use_sync_query_) { DCHECK(current_sync_query_); @@ -2542,7 +2528,7 @@ void GLRenderer::EnsureScissorTestDisabled() { void GLRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - scoped_ptr<CopyOutputRequest> request) { + std::unique_ptr<CopyOutputRequest> request) { TRACE_EVENT0("cc", "GLRenderer::CopyCurrentRenderPassToBitmap"); gfx::Rect copy_rect = frame->current_render_pass->output_rect; if (request->has_area()) @@ -2656,7 +2642,7 @@ void GLRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) { CompositorFrame compositor_frame; compositor_frame.metadata = metadata; - compositor_frame.gl_frame_data = make_scoped_ptr(new GLFrameData); + compositor_frame.gl_frame_data = base::WrapUnique(new GLFrameData); compositor_frame.gl_frame_data->size = surface_size; if (capabilities_.using_partial_swap) { // If supported, we can save significant bandwidth by only swapping the @@ -2732,7 +2718,7 @@ void GLRenderer::EnsureBackbuffer() { void GLRenderer::GetFramebufferPixelsAsync( const DrawingFrame* frame, const gfx::Rect& rect, - scoped_ptr<CopyOutputRequest> request) { + std::unique_ptr<CopyOutputRequest> request) { DCHECK(!request->IsEmpty()); if (request->IsEmpty()) return; @@ -2783,7 +2769,7 @@ void GLRenderer::GetFramebufferPixelsAsync( TextureMailbox texture_mailbox(mailbox, sync_token, GL_TEXTURE_2D); - scoped_ptr<SingleReleaseCallback> release_callback; + std::unique_ptr<SingleReleaseCallback> release_callback; if (own_mailbox) { gl_->BindTexture(GL_TEXTURE_2D, 0); release_callback = texture_mailbox_deleter_->GetReleaseCallback( @@ -2799,7 +2785,8 @@ void GLRenderer::GetFramebufferPixelsAsync( DCHECK(request->force_bitmap_result()); - scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels); + std::unique_ptr<PendingAsyncReadPixels> pending_read( + new PendingAsyncReadPixels); pending_read->copy_request = std::move(request); pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), std::move(pending_read)); @@ -2863,7 +2850,7 @@ void GLRenderer::FinishedReadback(unsigned source_buffer, PendingAsyncReadPixels* current_read = iter->get(); uint8_t* src_pixels = NULL; - scoped_ptr<SkBitmap> bitmap; + std::unique_ptr<SkBitmap> bitmap; if (source_buffer != 0) { gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, source_buffer); @@ -2873,7 +2860,7 @@ void GLRenderer::FinishedReadback(unsigned source_buffer, if (src_pixels) { bitmap.reset(new SkBitmap); bitmap->allocN32Pixels(size.width(), size.height()); - scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap)); + std::unique_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap)); uint8_t* dest_pixels = static_cast<uint8_t*>(bitmap->getPixels()); size_t row_bytes = size.width() * 4; @@ -2950,7 +2937,7 @@ bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame, SetStencilEnabled(false); gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_); current_framebuffer_lock_ = - make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL( + base::WrapUnique(new ResourceProvider::ScopedWriteLockGL( resource_provider_, texture->id())); unsigned texture_id = current_framebuffer_lock_->texture_id(); gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, @@ -2992,8 +2979,8 @@ void GLRenderer::InitializeSharedObjects() { gl_->GenFramebuffers(1, &offscreen_framebuffer_id_); shared_geometry_ = - make_scoped_ptr(new StaticGeometryBinding(gl_, QuadVertexRect())); - clipped_geometry_ = make_scoped_ptr(new DynamicGeometryBinding(gl_)); + base::WrapUnique(new StaticGeometryBinding(gl_, QuadVertexRect())); + clipped_geometry_ = base::WrapUnique(new DynamicGeometryBinding(gl_)); } void GLRenderer::PrepareGeometry(BoundGeometry binding) { @@ -3372,29 +3359,32 @@ GLRenderer::GetNonPremultipliedTextureBackgroundProgram( return program; } -const GLRenderer::TextureProgram* GLRenderer::GetTextureIOSurfaceProgram( - TexCoordPrecision precision) { +const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram( + TexCoordPrecision precision, + SamplerType sampler) { DCHECK_GE(precision, 0); DCHECK_LE(precision, LAST_TEX_COORD_PRECISION); - TextureProgram* program = &texture_io_surface_program_[precision]; + DCHECK_GE(sampler, 0); + DCHECK_LE(sampler, LAST_SAMPLER_TYPE); + VideoYUVProgram* program = &video_yuv_program_[precision][sampler]; if (!program->initialized()) { - TRACE_EVENT0("cc", "GLRenderer::textureIOSurfaceProgram::initialize"); + TRACE_EVENT0("cc", "GLRenderer::videoYUVProgram::initialize"); program->Initialize(output_surface_->context_provider(), precision, - SAMPLER_TYPE_2D_RECT); + sampler); } return program; } -const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram( +const GLRenderer::VideoNV12Program* GLRenderer::GetVideoNV12Program( TexCoordPrecision precision, SamplerType sampler) { DCHECK_GE(precision, 0); DCHECK_LE(precision, LAST_TEX_COORD_PRECISION); DCHECK_GE(sampler, 0); DCHECK_LE(sampler, LAST_SAMPLER_TYPE); - VideoYUVProgram* program = &video_yuv_program_[precision][sampler]; + VideoNV12Program* program = &video_nv12_program_[precision][sampler]; if (!program->initialized()) { - TRACE_EVENT0("cc", "GLRenderer::videoYUVProgram::initialize"); + TRACE_EVENT0("cc", "GLRenderer::videoNV12Program::initialize"); program->Initialize(output_surface_->context_provider(), precision, sampler); } @@ -3454,6 +3444,7 @@ void GLRenderer::CleanupSharedObjects() { video_yuv_program_[i][j].Cleanup(gl_); video_yuva_program_[i][j].Cleanup(gl_); + video_nv12_program_[i][j].Cleanup(gl_); } for (int j = 0; j <= LAST_BLEND_MODE; j++) { render_pass_program_[i][j].Cleanup(gl_); @@ -3468,7 +3459,6 @@ void GLRenderer::CleanupSharedObjects() { texture_background_program_[i][j].Cleanup(gl_); nonpremultiplied_texture_background_program_[i][j].Cleanup(gl_); } - texture_io_surface_program_[i].Cleanup(gl_); video_stream_texture_program_[i].Cleanup(gl_); } @@ -3547,7 +3537,7 @@ void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { unsigned texture_id = 0; if (ca_layer_overlay.contents_resource_id) { pending_overlay_resources_.push_back( - make_scoped_ptr(new ResourceProvider::ScopedReadLockGL( + base::WrapUnique(new ResourceProvider::ScopedReadLockGL( resource_provider_, ca_layer_overlay.contents_resource_id))); texture_id = pending_overlay_resources_.back()->texture_id(); } @@ -3569,10 +3559,12 @@ void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { GLint sorting_context_id = ca_layer_overlay.sorting_context_id; GLfloat transform[16]; ca_layer_overlay.transform.asColMajorf(transform); + unsigned filter = GL_LINEAR; gl_->ScheduleCALayerCHROMIUM( texture_id, contents_rect, ca_layer_overlay.opacity, ca_layer_overlay.background_color, ca_layer_overlay.edge_aa_mask, - bounds_rect, is_clipped, clip_rect, sorting_context_id, transform); + bounds_rect, is_clipped, clip_rect, sorting_context_id, transform, + filter); } } @@ -3588,7 +3580,7 @@ void GLRenderer::ScheduleOverlays(DrawingFrame* frame) { DCHECK(texture_id || IsContextLost()); } else { pending_overlay_resources_.push_back( - make_scoped_ptr(new ResourceProvider::ScopedReadLockGL( + base::WrapUnique(new ResourceProvider::ScopedReadLockGL( resource_provider_, overlay.resource_id))); texture_id = pending_overlay_resources_.back()->texture_id(); } diff --git a/chromium/cc/output/gl_renderer.h b/chromium/cc/output/gl_renderer.h index 321c2377d49..51135d7d18b 100644 --- a/chromium/cc/output/gl_renderer.h +++ b/chromium/cc/output/gl_renderer.h @@ -16,7 +16,6 @@ #include "cc/output/program_binding.h" #include "cc/output/renderer.h" #include "cc/quads/debug_border_draw_quad.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/tile_draw_quad.h" @@ -49,7 +48,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer { public: class ScopedUseGrContext; - static scoped_ptr<GLRenderer> Create( + static std::unique_ptr<GLRenderer> Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, @@ -88,7 +87,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer { void GetFramebufferPixelsAsync(const DrawingFrame* frame, const gfx::Rect& rect, - scoped_ptr<CopyOutputRequest> request); + std::unique_ptr<CopyOutputRequest> request); void GetFramebufferTexture(unsigned texture_id, ResourceFormat texture_format, const gfx::Rect& device_rect); @@ -118,7 +117,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer { void EnsureScissorTestDisabled() override; void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - scoped_ptr<CopyOutputRequest> request) override; + std::unique_ptr<CopyOutputRequest> request) override; void FinishDrawingQuadList() override; // Returns true if quad requires antialiasing and false otherwise. @@ -169,14 +168,14 @@ class CC_EXPORT GLRenderer : public DirectRenderer { const gfx::Transform& contents_device_transform, const gfx::QuadF* clip_region, bool use_aa); - scoped_ptr<ScopedResource> GetBackdropTexture(const gfx::Rect& bounding_rect); + std::unique_ptr<ScopedResource> GetBackdropTexture( + const gfx::Rect& bounding_rect); static bool ShouldApplyBackgroundFilters(const RenderPassDrawQuad* quad); - skia::RefPtr<SkImage> ApplyBackgroundFilters( - DrawingFrame* frame, - const RenderPassDrawQuad* quad, - ScopedResource* background_texture, - const gfx::RectF& rect); + sk_sp<SkImage> ApplyBackgroundFilters(DrawingFrame* frame, + const RenderPassDrawQuad* quad, + ScopedResource* background_texture, + const gfx::RectF& rect); void DrawRenderPassQuad(DrawingFrame* frame, const RenderPassDrawQuad* quadi, @@ -194,9 +193,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer { const TextureDrawQuad* quad, const gfx::QuadF* clip_region); void FlushTextureQuadCache(BoundGeometry flush_binding); - void DrawIOSurfaceQuad(const DrawingFrame* frame, - const IOSurfaceDrawQuad* quad, - const gfx::QuadF* clip_region); void DrawTileQuad(const DrawingFrame* frame, const TileDrawQuad* quad, const gfx::QuadF* clip_region); @@ -240,7 +236,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer { void InitializeSharedObjects(); void CleanupSharedObjects(); - typedef base::Callback<void(scoped_ptr<CopyOutputRequest> copy_request, + typedef base::Callback<void(std::unique_ptr<CopyOutputRequest> copy_request, bool success)> AsyncGetFramebufferPixelsCleanupCallback; void FinishedReadback(unsigned source_buffer, @@ -259,7 +255,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer { void ScheduleOverlays(DrawingFrame* frame); using OverlayResourceLockList = - std::vector<scoped_ptr<ResourceProvider::ScopedReadLockGL>>; + std::vector<std::unique_ptr<ResourceProvider::ScopedReadLockGL>>; OverlayResourceLockList pending_overlay_resources_; std::deque<OverlayResourceLockList> swapped_overlay_resources_; @@ -267,8 +263,8 @@ class CC_EXPORT GLRenderer : public DirectRenderer { unsigned offscreen_framebuffer_id_; - scoped_ptr<StaticGeometryBinding> shared_geometry_; - scoped_ptr<DynamicGeometryBinding> clipped_geometry_; + std::unique_ptr<StaticGeometryBinding> shared_geometry_; + std::unique_ptr<DynamicGeometryBinding> clipped_geometry_; gfx::QuadF shared_geometry_quad_; // This block of bindings defines all of the programs used by the compositor @@ -331,7 +327,11 @@ class CC_EXPORT GLRenderer : public DirectRenderer { typedef ProgramBinding<VertexShaderPosTexYUVStretchOffset, FragmentShaderYUVVideo> VideoYUVProgram; typedef ProgramBinding<VertexShaderPosTexYUVStretchOffset, - FragmentShaderYUVAVideo> VideoYUVAProgram; + FragmentShaderNV12Video> + VideoNV12Program; + typedef ProgramBinding<VertexShaderPosTexYUVStretchOffset, + FragmentShaderYUVAVideo> + VideoYUVAProgram; // Special purpose / effects shaders. typedef ProgramBinding<VertexShaderPos, FragmentShaderColor> @@ -396,11 +396,11 @@ class CC_EXPORT GLRenderer : public DirectRenderer { const NonPremultipliedTextureBackgroundProgram* GetNonPremultipliedTextureBackgroundProgram(TexCoordPrecision precision, SamplerType sampler); - const TextureProgram* GetTextureIOSurfaceProgram( - TexCoordPrecision precision); const VideoYUVProgram* GetVideoYUVProgram(TexCoordPrecision precision, SamplerType sampler); + const VideoNV12Program* GetVideoNV12Program(TexCoordPrecision precision, + SamplerType sampler); const VideoYUVAProgram* GetVideoYUVAProgram(TexCoordPrecision precision, SamplerType sampler); const VideoStreamTextureProgram* GetVideoStreamTextureProgram( @@ -435,7 +435,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer { NonPremultipliedTextureBackgroundProgram nonpremultiplied_texture_background_program_[LAST_TEX_COORD_PRECISION + 1][LAST_SAMPLER_TYPE + 1]; - TextureProgram texture_io_surface_program_[LAST_TEX_COORD_PRECISION + 1]; RenderPassProgram render_pass_program_[LAST_TEX_COORD_PRECISION + 1][LAST_BLEND_MODE + 1]; @@ -470,6 +469,8 @@ class CC_EXPORT GLRenderer : public DirectRenderer { VideoYUVProgram video_yuv_program_[LAST_TEX_COORD_PRECISION + 1][LAST_SAMPLER_TYPE + 1]; + VideoNV12Program video_nv12_program_[LAST_TEX_COORD_PRECISION + 1] + [LAST_SAMPLER_TYPE + 1]; VideoYUVAProgram video_yuva_program_[LAST_TEX_COORD_PRECISION + 1][LAST_SAMPLER_TYPE + 1]; VideoStreamTextureProgram @@ -498,14 +499,16 @@ class CC_EXPORT GLRenderer : public DirectRenderer { int highp_threshold_cache_; struct PendingAsyncReadPixels; - std::vector<scoped_ptr<PendingAsyncReadPixels>> pending_async_read_pixels_; + std::vector<std::unique_ptr<PendingAsyncReadPixels>> + pending_async_read_pixels_; - scoped_ptr<ResourceProvider::ScopedWriteLockGL> current_framebuffer_lock_; + std::unique_ptr<ResourceProvider::ScopedWriteLockGL> + current_framebuffer_lock_; class SyncQuery; - std::deque<scoped_ptr<SyncQuery>> pending_sync_queries_; - std::deque<scoped_ptr<SyncQuery>> available_sync_queries_; - scoped_ptr<SyncQuery> current_sync_query_; + std::deque<std::unique_ptr<SyncQuery>> pending_sync_queries_; + std::deque<std::unique_ptr<SyncQuery>> available_sync_queries_; + std::unique_ptr<SyncQuery> current_sync_query_; bool use_sync_query_; bool use_blend_equation_advanced_; bool use_blend_equation_advanced_coherent_; diff --git a/chromium/cc/output/gl_renderer_unittest.cc b/chromium/cc/output/gl_renderer_unittest.cc index ba7ac390de2..04f5762c28f 100644 --- a/chromium/cc/output/gl_renderer_unittest.cc +++ b/chromium/cc/output/gl_renderer_unittest.cc @@ -9,8 +9,8 @@ #include <set> #include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/base/math_util.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/output/copy_output_request.h" @@ -133,7 +133,6 @@ class GLRendererShaderPixelTest : public GLRendererPixelTest { } void TestShadersWithPrecision(TexCoordPrecision precision) { - EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision)); // This program uses external textures and sampler, so it won't compile // everywhere. if (renderer()->Capabilities().using_egl_image) @@ -174,6 +173,7 @@ class GLRendererShaderPixelTest : public GLRendererPixelTest { EXPECT_PROGRAM_VALID( renderer()->GetTileProgramSwizzleAA(precision, sampler)); EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision, sampler)); + EXPECT_PROGRAM_VALID(renderer()->GetVideoNV12Program(precision, sampler)); EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision, sampler)); } @@ -346,21 +346,20 @@ class GLRendererWithDefaultHarnessTest : public GLRendererTest { shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = FakeResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get()); - renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_, - &settings_, - output_surface_.get(), - resource_provider_.get())); + renderer_ = base::WrapUnique( + new FakeRendererGL(&renderer_client_, &settings_, output_surface_.get(), + resource_provider_.get())); } void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); } RendererSettings settings_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> output_surface_; + std::unique_ptr<FakeOutputSurface> output_surface_; FakeRendererClient renderer_client_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<FakeRendererGL> renderer_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<FakeRendererGL> renderer_; }; // Closing the namespace here so that GLRendererShaderTest can take advantage @@ -478,11 +477,11 @@ class GLRendererShaderTest : public GLRendererTest { RendererSettings settings_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> output_surface_; + std::unique_ptr<FakeOutputSurface> output_surface_; FakeRendererClient renderer_client_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<FakeRendererGL> renderer_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<FakeRendererGL> renderer_; }; namespace { @@ -667,14 +666,16 @@ class ForbidSynchronousCallContext : public TestWebGraphicsContext3D { }; TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) { FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext))); + std::unique_ptr<OutputSurface> output_surface( + FakeOutputSurface::Create3d(std::unique_ptr<TestWebGraphicsContext3D>( + new ForbidSynchronousCallContext))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -701,14 +702,16 @@ class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D { TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) { FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext))); + std::unique_ptr<OutputSurface> output_surface( + FakeOutputSurface::Create3d(std::unique_ptr<TestWebGraphicsContext3D>( + new LoseContextOnFirstGetContext))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -720,7 +723,7 @@ TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) { class ClearCountingContext : public TestWebGraphicsContext3D { public: - ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; } + ClearCountingContext() { test_capabilities_.discard_framebuffer = true; } MOCK_METHOD3(discardFramebufferEXT, void(GLenum target, @@ -730,18 +733,19 @@ class ClearCountingContext : public TestWebGraphicsContext3D { }; TEST_F(GLRendererTest, OpaqueBackground) { - scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext); + std::unique_ptr<ClearCountingContext> context_owned(new ClearCountingContext); ClearCountingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -775,18 +779,19 @@ TEST_F(GLRendererTest, OpaqueBackground) { } TEST_F(GLRendererTest, TransparentBackground) { - scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext); + std::unique_ptr<ClearCountingContext> context_owned(new ClearCountingContext); ClearCountingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -813,18 +818,19 @@ TEST_F(GLRendererTest, TransparentBackground) { } TEST_F(GLRendererTest, OffscreenOutputSurface) { - scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext); + std::unique_ptr<ClearCountingContext> context_owned(new ClearCountingContext); ClearCountingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::CreateOffscreen(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -854,7 +860,7 @@ TEST_F(GLRendererTest, OffscreenOutputSurface) { class TextureStateTrackingContext : public TestWebGraphicsContext3D { public: TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) { - test_capabilities_.gpu.egl_image_external = true; + test_capabilities_.egl_image_external = true; } MOCK_METHOD1(waitSyncToken, void(const GLbyte* sync_token)); @@ -874,19 +880,20 @@ class TextureStateTrackingContext : public TestWebGraphicsContext3D { }; TEST_F(GLRendererTest, ActiveTextureState) { - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -939,7 +946,7 @@ TEST_F(GLRendererTest, ActiveTextureState) { // The remaining quads also use GL_LINEAR because nearest neighbor // filtering is currently only used with tile quads. - EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6); + EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(5); } gfx::Rect viewport_rect(100, 100); @@ -959,19 +966,20 @@ class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D { }; TEST_F(GLRendererTest, ShouldClearRootRenderPass) { - scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned( + std::unique_ptr<NoClearRootRenderPassMockContext> mock_context_owned( new NoClearRootRenderPassMockContext); NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(mock_context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; settings.should_clear_root_render_pass = false; @@ -1051,18 +1059,19 @@ class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D { }; TEST_F(GLRendererTest, ScissorTestWhenClearing) { - scoped_ptr<ScissorTestOnClearCheckingContext> context_owned( + std::unique_ptr<ScissorTestOnClearCheckingContext> context_owned( new ScissorTestOnClearCheckingContext); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -1128,7 +1137,7 @@ class DiscardCheckingContext : public TestWebGraphicsContext3D { class NonReshapableOutputSurface : public FakeOutputSurface { public: explicit NonReshapableOutputSurface( - scoped_ptr<TestWebGraphicsContext3D> context3d) + std::unique_ptr<TestWebGraphicsContext3D> context3d) : FakeOutputSurface(TestContextProvider::Create(std::move(context3d)), false) { surface_size_ = gfx::Size(500, 500); @@ -1140,19 +1149,21 @@ class NonReshapableOutputSurface : public FakeOutputSurface { }; TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) { - scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext); + std::unique_ptr<DiscardCheckingContext> context_owned( + new DiscardCheckingContext); DiscardCheckingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<NonReshapableOutputSurface> output_surface( + std::unique_ptr<NonReshapableOutputSurface> output_surface( new NonReshapableOutputSurface(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); output_surface->set_fixed_size(gfx::Size(100, 100)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; settings.partial_swap_enabled = true; @@ -1294,7 +1305,7 @@ TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) { // and maintains a fixed size. This test verifies that glViewport and // glScissor's Y coordinate is flipped correctly in this environment, and that // the glViewport can be at a nonzero origin within the surface. - scoped_ptr<FlippedScissorAndViewportContext> context_owned( + std::unique_ptr<FlippedScissorAndViewportContext> context_owned( new FlippedScissorAndViewportContext); // We expect exactly one call to viewport on this context and exactly two @@ -1304,14 +1315,15 @@ TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) { EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20)); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( new NonReshapableOutputSurface(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -1346,14 +1358,15 @@ TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) { // Note: there is one path that will set it to 0, but that is after the render // has finished. FakeOutputSurfaceClient output_surface_client; - scoped_ptr<FakeOutputSurface> output_surface( + std::unique_ptr<FakeOutputSurface> output_surface( FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); RendererSettings settings; FakeRendererClient renderer_client; @@ -1417,12 +1430,10 @@ TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) { matrix[13] = matrix[14] = 0; matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; matrix[18] = 1; - sk_sp<SkColorFilter> color_filter = - SkColorFilter::MakeMatrixFilterRowMajor255(matrix); - skia::RefPtr<SkImageFilter> filter = skia::AdoptRef( - SkColorFilterImageFilter::Create(color_filter.get(), NULL)); FilterOperations filters; - filters.Append(FilterOperation::CreateReferenceFilter(filter)); + filters.Append( + FilterOperation::CreateReferenceFilter(SkColorFilterImageFilter::Make( + SkColorFilter::MakeMatrixFilterRowMajor255(matrix), nullptr))); gfx::Transform transform_causing_aa; transform_causing_aa.Rotate(20.0); @@ -1734,7 +1745,7 @@ TEST_F(GLRendererShaderTest, DrawSolidColorShader) { class OutputSurfaceMockContext : public TestWebGraphicsContext3D { public: - OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; } + OutputSurfaceMockContext() { test_capabilities_.post_sub_buffer = true; } // Specifically override methods even if they are unused (used in conjunction // with StrictMock). We need to make sure that GLRenderer does not issue @@ -1750,8 +1761,8 @@ class OutputSurfaceMockContext : public TestWebGraphicsContext3D { class MockOutputSurface : public OutputSurface { public: MockOutputSurface() - : OutputSurface( - TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>( + : OutputSurface(TestContextProvider::Create( + std::unique_ptr<TestWebGraphicsContext3D>( new StrictMock<OutputSurfaceMockContext>))) { surface_size_ = gfx::Size(100, 100); } @@ -1821,10 +1832,10 @@ class MockOutputSurfaceTest : public GLRendererTest { RendererSettings settings_; FakeOutputSurfaceClient output_surface_client_; StrictMock<MockOutputSurface> output_surface_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; FakeRendererClient renderer_client_; - scoped_ptr<FakeRendererGL> renderer_; + std::unique_ptr<FakeRendererGL> renderer_; }; TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) { @@ -1867,89 +1878,6 @@ TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) { renderer_->SwapBuffers(CompositorFrameMetadata()); } -class GLRendererTestSyncPoint : public GLRendererPixelTest { - protected: - static void SyncTokenCallback(int* callback_count) { - ++(*callback_count); - base::MessageLoop::current()->QuitWhenIdle(); - } - - static void OtherCallback(int* callback_count) { - ++(*callback_count); - base::MessageLoop::current()->QuitWhenIdle(); - } -}; - -#if !defined(OS_ANDROID) -TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) { - int sync_token_callback_count = 0; - int other_callback_count = 0; - gpu::gles2::GLES2Interface* gl = - output_surface_->context_provider()->ContextGL(); - gpu::ContextSupport* context_support = - output_surface_->context_provider()->ContextSupport(); - - const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM(); - gl->ShallowFlushCHROMIUM(); - - gpu::SyncToken sync_token; - gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); - - gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, - GL_INNOCENT_CONTEXT_RESET_ARB); - - context_support->SignalSyncToken( - sync_token, base::Bind(&SyncTokenCallback, &sync_token_callback_count)); - EXPECT_EQ(0, sync_token_callback_count); - EXPECT_EQ(0, other_callback_count); - - // Make the sync point happen. - gl->Finish(); - // Post a task after the sync point. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&OtherCallback, &other_callback_count)); - - base::MessageLoop::current()->Run(); - - // The sync point shouldn't have happened since the context was lost. - EXPECT_EQ(0, sync_token_callback_count); - EXPECT_EQ(1, other_callback_count); -} - -TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) { - int sync_token_callback_count = 0; - int other_callback_count = 0; - - gpu::gles2::GLES2Interface* gl = - output_surface_->context_provider()->ContextGL(); - gpu::ContextSupport* context_support = - output_surface_->context_provider()->ContextSupport(); - - const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM(); - gl->ShallowFlushCHROMIUM(); - - gpu::SyncToken sync_token; - gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); - - context_support->SignalSyncToken( - sync_token, base::Bind(&SyncTokenCallback, &sync_token_callback_count)); - EXPECT_EQ(0, sync_token_callback_count); - EXPECT_EQ(0, other_callback_count); - - // Make the sync point happen. - gl->Finish(); - // Post a task after the sync point. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&OtherCallback, &other_callback_count)); - - base::MessageLoop::current()->Run(); - - // The sync point should have happened. - EXPECT_EQ(1, sync_token_callback_count); - EXPECT_EQ(1, other_callback_count); -} -#endif // OS_ANDROID - class TestOverlayProcessor : public OverlayProcessor { public: class Strategy : public OverlayProcessor::Strategy { @@ -1983,7 +1911,7 @@ class TestOverlayProcessor : public OverlayProcessor { ~TestOverlayProcessor() override {} void Initialize() override { strategy_ = new Strategy(); - strategies_.push_back(make_scoped_ptr(strategy_)); + strategies_.push_back(base::WrapUnique(strategy_)); } Strategy* strategy_; @@ -1993,21 +1921,22 @@ void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource, BlockingTaskRunner* main_thread_task_runner) {} -void IgnoreCopyResult(scoped_ptr<CopyOutputResult> result) { -} +void IgnoreCopyResult(std::unique_ptr<CopyOutputResult> result) {} TEST_F(GLRendererTest, DontOverlayWithCopyRequests) { - scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext); + std::unique_ptr<DiscardCheckingContext> context_owned( + new DiscardCheckingContext); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<FakeOutputSurface> output_surface( + std::unique_ptr<FakeOutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); - scoped_ptr<TextureMailboxDeleter> mailbox_deleter( + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); + std::unique_ptr<TextureMailboxDeleter> mailbox_deleter( new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get())); RendererSettings settings; @@ -2019,7 +1948,7 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) { new TestOverlayProcessor(output_surface.get()); processor->Initialize(); renderer.SetOverlayProcessor(processor); - scoped_ptr<TestOverlayProcessor::Validator> validator( + std::unique_ptr<TestOverlayProcessor::Validator> validator( new TestOverlayProcessor::Validator); output_surface->SetOverlayCandidateValidator(validator.get()); @@ -2031,10 +1960,10 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) { root_pass->copy_requests.push_back( CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult))); - TextureMailbox mailbox = - TextureMailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D, - gfx::Size(256, 256), true, false); - scoped_ptr<SingleReleaseCallbackImpl> release_callback = + TextureMailbox mailbox = TextureMailbox( + gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D, + gfx::Size(256, 256), gfx::GpuMemoryBufferId(), true, false); + std::unique_ptr<SingleReleaseCallbackImpl> release_callback = SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased)); ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox( mailbox, std::move(release_callback)); @@ -2049,7 +1978,7 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) { viewport_rect, viewport_rect, viewport_rect, resource_id, premultiplied_alpha, gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity, - flipped, nearest_neighbor); + flipped, nearest_neighbor, false); // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays. // Attempt will be called for each strategy in OverlayProcessor. We have @@ -2073,7 +2002,7 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) { viewport_rect, viewport_rect, viewport_rect, resource_id, premultiplied_alpha, gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity, - flipped, nearest_neighbor); + flipped, nearest_neighbor, false); EXPECT_CALL(*validator, AllowCALayerOverlays()) .Times(1) .WillOnce(::testing::Return(false)); @@ -2092,7 +2021,7 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) { viewport_rect, viewport_rect, viewport_rect, resource_id, premultiplied_alpha, gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity, - flipped, nearest_neighbor); + flipped, nearest_neighbor, false); EXPECT_CALL(*validator, AllowCALayerOverlays()) .Times(1) .WillOnce(::testing::Return(true)); @@ -2107,8 +2036,9 @@ class SingleOverlayOnTopProcessor : public OverlayProcessor { public: void GetStrategies(OverlayProcessor::StrategyList* strategies) override { strategies->push_back( - make_scoped_ptr(new OverlayStrategySingleOnTop(this))); - strategies->push_back(make_scoped_ptr(new OverlayStrategyUnderlay(this))); + base::WrapUnique(new OverlayStrategySingleOnTop(this))); + strategies->push_back( + base::WrapUnique(new OverlayStrategyUnderlay(this))); } bool AllowCALayerOverlays() override { return false; } @@ -2125,7 +2055,7 @@ class SingleOverlayOnTopProcessor : public OverlayProcessor { void Initialize() override { strategies_.push_back( - make_scoped_ptr(new OverlayStrategySingleOnTop(&validator_))); + base::WrapUnique(new OverlayStrategySingleOnTop(&validator_))); } SingleOverlayValidator validator_; @@ -2147,7 +2077,7 @@ class MockOverlayScheduler { }; TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) { - scoped_ptr<WaitSyncTokenCountingContext> context_owned( + std::unique_ptr<WaitSyncTokenCountingContext> context_owned( new WaitSyncTokenCountingContext); WaitSyncTokenCountingContext* context = context_owned.get(); @@ -2158,15 +2088,16 @@ TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) { &MockOverlayScheduler::Schedule, base::Unretained(&overlay_scheduler))); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(context_provider)); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); - scoped_ptr<TextureMailboxDeleter> mailbox_deleter( + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); + std::unique_ptr<TextureMailboxDeleter> mailbox_deleter( new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get())); RendererSettings settings; @@ -2187,10 +2118,10 @@ TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) { gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO, 0, gpu::CommandBufferId::FromUnsafeValue(0x123), 29); - TextureMailbox mailbox = - TextureMailbox(gpu::Mailbox::Generate(), sync_token, GL_TEXTURE_2D, - gfx::Size(256, 256), true, false); - scoped_ptr<SingleReleaseCallbackImpl> release_callback = + TextureMailbox mailbox = TextureMailbox( + gpu::Mailbox::Generate(), sync_token, GL_TEXTURE_2D, gfx::Size(256, 256), + gfx::GpuMemoryBufferId(), true, false); + std::unique_ptr<SingleReleaseCallbackImpl> release_callback = SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased)); ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox( mailbox, std::move(release_callback)); @@ -2209,7 +2140,7 @@ TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) { overlay_quad->SetNew(shared_state, viewport_rect, viewport_rect, viewport_rect, resource_id, premultiplied_alpha, uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT, - vertex_opacity, flipped, nearest_neighbor); + vertex_opacity, flipped, nearest_neighbor, false); // 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/output_surface.cc b/chromium/cc/output/output_surface.cc index b3b18da4fa5..3e1549701e9 100644 --- a/chromium/cc/output/output_surface.cc +++ b/chromium/cc/output/output_surface.cc @@ -10,7 +10,7 @@ #include "base/location.h" #include "base/macros.h" #include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface_client.h" @@ -121,16 +121,12 @@ class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump { OutputSurface::OutputSurface( scoped_refptr<ContextProvider> context_provider, scoped_refptr<ContextProvider> worker_context_provider, -#if defined(ENABLE_VULKAN) scoped_refptr<VulkanContextProvider> vulkan_context_provider, -#endif - scoped_ptr<SoftwareOutputDevice> software_device) + std::unique_ptr<SoftwareOutputDevice> software_device) : client_(NULL), context_provider_(std::move(context_provider)), worker_context_provider_(std::move(worker_context_provider)), -#if defined(ENABLE_VULKAN) vulkan_context_provider_(vulkan_context_provider), -#endif software_device_(std::move(software_device)), device_scale_factor_(-1), has_alpha_(true), @@ -142,9 +138,7 @@ OutputSurface::OutputSurface( OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) : OutputSurface(std::move(context_provider), nullptr, -#if defined(ENABLE_VULKAN) nullptr, -#endif nullptr) { } @@ -153,51 +147,27 @@ OutputSurface::OutputSurface( scoped_refptr<ContextProvider> worker_context_provider) : OutputSurface(std::move(context_provider), std::move(worker_context_provider), -#if defined(ENABLE_VULKAN) nullptr, -#endif nullptr) { } -#if defined(ENABLE_VULKAN) OutputSurface::OutputSurface( - scoped_refptr<VulkanContextProvider> vulkan_context_provider) + std::unique_ptr<SoftwareOutputDevice> software_device) : OutputSurface(nullptr, nullptr, - std::move(vulkan_context_provider), - nullptr) {} -#endif - -OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) - : OutputSurface(nullptr, - nullptr, -#if defined(ENABLE_VULKAN) nullptr, -#endif std::move(software_device)) { } -OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider, - scoped_ptr<SoftwareOutputDevice> software_device) +OutputSurface::OutputSurface( + scoped_refptr<ContextProvider> context_provider, + std::unique_ptr<SoftwareOutputDevice> software_device) : OutputSurface(std::move(context_provider), nullptr, -#if defined(ENABLE_VULKAN) nullptr, -#endif std::move(software_device)) { } -void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) { - TRACE_EVENT2("cc", - "OutputSurface::CommitVSyncParameters", - "timebase", - (timebase - base::TimeTicks()).InSecondsF(), - "interval", - interval.InSecondsF()); - client_->CommitVSyncParameters(timebase, interval); -} - // Forwarded to OutputSurfaceClient void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect"); @@ -243,13 +213,10 @@ bool OutputSurface::BindToClient(OutputSurfaceClient* client) { } } - if (!success) - client_ = NULL; - // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). // Don't register a dump provider in these cases. // TODO(ericrk): Get this working in Android Webview. crbug.com/517156 - if (client_ && base::ThreadTaskRunnerHandle::IsSet()) { + if (base::ThreadTaskRunnerHandle::IsSet()) { // Now that we are on the context thread, register a dump provider with this // thread's task runner. This will overwrite any previous dump provider // registered. @@ -257,6 +224,8 @@ bool OutputSurface::BindToClient(OutputSurfaceClient* client) { this, "OutputSurface", base::ThreadTaskRunnerHandle::Get()); } + if (!success) + DetachFromClient(); return success; } diff --git a/chromium/cc/output/output_surface.h b/chromium/cc/output/output_surface.h index ccfe1184d9f..326b2fd2fbf 100644 --- a/chromium/cc/output/output_surface.h +++ b/chromium/cc/output/output_surface.h @@ -6,20 +6,17 @@ #define CC_OUTPUT_OUTPUT_SURFACE_H_ #include <deque> +#include <memory> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "cc/base/cc_export.h" #include "cc/output/context_provider.h" #include "cc/output/overlay_candidate_validator.h" #include "cc/output/software_output_device.h" - -#if defined(ENABLE_VULKAN) #include "cc/output/vulkan_context_provider.h" -#endif namespace base { class SingleThreadTaskRunner; } @@ -51,21 +48,15 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { public: OutputSurface(scoped_refptr<ContextProvider> context_provider, scoped_refptr<ContextProvider> worker_context_provider, -#if defined(ENABLE_VULKAN) scoped_refptr<VulkanContextProvider> vulkan_context_provider, -#endif - scoped_ptr<SoftwareOutputDevice> software_device); + std::unique_ptr<SoftwareOutputDevice> software_device); OutputSurface(scoped_refptr<ContextProvider> context_provider, scoped_refptr<ContextProvider> worker_context_provider); explicit OutputSurface(scoped_refptr<ContextProvider> context_provider); -#if defined(ENABLE_VULKAN) - explicit OutputSurface( - scoped_refptr<VulkanContextProvider> vulkan_context_provider); -#endif - explicit OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device); + explicit OutputSurface(std::unique_ptr<SoftwareOutputDevice> software_device); OutputSurface(scoped_refptr<ContextProvider> context_provider, - scoped_ptr<SoftwareOutputDevice> software_device); + std::unique_ptr<SoftwareOutputDevice> software_device); ~OutputSurface() override; @@ -111,11 +102,9 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { ContextProvider* worker_context_provider() const { return worker_context_provider_.get(); } -#if defined(ENABLE_VULKAN) VulkanContextProvider* vulkan_context_provider() const { return vulkan_context_provider_.get(); } -#endif SoftwareOutputDevice* software_device() const { return software_device_.get(); } @@ -190,18 +179,13 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { struct OutputSurface::Capabilities capabilities_; scoped_refptr<ContextProvider> context_provider_; scoped_refptr<ContextProvider> worker_context_provider_; -#if defined(ENABLE_VULKAN) scoped_refptr<VulkanContextProvider> vulkan_context_provider_; -#endif - scoped_ptr<SoftwareOutputDevice> software_device_; + std::unique_ptr<SoftwareOutputDevice> software_device_; gfx::Size surface_size_; float device_scale_factor_; bool has_alpha_; base::ThreadChecker client_thread_checker_; - void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval); - void SetNeedsRedrawRect(const gfx::Rect& damage_rect); void ReclaimResources(const CompositorFrameAck* ack); void SetExternalStencilTest(bool enabled); diff --git a/chromium/cc/output/output_surface_client.h b/chromium/cc/output/output_surface_client.h index 8f7f36ee204..dae73582ced 100644 --- a/chromium/cc/output/output_surface_client.h +++ b/chromium/cc/output/output_surface_client.h @@ -18,13 +18,20 @@ class Transform; namespace cc { +class BeginFrameSource; class CompositorFrameAck; struct ManagedMemoryPolicy; class CC_EXPORT OutputSurfaceClient { public: + // TODO(enne): Remove this in favor of using SetBeginFrameSource. virtual void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) = 0; + // Pass the begin frame source for the client to observe. Client does not own + // the BeginFrameSource. OutputSurface should call this once after binding to + // the client and then call again with a null while detaching. + virtual void SetBeginFrameSource(BeginFrameSource* source) = 0; + virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0; virtual void DidSwapBuffers() = 0; virtual void DidSwapBuffersComplete() = 0; @@ -39,7 +46,7 @@ class CC_EXPORT OutputSurfaceClient { // valid for the lifetime of the OutputSurfaceClient or until unregisted -- // use SetTreeActivationCallback(base::Closure()) to unregister it. virtual void SetTreeActivationCallback(const base::Closure& callback) = 0; - // This allows the output surface to ask it's client for a draw. + // This allows the output surface to ask its client for a draw. virtual void OnDraw(const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, diff --git a/chromium/cc/output/output_surface_unittest.cc b/chromium/cc/output/output_surface_unittest.cc index 36848522ea5..bebd2457275 100644 --- a/chromium/cc/output/output_surface_unittest.cc +++ b/chromium/cc/output/output_surface_unittest.cc @@ -4,6 +4,7 @@ #include "cc/output/output_surface.h" +#include "base/memory/ptr_util.h" #include "base/test/test_simple_task_runner.h" #include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface_client.h" @@ -28,11 +29,12 @@ class TestOutputSurface : public OutputSurface { scoped_refptr<ContextProvider> worker_context_provider) : OutputSurface(worker_context_provider) {} - explicit TestOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) + explicit TestOutputSurface( + std::unique_ptr<SoftwareOutputDevice> software_device) : OutputSurface(std::move(software_device)) {} TestOutputSurface(scoped_refptr<ContextProvider> context_provider, - scoped_ptr<SoftwareOutputDevice> software_device) + std::unique_ptr<SoftwareOutputDevice> software_device) : OutputSurface(context_provider, std::move(software_device)) {} void SwapBuffers(CompositorFrame* frame) override { @@ -40,11 +42,6 @@ class TestOutputSurface : public OutputSurface { client_->DidSwapBuffersComplete(); } - void CommitVSyncParametersForTesting(base::TimeTicks timebase, - base::TimeDelta interval) { - CommitVSyncParameters(timebase, interval); - } - void DidSwapBuffersForTesting() { client_->DidSwapBuffers(); } void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); } @@ -158,7 +155,7 @@ TEST(OutputSurfaceTest, SoftwareOutputDeviceBackbufferManagement) { // TestOutputSurface now owns software_output_device and has responsibility to // free it. - TestOutputSurface output_surface(make_scoped_ptr(software_output_device)); + TestOutputSurface output_surface(base::WrapUnique(software_output_device)); EXPECT_EQ(0, software_output_device->ensure_backbuffer_count()); EXPECT_EQ(0, software_output_device->discard_backbuffer_count()); diff --git a/chromium/cc/output/overlay_candidate.cc b/chromium/cc/output/overlay_candidate.cc index 1a734ced029..9259a6cc738 100644 --- a/chromium/cc/output/overlay_candidate.cc +++ b/chromium/cc/output/overlay_candidate.cc @@ -8,7 +8,6 @@ #include <limits> #include "base/logging.h" #include "cc/base/math_util.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/stream_video_draw_quad.h" #include "cc/quads/texture_draw_quad.h" @@ -208,9 +207,6 @@ bool OverlayCandidate::FromDrawQuad(ResourceProvider* resource_provider, return FromStreamVideoQuad(resource_provider, StreamVideoDrawQuad::MaterialCast(quad), candidate); - case DrawQuad::IO_SURFACE_CONTENT: - return FromIOSurfaceQuad( - resource_provider, IOSurfaceDrawQuad::MaterialCast(quad), candidate); default: break; } @@ -312,21 +308,4 @@ bool OverlayCandidate::FromStreamVideoQuad(ResourceProvider* resource_provider, return true; } -// static -bool OverlayCandidate::FromIOSurfaceQuad(ResourceProvider* resource_provider, - const IOSurfaceDrawQuad* quad, - OverlayCandidate* candidate) { - if (!resource_provider->IsOverlayCandidate(quad->io_surface_resource_id())) - return false; - gfx::OverlayTransform overlay_transform = GetOverlayTransform( - quad->shared_quad_state->quad_to_target_transform, false); - if (overlay_transform != gfx::OVERLAY_TRANSFORM_NONE) - return false; - candidate->resource_id = quad->io_surface_resource_id(); - candidate->resource_size_in_pixels = quad->io_surface_size; - candidate->transform = overlay_transform; - candidate->uv_rect = gfx::RectF(1.f, 1.f); - return true; -} - } // namespace cc diff --git a/chromium/cc/output/overlay_candidate.h b/chromium/cc/output/overlay_candidate.h index adf837e72e0..7ced45c4f1b 100644 --- a/chromium/cc/output/overlay_candidate.h +++ b/chromium/cc/output/overlay_candidate.h @@ -23,7 +23,6 @@ class Rect; namespace cc { class DrawQuad; -class IOSurfaceDrawQuad; class StreamVideoDrawQuad; class TextureDrawQuad; class ResourceProvider; @@ -90,9 +89,6 @@ class CC_EXPORT OverlayCandidate { static bool FromStreamVideoQuad(ResourceProvider* resource_provider, const StreamVideoDrawQuad* quad, OverlayCandidate* candidate); - static bool FromIOSurfaceQuad(ResourceProvider* resource_provider, - const IOSurfaceDrawQuad* quad, - OverlayCandidate* candidate); }; typedef std::vector<OverlayCandidate> OverlayCandidateList; diff --git a/chromium/cc/output/overlay_processor.h b/chromium/cc/output/overlay_processor.h index 4a441a8c2d7..01c28d25317 100644 --- a/chromium/cc/output/overlay_processor.h +++ b/chromium/cc/output/overlay_processor.h @@ -5,8 +5,9 @@ #ifndef CC_OUTPUT_OVERLAY_PROCESSOR_H_ #define CC_OUTPUT_OVERLAY_PROCESSOR_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/ca_layer_overlay.h" #include "cc/output/overlay_candidate.h" @@ -29,7 +30,7 @@ class CC_EXPORT OverlayProcessor { RenderPass* render_pass, OverlayCandidateList* candidates) = 0; }; - using StrategyList = std::vector<scoped_ptr<Strategy>>; + using StrategyList = std::vector<std::unique_ptr<Strategy>>; explicit OverlayProcessor(OutputSurface* surface); virtual ~OverlayProcessor(); diff --git a/chromium/cc/output/overlay_unittest.cc b/chromium/cc/output/overlay_unittest.cc index 8697685cccf..b95d46c7801 100644 --- a/chromium/cc/output/overlay_unittest.cc +++ b/chromium/cc/output/overlay_unittest.cc @@ -6,6 +6,7 @@ #include <utility> +#include "base/memory/ptr_util.h" #include "cc/base/region.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/output/gl_renderer.h" @@ -63,8 +64,8 @@ class SingleOverlayValidator : public OverlayCandidateValidator { public: void GetStrategies(OverlayProcessor::StrategyList* strategies) override { strategies->push_back( - make_scoped_ptr(new OverlayStrategySingleOnTop(this))); - strategies->push_back(make_scoped_ptr(new OverlayStrategyUnderlay(this))); + base::WrapUnique(new OverlayStrategySingleOnTop(this))); + strategies->push_back(base::WrapUnique(new OverlayStrategyUnderlay(this))); } bool AllowCALayerOverlays() override { return false; } void CheckOverlaySupport(OverlayCandidateList* surfaces) override { @@ -105,14 +106,14 @@ class SingleOnTopOverlayValidator : public SingleOverlayValidator { public: void GetStrategies(OverlayProcessor::StrategyList* strategies) override { strategies->push_back( - make_scoped_ptr(new OverlayStrategySingleOnTop(this))); + base::WrapUnique(new OverlayStrategySingleOnTop(this))); } }; class UnderlayOverlayValidator : public SingleOverlayValidator { public: void GetStrategies(OverlayProcessor::StrategyList* strategies) override { - strategies->push_back(make_scoped_ptr(new OverlayStrategyUnderlay(this))); + strategies->push_back(base::WrapUnique(new OverlayStrategyUnderlay(this))); } }; @@ -171,17 +172,17 @@ class OverlayOutputSurface : public OutputSurface { unsigned bind_framebuffer_count() const { return bind_framebuffer_count_; } private: - scoped_ptr<OverlayCandidateValidator> overlay_candidate_validator_; + std::unique_ptr<OverlayCandidateValidator> overlay_candidate_validator_; bool is_displayed_as_overlay_plane_; unsigned bind_framebuffer_count_ = 0; }; -scoped_ptr<RenderPass> CreateRenderPass() { +std::unique_ptr<RenderPass> CreateRenderPass() { RenderPassId id(1, 0); gfx::Rect output_rect(0, 0, 256, 256); bool has_transparent_background = true; - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetAll(id, output_rect, output_rect, @@ -196,10 +197,10 @@ scoped_ptr<RenderPass> CreateRenderPass() { ResourceId CreateResource(ResourceProvider* resource_provider, const gfx::Size& size, bool is_overlay_candidate) { - TextureMailbox mailbox = - TextureMailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D, - size, is_overlay_candidate, false); - scoped_ptr<SingleReleaseCallbackImpl> release_callback = + TextureMailbox mailbox = TextureMailbox( + gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D, size, + gfx::GpuMemoryBufferId(), is_overlay_candidate, false); + std::unique_ptr<SingleReleaseCallbackImpl> release_callback = SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased)); return resource_provider->CreateResourceFromTextureMailbox( @@ -232,18 +233,10 @@ TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider, TextureDrawQuad* overlay_quad = render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); - overlay_quad->SetNew(shared_quad_state, - rect, - rect, - rect, - resource_id, - premultiplied_alpha, - kUVTopLeft, - kUVBottomRight, - SK_ColorTRANSPARENT, - vertex_opacity, - flipped, - nearest_neighbor); + overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id, + premultiplied_alpha, kUVTopLeft, kUVBottomRight, + SK_ColorTRANSPARENT, vertex_opacity, flipped, + nearest_neighbor, false); overlay_quad->set_resource_size_in_pixels(resource_size_in_pixels); return overlay_quad; @@ -350,11 +343,11 @@ class OverlayTest : public testing::Test { } scoped_refptr<TestContextProvider> provider_; - scoped_ptr<OverlayOutputSurface> output_surface_; + std::unique_ptr<OverlayOutputSurface> output_surface_; FakeOutputSurfaceClient client_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<OverlayProcessor> overlay_processor_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<OverlayProcessor> overlay_processor_; gfx::Rect damage_rect_; }; @@ -378,19 +371,20 @@ TEST(OverlayTest, OverlaysProcessorHasStrategy) { EXPECT_TRUE(output_surface.BindToClient(&client)); output_surface.SetOverlayCandidateValidator(new SingleOverlayValidator); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - &output_surface, shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(&output_surface, + shared_bitmap_manager.get()); - scoped_ptr<DefaultOverlayProcessor> overlay_processor( + std::unique_ptr<DefaultOverlayProcessor> overlay_processor( new DefaultOverlayProcessor(&output_surface)); overlay_processor->Initialize(); EXPECT_GE(2U, overlay_processor->GetStrategyCount()); } TEST_F(SingleOverlayOnTopTest, SuccessfulOverlay) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); TextureDrawQuad* original_quad = CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -425,7 +419,7 @@ TEST_F(SingleOverlayOnTopTest, SuccessfulOverlay) { } TEST_F(SingleOverlayOnTopTest, DamageRect) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -455,7 +449,7 @@ TEST_F(SingleOverlayOnTopTest, DamageRect) { } TEST_F(SingleOverlayOnTopTest, NoCandidates) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenOpaqueQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); CreateFullscreenOpaqueQuad(resource_provider_.get(), @@ -477,7 +471,7 @@ TEST_F(SingleOverlayOnTopTest, NoCandidates) { } TEST_F(SingleOverlayOnTopTest, OccludedCandidates) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenOpaqueQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); CreateFullscreenOpaqueQuad(resource_provider_.get(), @@ -504,7 +498,7 @@ TEST_F(SingleOverlayOnTopTest, OccludedCandidates) { // Test with multiple render passes. TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -524,7 +518,7 @@ TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) { } TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); TextureDrawQuad* quad = CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -539,7 +533,7 @@ TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) { } TEST_F(SingleOverlayOnTopTest, RejectBlending) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); TextureDrawQuad* quad = CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -554,7 +548,7 @@ TEST_F(SingleOverlayOnTopTest, RejectBlending) { } TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); TextureDrawQuad* quad = CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -569,7 +563,7 @@ TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) { } TEST_F(SingleOverlayOnTopTest, RejectBlendMode) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -583,7 +577,7 @@ TEST_F(SingleOverlayOnTopTest, RejectBlendMode) { } TEST_F(SingleOverlayOnTopTest, RejectOpacity) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -597,7 +591,7 @@ TEST_F(SingleOverlayOnTopTest, RejectOpacity) { } TEST_F(SingleOverlayOnTopTest, RejectNonAxisAlignedTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -612,7 +606,7 @@ TEST_F(SingleOverlayOnTopTest, RejectNonAxisAlignedTransform) { } TEST_F(SingleOverlayOnTopTest, AllowClipped) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -630,7 +624,7 @@ TEST_F(SingleOverlayOnTopTest, AllowVerticalFlip) { gfx::Rect rect = kOverlayRect; rect.set_width(rect.width() / 2); rect.Offset(0, -rect.height()); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), rect); pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f, @@ -648,7 +642,7 @@ TEST_F(SingleOverlayOnTopTest, AllowHorizontalFlip) { gfx::Rect rect = kOverlayRect; rect.set_height(rect.height() / 2); rect.Offset(-rect.width(), 0); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), rect); pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(-1.0f, @@ -666,7 +660,7 @@ TEST_F(SingleOverlayOnTopTest, AllowHorizontalFlip) { TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) { gfx::Rect rect = kOverlayRect; rect.set_width(rect.width() / 2); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), rect); pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f, @@ -681,7 +675,7 @@ TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) { TEST_F(SingleOverlayOnTopTest, Allow90DegreeRotation) { gfx::Rect rect = kOverlayRect; rect.Offset(0, -rect.height()); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), rect); pass->shared_quad_state_list.back() @@ -698,7 +692,7 @@ TEST_F(SingleOverlayOnTopTest, Allow90DegreeRotation) { TEST_F(SingleOverlayOnTopTest, Allow180DegreeRotation) { gfx::Rect rect = kOverlayRect; rect.Offset(-rect.width(), -rect.height()); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), rect); pass->shared_quad_state_list.back() @@ -715,7 +709,7 @@ TEST_F(SingleOverlayOnTopTest, Allow180DegreeRotation) { TEST_F(SingleOverlayOnTopTest, Allow270DegreeRotation) { gfx::Rect rect = kOverlayRect; rect.Offset(-rect.width(), 0); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), rect); pass->shared_quad_state_list.back() @@ -730,7 +724,7 @@ TEST_F(SingleOverlayOnTopTest, Allow270DegreeRotation) { } TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateOpaqueQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), kOverlayTopLeftRect); @@ -747,7 +741,7 @@ TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) { } TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); shared_state->opacity = 0.f; CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(), @@ -765,7 +759,7 @@ TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) { } TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateSolidColorQuadAt(pass->shared_quad_state_list.back(), SK_ColorTRANSPARENT, pass.get(), kOverlayBottomRightRect); @@ -781,7 +775,7 @@ TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) { } TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); shared_state->opacity = 0.5f; CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(), @@ -799,7 +793,7 @@ TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) { } TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(), kOverlayBottomRightRect)->opaque_rect = @@ -815,7 +809,7 @@ TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) { } TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), kSwapTransform); @@ -828,7 +822,7 @@ TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) { } TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), kXMirrorTransform); @@ -841,7 +835,7 @@ TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) { } TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), kBothMirrorTransform); @@ -854,7 +848,7 @@ TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) { } TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), kNormalTransform); @@ -867,7 +861,7 @@ TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) { } TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateVideoQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), kYMirrorTransform); @@ -880,7 +874,7 @@ TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) { } TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenOpaqueQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); CreateCandidateQuadAt(resource_provider_.get(), @@ -899,7 +893,7 @@ TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) { } TEST_F(UnderlayTest, AllowOnTop) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -919,7 +913,7 @@ TEST_F(UnderlayTest, AllowOnTop) { // The first time an underlay is scheduled its damage must not be subtracted. TEST_F(UnderlayTest, InitialUnderlayDamageNotSubtracted) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -938,7 +932,7 @@ TEST_F(UnderlayTest, InitialUnderlayDamageNotSubtracted) { // subtracted the second time. TEST_F(UnderlayTest, DamageSubtractedForConsecutiveIdenticalUnderlays) { for (int i = 0; i < 2; ++i) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -965,7 +959,7 @@ TEST_F(UnderlayTest, DamageSubtractedForConsecutiveIdenticalUnderlays) { TEST_F(UnderlayTest, DamageNotSubtractedForNonIdenticalConsecutiveUnderlays) { gfx::Rect overlay_rects[] = {kOverlayBottomRightRect, kOverlayRect}; for (int i = 0; i < 2; ++i) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), @@ -984,7 +978,7 @@ TEST_F(UnderlayTest, DamageNotSubtractedForNonIdenticalConsecutiveUnderlays) { TEST_F(UnderlayTest, DamageNotSubtractedWhenQuadsAboveOverlap) { for (int i = 0; i < 2; ++i) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); // Add an overlapping quad above the candidate. CreateFullscreenOpaqueQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -1005,7 +999,7 @@ TEST_F(UnderlayTest, DamageNotSubtractedWhenQuadsAboveOverlap) { TEST_F(UnderlayTest, DamageSubtractedWhenQuadsAboveDontOverlap) { for (int i = 0; i < 2; ++i) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); // Add a non-overlapping quad above the candidate. CreateOpaqueQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), @@ -1038,7 +1032,7 @@ OverlayCandidateList BackbufferOverlayList(const RenderPass* root_render_pass) { } TEST_F(CALayerOverlayTest, AllowNonAxisAlignedTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -1058,7 +1052,7 @@ TEST_F(CALayerOverlayTest, AllowNonAxisAlignedTransform) { } TEST_F(CALayerOverlayTest, ThreeDTransform) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -1081,7 +1075,7 @@ TEST_F(CALayerOverlayTest, ThreeDTransform) { } TEST_F(CALayerOverlayTest, AllowContainingClip) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -1101,7 +1095,7 @@ TEST_F(CALayerOverlayTest, AllowContainingClip) { } TEST_F(CALayerOverlayTest, NontrivialClip) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -1123,7 +1117,7 @@ TEST_F(CALayerOverlayTest, NontrivialClip) { } TEST_F(CALayerOverlayTest, SkipTransparent) { - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -1215,11 +1209,9 @@ class GLRendererWithOverlaysTest : public testing::Test { if (use_validator) output_surface_->SetOverlayCandidateValidator(new SingleOverlayValidator); - renderer_ = - make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_, - &settings_, - output_surface_.get(), - resource_provider_.get())); + renderer_ = base::WrapUnique(new OverlayInfoRendererGL( + &renderer_client_, &settings_, output_surface_.get(), + resource_provider_.get())); } void SwapBuffers() { @@ -1237,10 +1229,10 @@ class GLRendererWithOverlaysTest : public testing::Test { RendererSettings settings_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<OverlayOutputSurface> output_surface_; + std::unique_ptr<OverlayOutputSurface> output_surface_; FakeRendererClient renderer_client_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<OverlayInfoRendererGL> renderer_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<OverlayInfoRendererGL> renderer_; scoped_refptr<TestContextProvider> provider_; MockOverlayScheduler scheduler_; }; @@ -1251,7 +1243,7 @@ TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) { renderer_->set_expect_overlays(true); gfx::Rect viewport_rect(16, 16); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateCandidateQuadAt(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get(), @@ -1290,7 +1282,7 @@ TEST_F(GLRendererWithOverlaysTest, OccludedQuadInUnderlay) { renderer_->set_expect_overlays(true); gfx::Rect viewport_rect(16, 16); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenOpaqueQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); @@ -1330,7 +1322,7 @@ TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) { renderer_->set_expect_overlays(false); gfx::Rect viewport_rect(16, 16); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -1364,7 +1356,7 @@ TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenPartialSwapEnabled) { renderer_->set_expect_overlays(true); gfx::Rect viewport_rect(16, 16); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -1395,7 +1387,7 @@ TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenEmptySwapAllowed) { renderer_->set_expect_overlays(true); gfx::Rect viewport_rect(16, 16); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -1431,7 +1423,7 @@ TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturnedWithDelay) { ResourceId resource3 = CreateResource(resource_provider_.get(), gfx::Size(32, 32), true); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); RenderPassList pass_list; pass_list.push_back(std::move(pass)); @@ -1554,7 +1546,7 @@ TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturnedAtSwapComplete) { ResourceId resource3 = CreateResource(resource_provider_.get(), gfx::Size(32, 32), true); - scoped_ptr<RenderPass> pass = CreateRenderPass(); + std::unique_ptr<RenderPass> pass = CreateRenderPass(); RenderPassList pass_list; pass_list.push_back(std::move(pass)); diff --git a/chromium/cc/output/program_binding.cc b/chromium/cc/output/program_binding.cc index c05447c7d65..7f6bf17e064 100644 --- a/chromium/cc/output/program_binding.cc +++ b/chromium/cc/output/program_binding.cc @@ -88,7 +88,7 @@ unsigned ProgramBindingBase::LoadShader(GLES2Interface* context, shader_source_str, shader_length); context->CompileShader(shader); -#ifndef NDEBUG +#if DCHECK_IS_ON() int compiled = 0; context->GetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (!compiled) diff --git a/chromium/cc/output/render_surface_filters.cc b/chromium/cc/output/render_surface_filters.cc index de3c7fc7ec4..8d9890c5146 100644 --- a/chromium/cc/output/render_surface_filters.cc +++ b/chromium/cc/output/render_surface_filters.cc @@ -10,7 +10,6 @@ #include "cc/output/filter_operation.h" #include "cc/output/filter_operations.h" -#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/effects/SkAlphaThresholdFilter.h" #include "third_party/skia/include/effects/SkBlurImageFilter.h" @@ -145,130 +144,125 @@ void GetSepiaMatrix(float amount, SkScalar matrix[20]) { matrix[18] = 1.f; } -skia::RefPtr<SkImageFilter> CreateMatrixImageFilter( - const SkScalar matrix[20], - const skia::RefPtr<SkImageFilter>& input) { - sk_sp<SkColorFilter> color_filter = - SkColorFilter::MakeMatrixFilterRowMajor255(matrix); - return skia::AdoptRef( - SkColorFilterImageFilter::Create(color_filter.get(), input.get())); +sk_sp<SkImageFilter> CreateMatrixImageFilter(const SkScalar matrix[20], + sk_sp<SkImageFilter> input) { + return SkColorFilterImageFilter::Make( + SkColorFilter::MakeMatrixFilterRowMajor255(matrix), std::move(input)); } } // namespace -skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( +sk_sp<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( const FilterOperations& filters, const gfx::SizeF& size) { - skia::RefPtr<SkImageFilter> image_filter; + sk_sp<SkImageFilter> image_filter; SkScalar matrix[20]; for (size_t i = 0; i < filters.size(); ++i) { const FilterOperation& op = filters.at(i); switch (op.type()) { case FilterOperation::GRAYSCALE: GetGrayscaleMatrix(1.f - op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::SEPIA: GetSepiaMatrix(1.f - op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::SATURATE: GetSaturateMatrix(op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::HUE_ROTATE: GetHueRotateMatrix(op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::INVERT: GetInvertMatrix(op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::OPACITY: GetOpacityMatrix(op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::BRIGHTNESS: GetBrightnessMatrix(op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::CONTRAST: GetContrastMatrix(op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::BLUR: - image_filter = skia::AdoptRef(SkBlurImageFilter::Create( - op.amount(), op.amount(), image_filter.get())); + image_filter = SkBlurImageFilter::Make(op.amount(), op.amount(), + std::move(image_filter)); break; case FilterOperation::DROP_SHADOW: - image_filter = skia::AdoptRef(SkDropShadowImageFilter::Create( + image_filter = SkDropShadowImageFilter::Make( SkIntToScalar(op.drop_shadow_offset().x()), SkIntToScalar(op.drop_shadow_offset().y()), - SkIntToScalar(op.amount()), - SkIntToScalar(op.amount()), + SkIntToScalar(op.amount()), SkIntToScalar(op.amount()), op.drop_shadow_color(), SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, - image_filter.get())); + std::move(image_filter)); break; case FilterOperation::COLOR_MATRIX: - image_filter = CreateMatrixImageFilter(op.matrix(), image_filter); + image_filter = + CreateMatrixImageFilter(op.matrix(), std::move(image_filter)); break; case FilterOperation::ZOOM: { - skia::RefPtr<SkImageFilter> zoom_filter = - skia::AdoptRef(SkMagnifierImageFilter::Create( - SkRect::MakeXYWH( - (size.width() - (size.width() / op.amount())) / 2.f, - (size.height() - (size.height() / op.amount())) / 2.f, - size.width() / op.amount(), - size.height() / op.amount()), - op.zoom_inset())); - if (image_filter.get()) { + sk_sp<SkImageFilter> zoom_filter(SkMagnifierImageFilter::Make( + SkRect::MakeXYWH( + (size.width() - (size.width() / op.amount())) / 2.f, + (size.height() - (size.height() / op.amount())) / 2.f, + size.width() / op.amount(), size.height() / op.amount()), + op.zoom_inset(), nullptr)); + if (image_filter) { // TODO(ajuma): When there's a 1-input version of // SkMagnifierImageFilter, use that to handle the input filter // instead of using an SkComposeImageFilter. - image_filter = skia::AdoptRef(SkComposeImageFilter::Create( - zoom_filter.get(), image_filter.get())); + image_filter = SkComposeImageFilter::Make(std::move(zoom_filter), + std::move(image_filter)); } else { - image_filter = zoom_filter; + image_filter = std::move(zoom_filter); } break; } case FilterOperation::SATURATING_BRIGHTNESS: GetSaturatingBrightnessMatrix(op.amount(), matrix); - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); break; case FilterOperation::REFERENCE: { if (!op.image_filter()) break; - skia::RefPtr<SkColorFilter> cf; + sk_sp<SkColorFilter> cf; { SkColorFilter* colorfilter_rawptr = NULL; op.image_filter()->asColorFilter(&colorfilter_rawptr); - cf = skia::AdoptRef(colorfilter_rawptr); + cf.reset(colorfilter_rawptr); } if (cf && cf->asColorMatrix(matrix) && !op.image_filter()->getInput(0)) { - image_filter = CreateMatrixImageFilter(matrix, image_filter); + image_filter = + CreateMatrixImageFilter(matrix, std::move(image_filter)); } else if (image_filter) { - image_filter = skia::AdoptRef(SkComposeImageFilter::Create( - op.image_filter().get(), image_filter.get())); + image_filter = SkComposeImageFilter::Make(op.image_filter(), + std::move(image_filter)); } else { image_filter = op.image_filter(); } break; } case FilterOperation::ALPHA_THRESHOLD: { - skia::RefPtr<SkImageFilter> alpha_filter = skia::AdoptRef( - SkAlphaThresholdFilter::Create( - op.region(), op.amount(), op.outer_threshold())); - if (image_filter.get()) { - image_filter = skia::AdoptRef(SkComposeImageFilter::Create( - alpha_filter.get(), image_filter.get())); + sk_sp<SkImageFilter> alpha_filter = SkAlphaThresholdFilter::Make( + op.region(), op.amount(), op.outer_threshold(), nullptr); + if (image_filter) { + image_filter = SkComposeImageFilter::Make(std::move(alpha_filter), + std::move(image_filter)); } else { - image_filter = alpha_filter; + image_filter = std::move(alpha_filter); } break; } diff --git a/chromium/cc/output/render_surface_filters.h b/chromium/cc/output/render_surface_filters.h index bf54986b9c9..e6c6d9f1c18 100644 --- a/chromium/cc/output/render_surface_filters.h +++ b/chromium/cc/output/render_surface_filters.h @@ -8,7 +8,7 @@ #include "base/macros.h" #include "cc/base/cc_export.h" -#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkRefCnt.h" class GrContext; class SkBitmap; @@ -30,9 +30,8 @@ class CC_EXPORT RenderSurfaceFilters { GrContext* gr_context); static FilterOperations Optimize(const FilterOperations& filters); - static skia::RefPtr<SkImageFilter> BuildImageFilter( - const FilterOperations& filters, - const gfx::SizeF& size); + static sk_sp<SkImageFilter> BuildImageFilter(const FilterOperations& filters, + const gfx::SizeF& size); private: DISALLOW_IMPLICIT_CONSTRUCTORS(RenderSurfaceFilters); diff --git a/chromium/cc/output/renderer.h b/chromium/cc/output/renderer.h index 880a139a448..cfda9fe10a5 100644 --- a/chromium/cc/output/renderer.h +++ b/chromium/cc/output/renderer.h @@ -5,8 +5,9 @@ #ifndef CC_OUTPUT_RENDERER_H_ #define CC_OUTPUT_RENDERER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/renderer_capabilities.h" #include "cc/output/renderer_settings.h" @@ -21,7 +22,7 @@ class RenderPassId; class ScopedResource; class Task; -typedef std::vector<scoped_ptr<RenderPass>> RenderPassList; +typedef std::vector<std::unique_ptr<RenderPass>> RenderPassList; struct RendererCapabilitiesImpl { RendererCapabilitiesImpl(); diff --git a/chromium/cc/output/renderer_pixeltest.cc b/chromium/cc/output/renderer_pixeltest.cc index b9472b35ff2..d4f2153d82f 100644 --- a/chromium/cc/output/renderer_pixeltest.cc +++ b/chromium/cc/output/renderer_pixeltest.cc @@ -4,6 +4,7 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include "base/message_loop/message_loop.h" #include "cc/output/gl_renderer.h" @@ -19,6 +20,7 @@ #include "third_party/skia/include/core/SkColorPriv.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" #include "third_party/skia/include/effects/SkColorMatrixFilter.h" @@ -30,9 +32,9 @@ namespace cc { namespace { #if !defined(OS_ANDROID) -scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id, - const gfx::Rect& rect) { - scoped_ptr<RenderPass> pass = RenderPass::Create(); +std::unique_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id, + const gfx::Rect& rect) { + std::unique_ptr<RenderPass> pass = RenderPass::Create(); const gfx::Rect output_rect = rect; const gfx::Rect damage_rect = rect; const gfx::Transform transform_to_root_target; @@ -40,11 +42,11 @@ scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id, return pass; } -scoped_ptr<RenderPass> CreateTestRenderPass( +std::unique_ptr<RenderPass> CreateTestRenderPass( RenderPassId id, const gfx::Rect& rect, const gfx::Transform& transform_to_root_target) { - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); const gfx::Rect output_rect = rect; const gfx::Rect damage_rect = rect; pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); @@ -146,7 +148,8 @@ void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect, render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, premultiplied_alpha, uv_top_left, uv_bottom_right, - background_color, vertex_opacity, flipped, nearest_neighbor); + background_color, vertex_opacity, flipped, nearest_neighbor, + false); } void CreateTestTextureDrawQuad(const gfx::Rect& rect, @@ -180,7 +183,8 @@ void CreateTestTextureDrawQuad(const gfx::Rect& rect, render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, premultiplied_alpha, uv_top_left, uv_bottom_right, - background_color, vertex_opacity, flipped, nearest_neighbor); + background_color, vertex_opacity, flipped, nearest_neighbor, + false); } void CreateTestYUVVideoDrawQuad_FromVideoFrame( @@ -470,6 +474,60 @@ void CreateTestYUVVideoDrawQuad_Solid( video_resource_updater, rect, visible_rect, resource_provider); } +void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state, + media::ColorSpace video_frame_color_space, + const gfx::RectF& tex_coord_rect, + uint8_t y, + uint8_t u, + uint8_t v, + RenderPass* render_pass, + const gfx::Rect& rect, + const gfx::Rect& visible_rect, + ResourceProvider* resource_provider) { + YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601; + if (video_frame_color_space == media::COLOR_SPACE_JPEG) { + color_space = YUVVideoDrawQuad::JPEG; + } + + const gfx::Rect opaque_rect(0, 0, 0, 0); + const gfx::Size ya_tex_size = rect.size(); + const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize( + media::PIXEL_FORMAT_NV12, media::VideoFrame::kUVPlane, rect.size()); + + ResourceId y_resource = resource_provider->CreateResource( + rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, + resource_provider->YuvResourceFormat(8)); + ResourceId u_resource = resource_provider->CreateResource( + uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888); + ResourceId v_resource = u_resource; + ResourceId a_resource = 0; + + std::vector<uint8_t> y_pixels(ya_tex_size.GetArea(), y); + resource_provider->CopyToResource(y_resource, y_pixels.data(), ya_tex_size); + + // U goes in the R component and V goes in the G component. + uint32_t rgba_pixel = (u << 24) | (v << 16); + std::vector<uint32_t> uv_pixels(uv_tex_size.GetArea(), rgba_pixel); + resource_provider->CopyToResource( + u_resource, reinterpret_cast<uint8_t*>(uv_pixels.data()), uv_tex_size); + + gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(), + tex_coord_rect.y() * ya_tex_size.height(), + tex_coord_rect.width() * ya_tex_size.width(), + tex_coord_rect.height() * ya_tex_size.height()); + gfx::RectF uv_tex_coord_rect(tex_coord_rect.x() * uv_tex_size.width(), + tex_coord_rect.y() * uv_tex_size.height(), + tex_coord_rect.width() * uv_tex_size.width(), + tex_coord_rect.height() * uv_tex_size.height()); + + YUVVideoDrawQuad* yuv_quad = + render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); + yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect, + ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, + uv_tex_size, y_resource, u_resource, v_resource, a_resource, + color_space, 0.0f, 1.0f); +} + typedef ::testing::Types<GLRenderer, SoftwareRenderer, GLRendererWithExpandedViewport, @@ -523,7 +581,7 @@ TYPED_TEST(RendererPixelTest, SimpleGreenRect) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -546,7 +604,7 @@ TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) { gfx::Rect small_rect(100, 100); RenderPassId child_id(2, 1); - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_id, small_rect, gfx::Transform()); SharedQuadState* child_shared_state = @@ -557,7 +615,7 @@ TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) { color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false); RenderPassId root_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRenderPass(root_id, rect, gfx::Transform()); SharedQuadState* root_shared_state = @@ -583,7 +641,7 @@ TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -613,7 +671,7 @@ TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* texture_quad_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -712,7 +770,7 @@ class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> { return render_pass_->CreateAndAppendDrawQuad<T>(); } - scoped_ptr<RenderPass> render_pass_; + std::unique_ptr<RenderPass> render_pass_; gfx::Rect viewport_rect_; SharedQuadState* front_quad_state_; SharedQuadState* back_quad_state_; @@ -735,8 +793,8 @@ class IntersectingQuadGLPixelTest } protected: - scoped_ptr<VideoResourceUpdater> video_resource_updater_; - scoped_ptr<VideoResourceUpdater> video_resource_updater2_; + std::unique_ptr<VideoResourceUpdater> video_resource_updater_; + std::unique_ptr<VideoResourceUpdater> video_resource_updater2_; }; template <typename TypeParam> @@ -817,7 +875,7 @@ TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) { SkPaint green_paint; green_paint.setColor(SK_ColorGREEN); - scoped_ptr<FakeRecordingSource> blue_recording = + std::unique_ptr<FakeRecordingSource> blue_recording = FakeRecordingSource::CreateFilledRecordingSource(this->quad_rect_.size()); blue_recording->add_draw_rect_with_paint(outer_rect, black_paint); blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint); @@ -833,7 +891,7 @@ TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) { this->quad_rect_.size(), false, RGBA_8888, this->quad_rect_, 1.f, blue_raster_source); - scoped_ptr<FakeRecordingSource> green_recording = + std::unique_ptr<FakeRecordingSource> green_recording = FakeRecordingSource::CreateFilledRecordingSource(this->quad_rect_.size()); green_recording->add_draw_rect_with_paint(outer_rect, green_paint); green_recording->add_draw_rect_with_paint(inner_rect, black_paint); @@ -856,11 +914,11 @@ TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) { this->SetupQuadStateAndRenderPass(); RenderPassId child_pass_id1(2, 2); RenderPassId child_pass_id2(2, 3); - scoped_ptr<RenderPass> child_pass1 = + std::unique_ptr<RenderPass> child_pass1 = CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform()); SharedQuadState* child1_quad_state = CreateTestSharedQuadState( gfx::Transform(), this->quad_rect_, child_pass1.get()); - scoped_ptr<RenderPass> child_pass2 = + std::unique_ptr<RenderPass> child_pass2 = CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform()); SharedQuadState* child2_quad_state = CreateTestSharedQuadState( gfx::Transform(), this->quad_rect_, child_pass2.get()); @@ -920,7 +978,7 @@ TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -951,7 +1009,7 @@ TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* texture_quad_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -988,7 +1046,7 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest { gfx::Rect rect(200, 200); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); // Scale the video up so that bilinear filtering kicks in to sample more // than just nearest neighbor would. @@ -1025,7 +1083,7 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest { output_surface_->context_provider(), resource_provider_.get())); } - scoped_ptr<VideoResourceUpdater> video_resource_updater_; + std::unique_ptr<VideoResourceUpdater> video_resource_updater_; }; class VideoGLRendererPixelHiLoTest @@ -1036,7 +1094,7 @@ TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -1062,7 +1120,7 @@ TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) { this->device_viewport_size_.height() * 1.5); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get()); @@ -1085,7 +1143,7 @@ TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -1108,7 +1166,7 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -1136,7 +1194,7 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -1155,6 +1213,28 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) { FuzzyPixelOffByOneComparator(true))); } +TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) { + gfx::Rect rect(this->device_viewport_size_); + + RenderPassId id(1, 1); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + + SharedQuadState* shared_state = + CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + + // YUV of (149,43,21) should be green (0,255,0) in RGB. + CreateTestYUVVideoDrawQuad_NV12( + shared_state, media::COLOR_SPACE_JPEG, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), + 149, 43, 21, pass.get(), rect, rect, resource_provider_.get()); + + RenderPassList pass_list; + pass_list.push_back(std::move(pass)); + + EXPECT_TRUE(this->RunPixelTest(&pass_list, + base::FilePath(FILE_PATH_LITERAL("green.png")), + FuzzyPixelOffByOneComparator(true))); +} + // Test that a YUV video doesn't bleed outside of its tex coords when the // tex coord rect is only a partial subrectangle of the coded contents. TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) { @@ -1179,7 +1259,7 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -1203,7 +1283,7 @@ TEST_F(VideoGLRendererPixelHiLoTest, SimpleYUVARect) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -1230,7 +1310,7 @@ TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -1257,13 +1337,13 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -1313,12 +1393,10 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) { matrix[13] = matrix[14] = 0; matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; matrix[18] = 1; - sk_sp<SkColorFilter> color_filter = - SkColorFilter::MakeMatrixFilterRowMajor255(matrix); - skia::RefPtr<SkImageFilter> filter = skia::AdoptRef( - SkColorFilterImageFilter::Create(color_filter.get(), NULL)); FilterOperations filters; - filters.Append(FilterOperation::CreateReferenceFilter(filter)); + filters.Append( + FilterOperation::CreateReferenceFilter(SkColorFilterImageFilter::Make( + SkColorFilter::MakeMatrixFilterRowMajor255(matrix), nullptr))); RenderPassDrawQuad* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); @@ -1349,13 +1427,13 @@ TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -1420,13 +1498,13 @@ TYPED_TEST(RendererPixelTest, FastPassFilterChain) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -1493,13 +1571,13 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -1552,12 +1630,10 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) { matrix[14] = 1.5f; matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; matrix[18] = 1; - sk_sp<SkColorFilter> color_filter = - SkColorFilter::MakeMatrixFilterRowMajor255(matrix); - skia::RefPtr<SkImageFilter> filter = skia::AdoptRef( - SkColorFilterImageFilter::Create(color_filter.get(), NULL)); FilterOperations filters; - filters.Append(FilterOperation::CreateReferenceFilter(filter)); + filters.Append( + FilterOperation::CreateReferenceFilter(SkColorFilterImageFilter::Make( + SkColorFilter::MakeMatrixFilterRowMajor255(matrix), nullptr))); RenderPassDrawQuad* render_pass_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); @@ -1589,13 +1665,13 @@ TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -1638,13 +1714,13 @@ TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -1702,14 +1778,14 @@ TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( gfx::Transform(), viewport_rect, root_pass.get()); RenderPassId child_pass_id(2, 2); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( gfx::Transform(), viewport_rect, child_pass.get()); @@ -1795,14 +1871,14 @@ TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad2) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( gfx::Transform(), viewport_rect, root_pass.get()); RenderPassId child_pass_id(2, 2); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( gfx::Transform(), viewport_rect, child_pass.get()); @@ -1886,7 +1962,7 @@ class RendererPixelTestWithBackgroundFilter gfx::Rect device_viewport_rect(this->device_viewport_size_); RenderPassId root_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_id, device_viewport_rect); root_pass->has_transparent_background = false; @@ -1894,7 +1970,7 @@ class RendererPixelTestWithBackgroundFilter RenderPassId filter_pass_id(2, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> filter_pass = CreateTestRenderPass( + std::unique_ptr<RenderPass> filter_pass = CreateTestRenderPass( filter_pass_id, filter_pass_layer_rect_, transform_to_root); // A non-visible quad in the filtering render pass. @@ -2045,7 +2121,7 @@ TEST_F(ExternalStencilPixelTest, StencilTestEnabled) { // clipped to the bottom left and top right corners by the external stencil. gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* blue_shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); SolidColorDrawQuad* blue = @@ -2068,7 +2144,7 @@ TEST_F(ExternalStencilPixelTest, StencilTestDisabled) { // buffer should be ignored. gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* green_shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); SolidColorDrawQuad* green = @@ -2092,14 +2168,14 @@ TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); root_pass->has_transparent_background = false; RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -2137,7 +2213,7 @@ TEST_F(ExternalStencilPixelTest, DeviceClip) { // clipped to the bottom right corner by the device clip. gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* blue_shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); SolidColorDrawQuad* blue = @@ -2157,7 +2233,7 @@ TEST_F(GLRendererPixelTest, AntiAliasing) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); gfx::Transform red_quad_to_target_transform; red_quad_to_target_transform.Rotate(10); @@ -2200,7 +2276,7 @@ TEST_F(GLRendererPixelTest, AxisAligned) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, rect, transform_to_root); gfx::Transform red_quad_to_target_transform; @@ -2247,7 +2323,7 @@ TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, rect, transform_to_root); gfx::Transform hole_quad_to_target_transform; @@ -2282,7 +2358,7 @@ TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) { TEST_F(GLRendererPixelTest, AntiAliasingPerspective) { gfx::Rect rect(this->device_viewport_size_); - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(RenderPassId(1, 1), rect); gfx::Rect red_rect(0, 0, 180, 500); @@ -2325,7 +2401,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); // One clipped blue quad in the lower right corner. Outside the clip @@ -2333,7 +2409,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) { gfx::Rect blue_rect(gfx::Size(100, 100)); gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50)); - scoped_ptr<FakeRecordingSource> blue_recording = + std::unique_ptr<FakeRecordingSource> blue_recording = FakeRecordingSource::CreateFilledRecordingSource(blue_rect.size()); SkPaint red_paint; red_paint.setColor(SK_ColorRED); @@ -2364,7 +2440,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) { 1.f, std::move(blue_raster_source)); // One viewport-filling green quad. - scoped_ptr<FakeRecordingSource> green_recording = + std::unique_ptr<FakeRecordingSource> green_recording = FakeRecordingSource::CreateFilledRecordingSource(viewport.size()); SkPaint green_paint; green_paint.setColor(SK_ColorGREEN); @@ -2401,11 +2477,11 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); // One viewport-filling 0.5-opacity green quad. - scoped_ptr<FakeRecordingSource> green_recording = + std::unique_ptr<FakeRecordingSource> green_recording = FakeRecordingSource::CreateFilledRecordingSource(viewport.size()); SkPaint green_paint; green_paint.setColor(SK_ColorGREEN); @@ -2426,7 +2502,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) { texture_format, viewport, 1.f, green_raster_source.get()); // One viewport-filling white quad. - scoped_ptr<FakeRecordingSource> white_recording = + std::unique_ptr<FakeRecordingSource> white_recording = FakeRecordingSource::CreateFilledRecordingSource(viewport.size()); SkPaint white_paint; white_paint.setColor(SK_ColorWHITE); @@ -2483,7 +2559,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(2, 2); @@ -2493,13 +2569,13 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) { canvas->drawPoint(0, 1, SK_ColorBLUE); canvas->drawPoint(1, 0, SK_ColorBLUE); canvas->drawPoint(1, 1, SK_ColorGREEN); - skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot()); - scoped_ptr<FakeRecordingSource> recording = + std::unique_ptr<FakeRecordingSource> recording = FakeRecordingSource::CreateFilledRecordingSource(viewport.size()); SkPaint paint; paint.setFilterQuality(kLow_SkFilterQuality); - recording->add_draw_image_with_paint(image.get(), gfx::Point(), paint); + recording->add_draw_image_with_paint(surface->makeImageSnapshot(), + gfx::Point(), paint); recording->Rerecord(); scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFromRecordingSource(recording.get(), false); @@ -2532,7 +2608,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(2, 2); @@ -2542,13 +2618,13 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) { canvas->drawPoint(0, 1, SK_ColorBLUE); canvas->drawPoint(1, 0, SK_ColorBLUE); canvas->drawPoint(1, 1, SK_ColorGREEN); - skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot()); - scoped_ptr<FakeRecordingSource> recording = + std::unique_ptr<FakeRecordingSource> recording = FakeRecordingSource::CreateFilledRecordingSource(viewport.size()); SkPaint paint; paint.setFilterQuality(kLow_SkFilterQuality); - recording->add_draw_image_with_paint(image.get(), gfx::Point(), paint); + recording->add_draw_image_with_paint(surface->makeImageSnapshot(), + gfx::Point(), paint); recording->Rerecord(); scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFromRecordingSource(recording.get(), false); @@ -2600,7 +2676,7 @@ TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); gfx::Transform quad_to_target_transform; @@ -2650,7 +2726,7 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); gfx::Transform quad_to_target_transform; @@ -2661,7 +2737,7 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) { TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false, gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK, - vertex_opacity, false, nearest_neighbor); + vertex_opacity, false, nearest_neighbor, false); RenderPassList pass_list; pass_list.push_back(std::move(pass)); @@ -2701,7 +2777,7 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); gfx::Transform quad_to_target_transform; @@ -2712,7 +2788,7 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) { TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false, gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK, - vertex_opacity, false, nearest_neighbor); + vertex_opacity, false, nearest_neighbor, false); RenderPassList pass_list; pass_list.push_back(std::move(pass)); @@ -2733,7 +2809,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) { RenderPassId id(1, 1); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> pass = + std::unique_ptr<RenderPass> pass = CreateTestRenderPass(id, viewport, transform_to_root); // As scaling up the blue checkerboards will cause sampling on the GPU, @@ -2744,7 +2820,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) { gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100)); gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20)); - scoped_ptr<FakeRecordingSource> green_recording = + std::unique_ptr<FakeRecordingSource> green_recording = FakeRecordingSource::CreateFilledRecordingSource(viewport.size()); SkPaint red_paint; @@ -2810,7 +2886,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) { blue_layer_rect1.Inset(inset, inset, inset, inset); blue_layer_rect2.Inset(inset, inset, inset, inset); - scoped_ptr<FakeRecordingSource> recording = + std::unique_ptr<FakeRecordingSource> recording = FakeRecordingSource::CreateFilledRecordingSource(layer_rect.size()); Region outside(layer_rect); @@ -2877,13 +2953,13 @@ TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -2925,13 +3001,13 @@ TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -2973,13 +3049,13 @@ TEST_F(GLRendererPixelTest, CheckReadbackSubset) { gfx::Rect viewport_rect(this->device_viewport_size_); RenderPassId root_pass_id(1, 1); - scoped_ptr<RenderPass> root_pass = + std::unique_ptr<RenderPass> root_pass = CreateTestRootRenderPass(root_pass_id, viewport_rect); RenderPassId child_pass_id(2, 2); gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - scoped_ptr<RenderPass> child_pass = + std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); gfx::Transform quad_to_target_transform; @@ -3030,7 +3106,7 @@ TEST_F(GLRendererPixelTest, TextureQuadBatching) { gfx::Rect rect(this->device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); SharedQuadState* shared_state = CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); @@ -3091,7 +3167,7 @@ TEST_F(GLRendererPixelTest, TextureQuadBatching) { texture_quad->SetNew(shared_state, layer_rect, layer_rect, layer_rect, resource, true, uv_rect.origin(), uv_rect.bottom_right(), SK_ColorWHITE, - vertex_opacity, false, false); + vertex_opacity, false, false, false); } } diff --git a/chromium/cc/output/renderer_unittest.cc b/chromium/cc/output/renderer_unittest.cc index 1648aece04a..67d13caf40a 100644 --- a/chromium/cc/output/renderer_unittest.cc +++ b/chromium/cc/output/renderer_unittest.cc @@ -39,7 +39,8 @@ void TestOutputSurface::SwapBuffers(CompositorFrame* frame) { class MockContextProvider : public TestContextProvider { public: - explicit MockContextProvider(scoped_ptr<TestWebGraphicsContext3D> context) + explicit MockContextProvider( + std::unique_ptr<TestWebGraphicsContext3D> context) : TestContextProvider(std::move(context)) {} MOCK_METHOD0(DeleteCachedResources, void()); @@ -48,13 +49,13 @@ class MockContextProvider : public TestContextProvider { }; template <class T> -scoped_ptr<Renderer> CreateRenderer(RendererClient* client, - const RendererSettings* settings, - OutputSurface* output_surface, - ResourceProvider* resource_provider); +std::unique_ptr<Renderer> CreateRenderer(RendererClient* client, + const RendererSettings* settings, + OutputSurface* output_surface, + ResourceProvider* resource_provider); template <> -scoped_ptr<Renderer> CreateRenderer<DelegatingRenderer>( +std::unique_ptr<Renderer> CreateRenderer<DelegatingRenderer>( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, @@ -64,7 +65,7 @@ scoped_ptr<Renderer> CreateRenderer<DelegatingRenderer>( } template <> -scoped_ptr<Renderer> CreateRenderer<GLRenderer>( +std::unique_ptr<Renderer> CreateRenderer<GLRenderer>( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, @@ -93,9 +94,9 @@ class RendererTest : public ::testing::Test { RendererSettings tree_settings_; FakeOutputSurfaceClient output_surface_client_; scoped_refptr<MockContextProvider> context_provider_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<Renderer> renderer_; + std::unique_ptr<OutputSurface> output_surface_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<Renderer> renderer_; }; typedef ::testing::Types<DelegatingRenderer, GLRenderer> RendererTypes; diff --git a/chromium/cc/output/shader.cc b/chromium/cc/output/shader.cc index 75cac6cbfd6..5df5a3c4d3f 100644 --- a/chromium/cc/output/shader.cc +++ b/chromium/cc/output/shader.cc @@ -133,7 +133,8 @@ static std::string SetFragmentSamplerType(SamplerType requested_type, case SAMPLER_TYPE_EXTERNAL_OES: DCHECK_NE(shader_string.find("SamplerType"), std::string::npos); DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos); - return "#extension GL_OES_EGL_image_external : require\n" + return "#extension GL_OES_EGL_image_external : enable\n" + "#extension GL_NV_EGL_stream_consumer_external : enable\n" "#define SamplerType samplerExternalOES\n" "#define TextureLookup texture2D\n" + shader_string; @@ -2092,6 +2093,72 @@ std::string FragmentShaderYUVVideo::GetShaderBody() { }); } +FragmentShaderNV12Video::FragmentShaderNV12Video() + : y_texture_location_(-1), + uv_texture_location_(-1), + alpha_location_(-1), + yuv_matrix_location_(-1), + yuv_adj_location_(-1), + ya_clamp_rect_location_(-1), + uv_clamp_rect_location_(-1) {} + +void FragmentShaderNV12Video::Init(GLES2Interface* context, + unsigned program, + int* base_uniform_index) { + static const char* uniforms[] = { + "y_texture", "uv_texture", "alpha", "yuv_matrix", + "yuv_adj", "ya_clamp_rect", "uv_clamp_rect"}; + int locations[arraysize(uniforms)]; + + GetProgramUniformLocations(context, program, arraysize(uniforms), uniforms, + locations, base_uniform_index); + y_texture_location_ = locations[0]; + uv_texture_location_ = locations[1]; + alpha_location_ = locations[2]; + yuv_matrix_location_ = locations[3]; + yuv_adj_location_ = locations[4]; + ya_clamp_rect_location_ = locations[5]; + uv_clamp_rect_location_ = locations[6]; +} + +std::string FragmentShaderNV12Video::GetShaderString( + TexCoordPrecision precision, + SamplerType sampler) const { + return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody()); +} + +std::string FragmentShaderNV12Video::GetShaderHead() { + return SHADER0([]() { + precision mediump float; + precision mediump int; + varying TexCoordPrecision vec2 v_yaTexCoord; + varying TexCoordPrecision vec2 v_uvTexCoord; + uniform SamplerType y_texture; + uniform SamplerType uv_texture; + uniform float alpha; + uniform vec3 yuv_adj; + uniform mat3 yuv_matrix; + uniform vec4 ya_clamp_rect; + uniform vec4 uv_clamp_rect; + }); +} + +std::string FragmentShaderNV12Video::GetShaderBody() { + return SHADER0([]() { + void main() { + vec2 ya_clamped = + max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); + float y_raw = TextureLookup(y_texture, ya_clamped).x; + vec2 uv_clamped = + max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); + vec2 uv_unsigned = TextureLookup(uv_texture, uv_clamped).xy; + vec3 yuv = vec3(y_raw, uv_unsigned) + yuv_adj; + vec3 rgb = yuv_matrix * yuv; + gl_FragColor = vec4(rgb, 1.0) * alpha; + } + }); +} + FragmentShaderYUVAVideo::FragmentShaderYUVAVideo() : y_texture_location_(-1), u_texture_location_(-1), diff --git a/chromium/cc/output/shader.h b/chromium/cc/output/shader.h index 88b632e81b4..836c9f57e05 100644 --- a/chromium/cc/output/shader.h +++ b/chromium/cc/output/shader.h @@ -794,6 +794,37 @@ class FragmentShaderYUVVideo : public FragmentTexBlendMode { DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVVideo); }; +class FragmentShaderNV12Video : public FragmentTexBlendMode { + public: + FragmentShaderNV12Video(); + std::string GetShaderString(TexCoordPrecision precision, + SamplerType sampler) const; + static std::string GetShaderHead(); + static std::string GetShaderBody(); + + void Init(gpu::gles2::GLES2Interface* context, + unsigned program, + int* base_uniform_index); + int y_texture_location() const { return y_texture_location_; } + int uv_texture_location() const { return uv_texture_location_; } + int alpha_location() const { return alpha_location_; } + int yuv_matrix_location() const { return yuv_matrix_location_; } + int yuv_adj_location() const { return yuv_adj_location_; } + int ya_clamp_rect_location() const { return ya_clamp_rect_location_; } + int uv_clamp_rect_location() const { return uv_clamp_rect_location_; } + + private: + int y_texture_location_; + int uv_texture_location_; + int alpha_location_; + int yuv_matrix_location_; + int yuv_adj_location_; + int ya_clamp_rect_location_; + int uv_clamp_rect_location_; + + DISALLOW_COPY_AND_ASSIGN(FragmentShaderNV12Video); +}; + class FragmentShaderYUVAVideo : public FragmentTexBlendMode { public: FragmentShaderYUVAVideo(); diff --git a/chromium/cc/output/shader_unittest.cc b/chromium/cc/output/shader_unittest.cc index 675e47fb26b..78850184ad2 100644 --- a/chromium/cc/output/shader_unittest.cc +++ b/chromium/cc/output/shader_unittest.cc @@ -15,8 +15,8 @@ namespace cc { TEST(ShaderTest, HighpThresholds) { // The test context always uses a mediump precision of 10 bits which // corresponds to a native highp threshold of 2^10 = 1024 - scoped_ptr<TestWebGraphicsContext3D> stub_context = - TestWebGraphicsContext3D::Create(); + std::unique_ptr<TestWebGraphicsContext3D> stub_context = + TestWebGraphicsContext3D::Create(); TestGLES2Interface stub_gl(stub_context.get()); int threshold_cache = 0; diff --git a/chromium/cc/output/software_output_device.h b/chromium/cc/output/software_output_device.h index 397229742fc..109fc90f387 100644 --- a/chromium/cc/output/software_output_device.h +++ b/chromium/cc/output/software_output_device.h @@ -5,8 +5,9 @@ #ifndef CC_OUTPUT_SOFTWARE_OUTPUT_DEVICE_H_ #define CC_OUTPUT_SOFTWARE_OUTPUT_DEVICE_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "third_party/skia/include/core/SkSurface.h" #include "ui/gfx/geometry/rect.h" @@ -60,7 +61,7 @@ class CC_EXPORT SoftwareOutputDevice { float scale_factor_; gfx::Rect damage_rect_; sk_sp<SkSurface> surface_; - scoped_ptr<gfx::VSyncProvider> vsync_provider_; + std::unique_ptr<gfx::VSyncProvider> vsync_provider_; private: DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDevice); diff --git a/chromium/cc/output/software_renderer.cc b/chromium/cc/output/software_renderer.cc index 51c75014360..13d13418b20 100644 --- a/chromium/cc/output/software_renderer.cc +++ b/chromium/cc/output/software_renderer.cc @@ -4,6 +4,7 @@ #include "cc/output/software_renderer.h" +#include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "cc/base/math_util.h" #include "cc/output/compositor_frame.h" @@ -51,24 +52,28 @@ bool IsScaleAndIntegerTranslate(const SkMatrix& matrix) { } // anonymous namespace -scoped_ptr<SoftwareRenderer> SoftwareRenderer::Create( +std::unique_ptr<SoftwareRenderer> SoftwareRenderer::Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, - ResourceProvider* resource_provider) { - return make_scoped_ptr(new SoftwareRenderer( - client, settings, output_surface, resource_provider)); + ResourceProvider* resource_provider, + bool use_image_hijack_canvas) { + return base::WrapUnique(new SoftwareRenderer(client, settings, output_surface, + resource_provider, + use_image_hijack_canvas)); } SoftwareRenderer::SoftwareRenderer(RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, - ResourceProvider* resource_provider) + ResourceProvider* resource_provider, + bool use_image_hijack_canvas) : DirectRenderer(client, settings, output_surface, resource_provider), is_scissor_enabled_(false), is_backbuffer_discarded_(false), output_device_(output_surface->software_device()), - current_canvas_(NULL) { + current_canvas_(nullptr), + use_image_hijack_canvas_(use_image_hijack_canvas) { if (resource_provider_) { capabilities_.max_texture_size = resource_provider_->max_texture_size(); capabilities_.best_texture_format = @@ -97,7 +102,7 @@ void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) { void SoftwareRenderer::FinishDrawingFrame(DrawingFrame* frame) { TRACE_EVENT0("cc", "SoftwareRenderer::FinishDrawingFrame"); current_framebuffer_lock_ = nullptr; - current_framebuffer_canvas_.clear(); + current_framebuffer_canvas_.reset(); current_canvas_ = NULL; root_canvas_ = NULL; @@ -137,7 +142,7 @@ void SoftwareRenderer::Finish() {} void SoftwareRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) { DCHECK(!output_surface_->HasExternalStencilTest()); current_framebuffer_lock_ = nullptr; - current_framebuffer_canvas_.clear(); + current_framebuffer_canvas_.reset(); current_canvas_ = root_canvas_; } @@ -149,11 +154,11 @@ bool SoftwareRenderer::BindFramebufferToTexture( // Explicitly release lock, otherwise we can crash when try to lock // same texture again. current_framebuffer_lock_ = nullptr; - current_framebuffer_lock_ = make_scoped_ptr( - new ResourceProvider::ScopedWriteLockSoftware( + current_framebuffer_lock_ = + base::WrapUnique(new ResourceProvider::ScopedWriteLockSoftware( resource_provider_, texture->id())); current_framebuffer_canvas_ = - skia::AdoptRef(new SkCanvas(current_framebuffer_lock_->sk_bitmap())); + sk_make_sp<SkCanvas>(current_framebuffer_lock_->sk_bitmap()); current_canvas_ = current_framebuffer_canvas_.get(); return true; } @@ -316,7 +321,6 @@ void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame, NOTREACHED(); break; case DrawQuad::INVALID: - case DrawQuad::IO_SURFACE_CONTENT: case DrawQuad::YUV_VIDEO_CONTENT: case DrawQuad::STREAM_VIDEO_CONTENT: DrawUnsupportedQuad(frame, quad); @@ -368,6 +372,7 @@ void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame, RasterSource::PlaybackSettings playback_settings; playback_settings.playback_to_shared_canvas = true; + playback_settings.use_image_hijack_canvas = use_image_hijack_canvas_; 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 @@ -491,21 +496,36 @@ void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame, gfx::RectF(quad->visible_rect))); SkRect content_rect = SkRect::MakeWH(quad->rect.width(), quad->rect.height()); - SkMatrix content_mat; - content_mat.setRectToRect(content_rect, dest_rect, - SkMatrix::kFill_ScaleToFit); - const SkBitmap* content = lock.sk_bitmap(); - skia::RefPtr<SkImage> filter_image; + sk_sp<SkImage> filter_image; if (!quad->filters.IsEmpty()) { - skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( + sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( quad->filters, gfx::SizeF(content_texture->size())); - // TODO(ajuma): Apply the filter in the same pass as the content where - // possible (e.g. when there's no origin offset). See crbug.com/308201. - filter_image = ApplyImageFilter(filter.get(), quad, content); + if (filter) { + SkIRect result_rect; + // TODO(ajuma): Apply the filter in the same pass as the content where + // possible (e.g. when there's no origin offset). See crbug.com/308201. + filter_image = + ApplyImageFilter(filter.get(), quad, *content, &result_rect); + if (result_rect.isEmpty()) { + return; + } + if (filter_image) { + gfx::RectF rect = gfx::SkRectToRectF(SkRect::Make(result_rect)); + dest_rect = dest_visible_rect = + gfx::RectFToSkRect(MathUtil::ScaleRectProportional( + QuadVertexRect(), gfx::RectF(quad->rect), rect)); + content_rect = + SkRect::MakeWH(result_rect.width(), result_rect.height()); + } + } } + SkMatrix content_mat; + content_mat.setRectToRect(content_rect, dest_rect, + SkMatrix::kFill_ScaleToFit); + sk_sp<SkShader> shader; if (!filter_image) { shader = @@ -516,9 +536,9 @@ void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame, SkShader::kClamp_TileMode, &content_mat); } - scoped_ptr<ResourceProvider::ScopedReadLockSoftware> mask_lock; + std::unique_ptr<ResourceProvider::ScopedReadLockSoftware> mask_lock; if (quad->mask_resource_id()) { - mask_lock = scoped_ptr<ResourceProvider::ScopedReadLockSoftware>( + mask_lock = std::unique_ptr<ResourceProvider::ScopedReadLockSoftware>( new ResourceProvider::ScopedReadLockSoftware(resource_provider_, quad->mask_resource_id())); @@ -574,13 +594,13 @@ void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame, void SoftwareRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - scoped_ptr<CopyOutputRequest> request) { + std::unique_ptr<CopyOutputRequest> request) { gfx::Rect copy_rect = frame->current_render_pass->output_rect; if (request->has_area()) copy_rect.Intersect(request->area()); gfx::Rect window_copy_rect = MoveFromDrawToWindowSpace(frame, copy_rect); - scoped_ptr<SkBitmap> bitmap(new SkBitmap); + std::unique_ptr<SkBitmap> bitmap(new SkBitmap); bitmap->setInfo(SkImageInfo::MakeN32Premul(window_copy_rect.width(), window_copy_rect.height())); current_canvas_->readPixels( @@ -627,27 +647,44 @@ bool SoftwareRenderer::ShouldApplyBackgroundFilters( return true; } -skia::RefPtr<SkImage> SoftwareRenderer::ApplyImageFilter( +// If non-null, auto_bounds will be filled with the automatically-computed +// destination bounds. If null, the output will be the same size as the +// input bitmap. +sk_sp<SkImage> SoftwareRenderer::ApplyImageFilter( SkImageFilter* filter, const RenderPassDrawQuad* quad, - const SkBitmap* to_filter) const { + const SkBitmap& to_filter, + SkIRect* auto_bounds) const { if (!filter) return nullptr; + SkMatrix local_matrix; + local_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); + SkIRect dst_rect; + if (auto_bounds) { + dst_rect = + filter->filterBounds(gfx::RectToSkIRect(quad->rect), local_matrix, + SkImageFilter::kForward_MapDirection); + *auto_bounds = dst_rect; + } else { + dst_rect = to_filter.bounds(); + } + SkImageInfo dst_info = - SkImageInfo::MakeN32Premul(to_filter->width(), to_filter->height()); + SkImageInfo::MakeN32Premul(dst_rect.width(), dst_rect.height()); sk_sp<SkSurface> surface = SkSurface::MakeRaster(dst_info); - SkMatrix localM; - localM.setTranslate(SkIntToScalar(-quad->rect.origin().x()), - SkIntToScalar(-quad->rect.origin().y())); - localM.preScale(quad->filters_scale.x(), quad->filters_scale.y()); + if (!surface) { + return nullptr; + } SkPaint paint; - paint.setImageFilter(filter->makeWithLocalMatrix(localM)); - surface->getCanvas()->drawBitmap(*to_filter, 0, 0, &paint); + paint.setImageFilter(filter->makeWithLocalMatrix(local_matrix)); + surface->getCanvas()->translate(-dst_rect.x(), -dst_rect.y()); + surface->getCanvas()->drawBitmap(to_filter, quad->rect.x(), quad->rect.y(), + &paint); - return skia::AdoptRef(surface->newImageSnapshot()); + return surface->makeImageSnapshot(); } SkBitmap SoftwareRenderer::GetBackdropBitmap( @@ -707,11 +744,11 @@ sk_sp<SkShader> SoftwareRenderer::GetBackgroundFilterShader( // Draw what's behind, and apply the filter to it. SkBitmap backdrop_bitmap = GetBackdropBitmap(backdrop_rect); - skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( + sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( quad->background_filters, gfx::SizeF(backdrop_bitmap.width(), backdrop_bitmap.height())); - skia::RefPtr<SkImage> filter_backdrop_image = - ApplyImageFilter(filter.get(), quad, &backdrop_bitmap); + sk_sp<SkImage> filter_backdrop_image = + ApplyImageFilter(filter.get(), quad, backdrop_bitmap, nullptr); if (!filter_backdrop_image) return nullptr; diff --git a/chromium/cc/output/software_renderer.h b/chromium/cc/output/software_renderer.h index 38cf2a9824e..9323358d8ce 100644 --- a/chromium/cc/output/software_renderer.h +++ b/chromium/cc/output/software_renderer.h @@ -26,11 +26,12 @@ class TileDrawQuad; class CC_EXPORT SoftwareRenderer : public DirectRenderer { public: - static scoped_ptr<SoftwareRenderer> Create( + static std::unique_ptr<SoftwareRenderer> Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, - ResourceProvider* resource_provider); + ResourceProvider* resource_provider, + bool use_image_hijack_canvas); ~SoftwareRenderer() override; const RendererCapabilitiesImpl& Capabilities() const override; @@ -58,12 +59,13 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { void EnsureScissorTestDisabled() override; void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - scoped_ptr<CopyOutputRequest> request) override; + std::unique_ptr<CopyOutputRequest> request) override; SoftwareRenderer(RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, - ResourceProvider* resource_provider); + ResourceProvider* resource_provider, + bool use_image_hijack_canvas); void DidChangeVisibility() override; @@ -88,9 +90,10 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { void DrawUnsupportedQuad(const DrawingFrame* frame, const DrawQuad* quad); bool ShouldApplyBackgroundFilters(const RenderPassDrawQuad* quad) const; - skia::RefPtr<SkImage> ApplyImageFilter(SkImageFilter* filter, - const RenderPassDrawQuad* quad, - const SkBitmap* to_filter) const; + sk_sp<SkImage> ApplyImageFilter(SkImageFilter* filter, + const RenderPassDrawQuad* quad, + const SkBitmap& to_filter, + SkIRect* auto_bounds) const; gfx::Rect GetBackdropBoundingBoxForRenderPassQuad( const DrawingFrame* frame, const RenderPassDrawQuad* quad, @@ -110,9 +113,16 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { SkCanvas* root_canvas_; SkCanvas* current_canvas_; SkPaint current_paint_; - scoped_ptr<ResourceProvider::ScopedWriteLockSoftware> + std::unique_ptr<ResourceProvider::ScopedWriteLockSoftware> current_framebuffer_lock_; - skia::RefPtr<SkCanvas> current_framebuffer_canvas_; + sk_sp<SkCanvas> current_framebuffer_canvas_; + + // Indicates whether content rasterization should happen through an + // ImageHijackCanvas, which causes image decodes to be managed by an + // ImageDecodeController. We set this to false during resourceless software + // draw when a GPU ImageDecodeController is in use, as software rasterization + // cannot use the GPU IDC. + const bool use_image_hijack_canvas_; DISALLOW_COPY_AND_ASSIGN(SoftwareRenderer); }; diff --git a/chromium/cc/output/software_renderer_unittest.cc b/chromium/cc/output/software_renderer_unittest.cc index 7f890c98e47..b5fe93783fb 100644 --- a/chromium/cc/output/software_renderer_unittest.cc +++ b/chromium/cc/output/software_renderer_unittest.cc @@ -6,6 +6,7 @@ #include <stdint.h> +#include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/output/copy_output_request.h" @@ -32,7 +33,7 @@ namespace { class SoftwareRendererTest : public testing::Test, public RendererClient { public: void InitializeRenderer( - scoped_ptr<SoftwareOutputDevice> software_output_device) { + std::unique_ptr<SoftwareOutputDevice> software_output_device) { output_surface_ = FakeOutputSurface::CreateSoftware(std::move(software_output_device)); CHECK(output_surface_->BindToClient(&output_surface_client_)); @@ -41,7 +42,8 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { resource_provider_ = FakeResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get()); renderer_ = SoftwareRenderer::Create( - this, &settings_, output_surface_.get(), resource_provider()); + this, &settings_, output_surface_.get(), resource_provider(), + true /* use_image_hijack_canvas */); } ResourceProvider* resource_provider() const { @@ -53,10 +55,10 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { // RendererClient implementation. void SetFullRootLayerDamage() override {} - scoped_ptr<SkBitmap> DrawAndCopyOutput(RenderPassList* list, - float device_scale_factor, - gfx::Rect device_viewport_rect) { - scoped_ptr<SkBitmap> bitmap_result; + std::unique_ptr<SkBitmap> DrawAndCopyOutput(RenderPassList* list, + float device_scale_factor, + gfx::Rect device_viewport_rect) { + std::unique_ptr<SkBitmap> bitmap_result; base::RunLoop loop; list->back()->copy_requests.push_back( @@ -74,9 +76,9 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { return bitmap_result; } - static void SaveBitmapResult(scoped_ptr<SkBitmap>* bitmap_result, + static void SaveBitmapResult(std::unique_ptr<SkBitmap>* bitmap_result, const base::Closure& quit_closure, - scoped_ptr<CopyOutputResult> result) { + std::unique_ptr<CopyOutputResult> result) { DCHECK(result->HasBitmap()); *bitmap_result = result->TakeBitmap(); quit_closure.Run(); @@ -85,10 +87,10 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { protected: RendererSettings settings_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> output_surface_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<SoftwareRenderer> renderer_; + std::unique_ptr<FakeOutputSurface> output_surface_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<SoftwareRenderer> renderer_; }; TEST_F(SoftwareRendererTest, SolidColorQuad) { @@ -98,10 +100,10 @@ TEST_F(SoftwareRendererTest, SolidColorQuad) { gfx::Rect inner_rect(gfx::Point(1, 1), inner_size); gfx::Rect visible_rect(gfx::Point(1, 2), gfx::Size(98, 97)); - InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice)); + InitializeRenderer(base::WrapUnique(new SoftwareOutputDevice)); RenderPassId root_render_pass_id = RenderPassId(1, 1); - scoped_ptr<RenderPass> root_render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> root_render_pass = RenderPass::Create(); root_render_pass->SetNew( root_render_pass_id, outer_rect, outer_rect, gfx::Transform()); SharedQuadState* shared_quad_state = @@ -129,7 +131,7 @@ TEST_F(SoftwareRendererTest, SolidColorQuad) { float device_scale_factor = 1.f; gfx::Rect device_viewport_rect(outer_size); - scoped_ptr<SkBitmap> output = + std::unique_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(outer_rect.width(), output->info().width()); EXPECT_EQ(outer_rect.height(), output->info().height()); @@ -148,7 +150,7 @@ TEST_F(SoftwareRendererTest, TileQuad) { gfx::Size inner_size(98, 98); gfx::Rect outer_rect(outer_size); gfx::Rect inner_rect(gfx::Point(1, 1), inner_size); - InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice)); + InitializeRenderer(base::WrapUnique(new SoftwareOutputDevice)); ResourceId resource_yellow = resource_provider()->CreateResource( outer_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); @@ -172,7 +174,7 @@ TEST_F(SoftwareRendererTest, TileQuad) { gfx::Rect root_rect = outer_rect; RenderPassId root_render_pass_id = RenderPassId(1, 1); - scoped_ptr<RenderPass> root_render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> root_render_pass = RenderPass::Create(); root_render_pass->SetNew( root_render_pass_id, root_rect, root_rect, gfx::Transform()); SharedQuadState* shared_quad_state = @@ -201,7 +203,7 @@ TEST_F(SoftwareRendererTest, TileQuad) { float device_scale_factor = 1.f; gfx::Rect device_viewport_rect(outer_size); - scoped_ptr<SkBitmap> output = + std::unique_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(outer_rect.width(), output->info().width()); EXPECT_EQ(outer_rect.height(), output->info().height()); @@ -219,7 +221,7 @@ TEST_F(SoftwareRendererTest, TileQuadVisibleRect) { gfx::Rect tile_rect(tile_size); gfx::Rect visible_rect = tile_rect; visible_rect.Inset(1, 2, 3, 4); - InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice)); + InitializeRenderer(base::WrapUnique(new SoftwareOutputDevice)); ResourceId resource_cyan = resource_provider()->CreateResource( tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); @@ -238,7 +240,7 @@ TEST_F(SoftwareRendererTest, TileQuadVisibleRect) { gfx::Rect root_rect(tile_size); RenderPassId root_render_pass_id = RenderPassId(1, 1); - scoped_ptr<RenderPass> root_render_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> root_render_pass = RenderPass::Create(); root_render_pass->SetNew( root_render_pass_id, root_rect, root_rect, gfx::Transform()); SharedQuadState* shared_quad_state = @@ -263,7 +265,7 @@ TEST_F(SoftwareRendererTest, TileQuadVisibleRect) { float device_scale_factor = 1.f; gfx::Rect device_viewport_rect(tile_size); - scoped_ptr<SkBitmap> output = + std::unique_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(tile_rect.width(), output->info().width()); EXPECT_EQ(tile_rect.height(), output->info().height()); @@ -293,7 +295,7 @@ TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) { gfx::Rect device_viewport_rect(0, 0, 100, 100); settings_.should_clear_root_render_pass = false; - InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice)); + InitializeRenderer(base::WrapUnique(new SoftwareOutputDevice)); RenderPassList list; @@ -305,7 +307,7 @@ TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) { renderer()->DecideRenderPassAllocationsForFrame(list); - scoped_ptr<SkBitmap> output = + std::unique_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(device_viewport_rect.width(), output->info().width()); EXPECT_EQ(device_viewport_rect.height(), output->info().height()); @@ -348,7 +350,7 @@ TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) { TEST_F(SoftwareRendererTest, RenderPassVisibleRect) { float device_scale_factor = 1.f; gfx::Rect device_viewport_rect(0, 0, 100, 100); - InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice)); + InitializeRenderer(base::WrapUnique(new SoftwareOutputDevice)); RenderPassList list; @@ -372,7 +374,7 @@ TEST_F(SoftwareRendererTest, RenderPassVisibleRect) { renderer()->DecideRenderPassAllocationsForFrame(list); - scoped_ptr<SkBitmap> output = + std::unique_ptr<SkBitmap> output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect); EXPECT_EQ(device_viewport_rect.width(), output->info().width()); EXPECT_EQ(device_viewport_rect.height(), output->info().height()); diff --git a/chromium/cc/output/texture_mailbox_deleter.cc b/chromium/cc/output/texture_mailbox_deleter.cc index 1310fe7b44e..ff3480d5f30 100644 --- a/chromium/cc/output/texture_mailbox_deleter.cc +++ b/chromium/cc/output/texture_mailbox_deleter.cc @@ -48,13 +48,14 @@ TextureMailboxDeleter::~TextureMailboxDeleter() { impl_callbacks_.at(i)->Run(gpu::SyncToken(), true); } -scoped_ptr<SingleReleaseCallback> TextureMailboxDeleter::GetReleaseCallback( +std::unique_ptr<SingleReleaseCallback> +TextureMailboxDeleter::GetReleaseCallback( scoped_refptr<ContextProvider> context_provider, unsigned texture_id) { // This callback owns the |context_provider|. It must be destroyed on the impl // thread. Upon destruction of this class, the callback must immediately be // destroyed. - scoped_ptr<SingleReleaseCallback> impl_callback = + std::unique_ptr<SingleReleaseCallback> impl_callback = SingleReleaseCallback::Create(base::Bind( &DeleteTextureOnImplThread, std::move(context_provider), texture_id)); @@ -68,7 +69,7 @@ scoped_ptr<SingleReleaseCallback> TextureMailboxDeleter::GetReleaseCallback( // Provide a callback for the main thread that posts back to the impl // thread. - scoped_ptr<SingleReleaseCallback> main_callback; + std::unique_ptr<SingleReleaseCallback> main_callback; if (impl_task_runner_) { main_callback = SingleReleaseCallback::Create(base::Bind( &PostTaskFromMainToImplThread, impl_task_runner_, run_impl_callback)); diff --git a/chromium/cc/output/texture_mailbox_deleter.h b/chromium/cc/output/texture_mailbox_deleter.h index 3ff91d40ebb..c4fbf0b5136 100644 --- a/chromium/cc/output/texture_mailbox_deleter.h +++ b/chromium/cc/output/texture_mailbox_deleter.h @@ -5,9 +5,9 @@ #ifndef CC_OUTPUT_TEXTURE_MAILBOX_DELETER_H_ #define CC_OUTPUT_TEXTURE_MAILBOX_DELETER_H_ +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" @@ -38,7 +38,7 @@ class CC_EXPORT TextureMailboxDeleter { // due to the compositor shutting down, then the ReleaseCallback will // become a no-op and the texture will be deleted immediately on the // impl thread, along with dropping the reference to the ContextProvider. - scoped_ptr<SingleReleaseCallback> GetReleaseCallback( + std::unique_ptr<SingleReleaseCallback> GetReleaseCallback( scoped_refptr<ContextProvider> context_provider, unsigned texture_id); @@ -50,7 +50,7 @@ class CC_EXPORT TextureMailboxDeleter { bool is_lost); scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_; - std::vector<scoped_ptr<SingleReleaseCallback>> impl_callbacks_; + std::vector<std::unique_ptr<SingleReleaseCallback>> impl_callbacks_; base::WeakPtrFactory<TextureMailboxDeleter> weak_ptr_factory_; }; diff --git a/chromium/cc/output/texture_mailbox_deleter_unittest.cc b/chromium/cc/output/texture_mailbox_deleter_unittest.cc index d17e9c36071..205aede2d51 100644 --- a/chromium/cc/output/texture_mailbox_deleter_unittest.cc +++ b/chromium/cc/output/texture_mailbox_deleter_unittest.cc @@ -5,7 +5,7 @@ #include "cc/output/texture_mailbox_deleter.h" #include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/resources/single_release_callback.h" #include "cc/test/test_context_provider.h" #include "cc/test/test_web_graphics_context_3d.h" @@ -15,7 +15,7 @@ namespace cc { namespace { TEST(TextureMailboxDeleterTest, Destroy) { - scoped_ptr<TextureMailboxDeleter> deleter( + std::unique_ptr<TextureMailboxDeleter> deleter( new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get())); scoped_refptr<TestContextProvider> context_provider = @@ -28,7 +28,7 @@ TEST(TextureMailboxDeleterTest, Destroy) { EXPECT_TRUE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); - scoped_ptr<SingleReleaseCallback> cb = + std::unique_ptr<SingleReleaseCallback> cb = deleter->GetReleaseCallback(context_provider, texture_id); EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); @@ -45,7 +45,8 @@ TEST(TextureMailboxDeleterTest, Destroy) { } TEST(TextureMailboxDeleterTest, NullTaskRunner) { - scoped_ptr<TextureMailboxDeleter> deleter(new TextureMailboxDeleter(nullptr)); + std::unique_ptr<TextureMailboxDeleter> deleter( + new TextureMailboxDeleter(nullptr)); scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); @@ -57,7 +58,7 @@ TEST(TextureMailboxDeleterTest, NullTaskRunner) { EXPECT_TRUE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); - scoped_ptr<SingleReleaseCallback> cb = + std::unique_ptr<SingleReleaseCallback> cb = deleter->GetReleaseCallback(context_provider, texture_id); EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); diff --git a/chromium/cc/output/vulkan_context_provider.h b/chromium/cc/output/vulkan_context_provider.h index 6b50128cdaa..f3d6be0b986 100644 --- a/chromium/cc/output/vulkan_context_provider.h +++ b/chromium/cc/output/vulkan_context_provider.h @@ -6,6 +6,7 @@ #define CC_OUTPUT_VULKAN_CONTEXT_PROVIDER_H_ #include "base/memory/ref_counted.h" +#include "cc/base/cc_export.h" namespace gpu { class VulkanDeviceQueue; @@ -14,7 +15,7 @@ class VulkanDeviceQueue; namespace cc { // The VulkanContextProvider groups sharing of vulkan objects synchronously. -class VulkanContextProvider +class CC_EXPORT VulkanContextProvider : public base::RefCountedThreadSafe<VulkanContextProvider> { public: virtual gpu::VulkanDeviceQueue* GetDeviceQueue() = 0; diff --git a/chromium/cc/output/vulkan_in_process_context_provider.cc b/chromium/cc/output/vulkan_in_process_context_provider.cc index 67e11222134..9d602c42450 100644 --- a/chromium/cc/output/vulkan_in_process_context_provider.cc +++ b/chromium/cc/output/vulkan_in_process_context_provider.cc @@ -4,50 +4,69 @@ #include "cc/output/vulkan_in_process_context_provider.h" -#include <vector> - +#if defined(ENABLE_VULKAN) #include "gpu/vulkan/vulkan_device_queue.h" - -#if defined(VK_USE_PLATFORM_XLIB_KHR) -#include "ui/gfx/x/x11_types.h" -#endif // defined(VK_USE_PLATFORM_XLIB_KHR) +#include "gpu/vulkan/vulkan_implementation.h" +#endif // defined(ENABLE_VULKAN) namespace cc { scoped_refptr<VulkanInProcessContextProvider> VulkanInProcessContextProvider::Create() { +#if defined(ENABLE_VULKAN) + if (!gpu::VulkanSupported()) + return nullptr; + scoped_refptr<VulkanInProcessContextProvider> context_provider( new VulkanInProcessContextProvider); if (!context_provider->Initialize()) return nullptr; return context_provider; +#else + return nullptr; +#endif } bool VulkanInProcessContextProvider::Initialize() { - scoped_ptr<gpu::VulkanDeviceQueue> device_queue(new gpu::VulkanDeviceQueue); - if (device_queue->Initialize( +#if defined(ENABLE_VULKAN) + DCHECK(!device_queue_); + std::unique_ptr<gpu::VulkanDeviceQueue> device_queue( + new gpu::VulkanDeviceQueue); + if (!device_queue->Initialize( gpu::VulkanDeviceQueue::GRAPHICS_QUEUE_FLAG | gpu::VulkanDeviceQueue::PRESENTATION_SUPPORT_QUEUE_FLAG)) { - device_queue_ = std::move(device_queue); - return true; + device_queue->Destroy(); + return false; } + device_queue_ = std::move(device_queue); + return true; +#else return false; +#endif } void VulkanInProcessContextProvider::Destroy() { +#if defined(ENABLE_VULKAN) if (device_queue_) { device_queue_->Destroy(); device_queue_.reset(); } +#endif } gpu::VulkanDeviceQueue* VulkanInProcessContextProvider::GetDeviceQueue() { +#if defined(ENABLE_VULKAN) return device_queue_.get(); +#else + return nullptr; +#endif } VulkanInProcessContextProvider::VulkanInProcessContextProvider() {} -VulkanInProcessContextProvider::~VulkanInProcessContextProvider() {} +VulkanInProcessContextProvider::~VulkanInProcessContextProvider() { + Destroy(); +} } // namespace cc diff --git a/chromium/cc/output/vulkan_in_process_context_provider.h b/chromium/cc/output/vulkan_in_process_context_provider.h index da2d0e03267..c477f2f3eee 100644 --- a/chromium/cc/output/vulkan_in_process_context_provider.h +++ b/chromium/cc/output/vulkan_in_process_context_provider.h @@ -5,7 +5,8 @@ #ifndef CC_OUTPUT_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_ #define CC_OUTPUT_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/output/vulkan_context_provider.h" @@ -22,6 +23,7 @@ class CC_EXPORT VulkanInProcessContextProvider : public VulkanContextProvider { bool Initialize(); void Destroy(); + // VulkanContextProvider implementation gpu::VulkanDeviceQueue* GetDeviceQueue() override; protected: @@ -29,7 +31,11 @@ class CC_EXPORT VulkanInProcessContextProvider : public VulkanContextProvider { ~VulkanInProcessContextProvider() override; private: - scoped_ptr<gpu::VulkanDeviceQueue> device_queue_; +#if defined(ENABLE_VULKAN) + std::unique_ptr<gpu::VulkanDeviceQueue> device_queue_; +#endif + + DISALLOW_COPY_AND_ASSIGN(VulkanInProcessContextProvider); }; } // namespace cc diff --git a/chromium/cc/output/vulkan_renderer.cc b/chromium/cc/output/vulkan_renderer.cc index a285c6566f2..6fc9463781e 100644 --- a/chromium/cc/output/vulkan_renderer.cc +++ b/chromium/cc/output/vulkan_renderer.cc @@ -6,14 +6,14 @@ namespace cc { -scoped_ptr<VulkanRenderer> VulkanRenderer::Create( +std::unique_ptr<VulkanRenderer> VulkanRenderer::Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, ResourceProvider* resource_provider, TextureMailboxDeleter* texture_mailbox_deleter, int highp_threshold_min) { - return scoped_ptr<VulkanRenderer>( + return std::unique_ptr<VulkanRenderer>( new VulkanRenderer(client, settings, output_surface, resource_provider, texture_mailbox_deleter, highp_threshold_min)); } @@ -29,7 +29,8 @@ void VulkanRenderer::Finish() { } void VulkanRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) { - NOTIMPLEMENTED(); + CompositorFrame* compositor_frame = nullptr; + output_surface_->SwapBuffers(compositor_frame); } void VulkanRenderer::ReceiveSwapBuffersAck(const CompositorFrameAck& ack) { @@ -110,7 +111,7 @@ void VulkanRenderer::EnsureBackbuffer() { void VulkanRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - scoped_ptr<CopyOutputRequest> request) { + std::unique_ptr<CopyOutputRequest> request) { NOTIMPLEMENTED(); } diff --git a/chromium/cc/output/vulkan_renderer.h b/chromium/cc/output/vulkan_renderer.h index 1dfbbc78b5b..076a7c87414 100644 --- a/chromium/cc/output/vulkan_renderer.h +++ b/chromium/cc/output/vulkan_renderer.h @@ -13,9 +13,9 @@ namespace cc { class TextureMailboxDeleter; -class VulkanRenderer : public DirectRenderer { +class CC_EXPORT VulkanRenderer : public DirectRenderer { public: - static scoped_ptr<VulkanRenderer> Create( + static std::unique_ptr<VulkanRenderer> Create( RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, @@ -63,7 +63,7 @@ class VulkanRenderer : public DirectRenderer { void EnsureBackbuffer() override; void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, - scoped_ptr<CopyOutputRequest> request) override; + std::unique_ptr<CopyOutputRequest> request) override; private: RendererCapabilitiesImpl capabilities_; diff --git a/chromium/cc/playback/clip_display_item.h b/chromium/cc/playback/clip_display_item.h index 2715ce3cdd0..493e45c7382 100644 --- a/chromium/cc/playback/clip_display_item.h +++ b/chromium/cc/playback/clip_display_item.h @@ -7,9 +7,9 @@ #include <stddef.h> +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/playback/display_item.h" #include "third_party/skia/include/core/SkRRect.h" @@ -38,7 +38,6 @@ class CC_EXPORT ClipDisplayItem : public DisplayItem { size_t ExternalMemoryUsage() const override; int ApproximateOpCount() const { return 1; } - bool IsSuitableForGpuRasterization() const { return true; } private: void SetNew(const gfx::Rect& clip_rect, diff --git a/chromium/cc/playback/clip_path_display_item.cc b/chromium/cc/playback/clip_path_display_item.cc index 64ad81338ba..a5dccec8cc4 100644 --- a/chromium/cc/playback/clip_path_display_item.cc +++ b/chromium/cc/playback/clip_path_display_item.cc @@ -62,7 +62,7 @@ void ClipPathDisplayItem::ToProtobuf( // Just use skia's serialization method for the SkPath for now. size_t path_size = clip_path_.writeToMemory(nullptr); if (path_size > 0) { - scoped_ptr<uint8_t[]> buffer(new uint8_t[path_size]); + std::unique_ptr<uint8_t[]> buffer(new uint8_t[path_size]); clip_path_.writeToMemory(buffer.get()); details->set_clip_path(buffer.get(), path_size); } diff --git a/chromium/cc/playback/clip_path_display_item.h b/chromium/cc/playback/clip_path_display_item.h index f946c147134..857d590ab05 100644 --- a/chromium/cc/playback/clip_path_display_item.h +++ b/chromium/cc/playback/clip_path_display_item.h @@ -7,7 +7,9 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/playback/display_item.h" #include "third_party/skia/include/core/SkPath.h" @@ -35,7 +37,6 @@ class CC_EXPORT ClipPathDisplayItem : public DisplayItem { size_t ExternalMemoryUsage() const override; int ApproximateOpCount() const { return 1; } - bool IsSuitableForGpuRasterization() const { return true; } private: void SetNew(const SkPath& path, SkRegion::Op clip_op, bool antialias); @@ -51,8 +52,8 @@ class CC_EXPORT EndClipPathDisplayItem : public DisplayItem { explicit EndClipPathDisplayItem(const proto::DisplayItem& proto); ~EndClipPathDisplayItem() override; - static scoped_ptr<EndClipPathDisplayItem> Create() { - return make_scoped_ptr(new EndClipPathDisplayItem()); + static std::unique_ptr<EndClipPathDisplayItem> Create() { + return base::WrapUnique(new EndClipPathDisplayItem()); } void ToProtobuf(proto::DisplayItem* proto, diff --git a/chromium/cc/playback/compositing_display_item.cc b/chromium/cc/playback/compositing_display_item.cc index 0d75ca9a6bb..dc947d2752a 100644 --- a/chromium/cc/playback/compositing_display_item.cc +++ b/chromium/cc/playback/compositing_display_item.cc @@ -40,7 +40,7 @@ CompositingDisplayItem::CompositingDisplayItem( const proto::CompositingDisplayItem& details = proto.compositing_item(); uint8_t alpha = static_cast<uint8_t>(details.alpha()); SkXfermode::Mode xfermode = SkXfermodeModeFromProto(details.mode()); - scoped_ptr<SkRect> bounds; + std::unique_ptr<SkRect> bounds; if (details.has_bounds()) { bounds.reset( new SkRect(gfx::RectFToSkRect(ProtoToRectF(details.bounds())))); @@ -90,8 +90,7 @@ void CompositingDisplayItem::ToProtobuf( RectFToProto(gfx::SkRectToRectF(bounds_), details->mutable_bounds()); if (color_filter_) { - skia::RefPtr<SkData> data = - skia::AdoptRef(SkValidatingSerializeFlattenable(color_filter_.get())); + sk_sp<SkData> data(SkValidatingSerializeFlattenable(color_filter_.get())); if (data->size() > 0) details->set_color_filter(data->data(), data->size()); } diff --git a/chromium/cc/playback/compositing_display_item.h b/chromium/cc/playback/compositing_display_item.h index cf6722206f5..2f9ef225e06 100644 --- a/chromium/cc/playback/compositing_display_item.h +++ b/chromium/cc/playback/compositing_display_item.h @@ -8,7 +8,9 @@ #include <stddef.h> #include <stdint.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/playback/display_item.h" #include "third_party/skia/include/core/SkColorFilter.h" @@ -43,7 +45,6 @@ class CC_EXPORT CompositingDisplayItem : public DisplayItem { size_t ExternalMemoryUsage() const override; int ApproximateOpCount() const { return 1; } - bool IsSuitableForGpuRasterization() const { return true; } private: void SetNew(uint8_t alpha, @@ -66,8 +67,8 @@ class CC_EXPORT EndCompositingDisplayItem : public DisplayItem { explicit EndCompositingDisplayItem(const proto::DisplayItem& proto); ~EndCompositingDisplayItem() override; - static scoped_ptr<EndCompositingDisplayItem> Create() { - return make_scoped_ptr(new EndCompositingDisplayItem()); + static std::unique_ptr<EndCompositingDisplayItem> Create() { + return base::WrapUnique(new EndCompositingDisplayItem()); } void ToProtobuf(proto::DisplayItem* proto, diff --git a/chromium/cc/playback/decoded_draw_image.cc b/chromium/cc/playback/decoded_draw_image.cc new file mode 100644 index 00000000000..fa5c3b49e33 --- /dev/null +++ b/chromium/cc/playback/decoded_draw_image.cc @@ -0,0 +1,30 @@ +// 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/decoded_draw_image.h" + +namespace cc { + +DecodedDrawImage::DecodedDrawImage(sk_sp<const SkImage> image, + const SkSize& src_rect_offset, + const SkSize& scale_adjustment, + SkFilterQuality filter_quality) + : image_(std::move(image)), + src_rect_offset_(src_rect_offset), + scale_adjustment_(scale_adjustment), + filter_quality_(filter_quality), + at_raster_decode_(false) {} + +DecodedDrawImage::DecodedDrawImage(sk_sp<const SkImage> image, + SkFilterQuality filter_quality) + : DecodedDrawImage(std::move(image), + SkSize::Make(0.f, 0.f), + SkSize::Make(1.f, 1.f), + filter_quality) {} + +DecodedDrawImage::DecodedDrawImage(const DecodedDrawImage& other) = default; + +DecodedDrawImage::~DecodedDrawImage() = default; + +} // namespace cc diff --git a/chromium/cc/playback/decoded_draw_image.h b/chromium/cc/playback/decoded_draw_image.h index 90c9e1b3e85..8003fa6074f 100644 --- a/chromium/cc/playback/decoded_draw_image.h +++ b/chromium/cc/playback/decoded_draw_image.h @@ -8,32 +8,25 @@ #include <cfloat> #include <cmath> +#include "cc/base/cc_export.h" #include "third_party/skia/include/core/SkFilterQuality.h" #include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSize.h" namespace cc { -class DecodedDrawImage { +class CC_EXPORT DecodedDrawImage { public: - DecodedDrawImage(const SkImage* image, + DecodedDrawImage(sk_sp<const SkImage> image, const SkSize& src_rect_offset, const SkSize& scale_adjustment, - SkFilterQuality filter_quality) - : image_(image), - src_rect_offset_(src_rect_offset), - scale_adjustment_(scale_adjustment), - filter_quality_(filter_quality), - at_raster_decode_(false) {} - - DecodedDrawImage(const SkImage* image, SkFilterQuality filter_quality) - : image_(image), - src_rect_offset_(SkSize::Make(0.f, 0.f)), - scale_adjustment_(SkSize::Make(1.f, 1.f)), - filter_quality_(filter_quality), - at_raster_decode_(false) {} - - const SkImage* image() const { return image_; } + SkFilterQuality filter_quality); + DecodedDrawImage(sk_sp<const SkImage> image, SkFilterQuality filter_quality); + DecodedDrawImage(const DecodedDrawImage& other); + ~DecodedDrawImage(); + + const sk_sp<const SkImage>& image() const { return image_; } const SkSize& src_rect_offset() const { return src_rect_offset_; } const SkSize& scale_adjustment() const { return scale_adjustment_; } SkFilterQuality filter_quality() const { return filter_quality_; } @@ -48,7 +41,7 @@ class DecodedDrawImage { bool is_at_raster_decode() const { return at_raster_decode_; } private: - const SkImage* image_; + sk_sp<const SkImage> image_; const SkSize src_rect_offset_; const SkSize scale_adjustment_; const SkFilterQuality filter_quality_; diff --git a/chromium/cc/playback/discardable_image_map.cc b/chromium/cc/playback/discardable_image_map.cc index 5588a69cc89..840de37a956 100644 --- a/chromium/cc/playback/discardable_image_map.cc +++ b/chromium/cc/playback/discardable_image_map.cc @@ -53,7 +53,7 @@ class DiscardableImagesMetadataCanvas : public SkNWayCanvas { const SkPaint* paint) override { const SkMatrix& ctm = getTotalMatrix(); AddImage( - image, SkRect::MakeIWH(image->width(), image->height()), + sk_ref_sp(image), SkRect::MakeIWH(image->width(), image->height()), MapRect(ctm, SkRect::MakeXYWH(x, y, image->width(), image->height())), ctm, paint); } @@ -72,7 +72,7 @@ class DiscardableImagesMetadataCanvas : public SkNWayCanvas { SkMatrix matrix; matrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit); matrix.postConcat(ctm); - AddImage(image, *src, MapRect(ctm, dst), matrix, paint); + AddImage(sk_ref_sp(image), *src, MapRect(ctm, dst), matrix, paint); } void onDrawImageNine(const SkImage* image, @@ -119,7 +119,7 @@ class DiscardableImagesMetadataCanvas : public SkNWayCanvas { return true; } - void AddImage(const SkImage* image, + void AddImage(sk_sp<const SkImage> image, const SkRect& src_rect, const SkRect& rect, const SkMatrix& matrix, @@ -144,9 +144,9 @@ class DiscardableImagesMetadataCanvas : public SkNWayCanvas { SkIRect src_irect; src_rect.roundOut(&src_irect); - image_set_->push_back( - std::make_pair(DrawImage(image, src_irect, filter_quality, matrix), - gfx::ToEnclosingRect(gfx::SkRectToRectF(paint_rect)))); + image_set_->push_back(std::make_pair( + DrawImage(std::move(image), src_irect, filter_quality, matrix), + gfx::ToEnclosingRect(gfx::SkRectToRectF(paint_rect)))); } std::vector<std::pair<DrawImage, gfx::Rect>>* image_set_; @@ -160,11 +160,11 @@ DiscardableImageMap::DiscardableImageMap() {} DiscardableImageMap::~DiscardableImageMap() {} -skia::RefPtr<SkCanvas> DiscardableImageMap::BeginGeneratingMetadata( +sk_sp<SkCanvas> DiscardableImageMap::BeginGeneratingMetadata( const gfx::Size& bounds) { DCHECK(all_images_.empty()); - return skia::AdoptRef(new DiscardableImagesMetadataCanvas( - bounds.width(), bounds.height(), &all_images_)); + return sk_make_sp<DiscardableImagesMetadataCanvas>( + bounds.width(), bounds.height(), &all_images_); } void DiscardableImageMap::EndGeneratingMetadata() { diff --git a/chromium/cc/playback/discardable_image_map.h b/chromium/cc/playback/discardable_image_map.h index 3b29da20b42..2d1b69f048b 100644 --- a/chromium/cc/playback/discardable_image_map.h +++ b/chromium/cc/playback/discardable_image_map.h @@ -11,14 +11,11 @@ #include "cc/base/cc_export.h" #include "cc/base/rtree.h" #include "cc/playback/draw_image.h" -#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkPicture.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -class SkImage; - namespace cc { // Helper function to apply the matrix to the rect and return the result. @@ -39,7 +36,7 @@ class CC_EXPORT DiscardableImageMap { private: DiscardableImageMap* image_map_; - skia::RefPtr<SkCanvas> metadata_canvas_; + sk_sp<SkCanvas> metadata_canvas_; }; DiscardableImageMap(); @@ -54,7 +51,7 @@ class CC_EXPORT DiscardableImageMap { friend class ScopedMetadataGenerator; friend class DiscardableImageMapTest; - skia::RefPtr<SkCanvas> BeginGeneratingMetadata(const gfx::Size& bounds); + sk_sp<SkCanvas> BeginGeneratingMetadata(const gfx::Size& bounds); void EndGeneratingMetadata(); std::vector<std::pair<DrawImage, gfx::Rect>> all_images_; diff --git a/chromium/cc/playback/discardable_image_map_unittest.cc b/chromium/cc/playback/discardable_image_map_unittest.cc index 95c23a3b702..3a10256786c 100644 --- a/chromium/cc/playback/discardable_image_map_unittest.cc +++ b/chromium/cc/playback/discardable_image_map_unittest.cc @@ -6,8 +6,9 @@ #include <stddef.h> +#include <memory> + #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/values.h" #include "cc/base/region.h" #include "cc/test/fake_content_layer_client.h" @@ -17,6 +18,7 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkGraphics.h" #include "third_party/skia/include/core/SkImageGenerator.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/skia_util.h" @@ -24,9 +26,9 @@ namespace cc { namespace { struct PositionDrawImage { - PositionDrawImage(const SkImage* image, const gfx::Rect& image_rect) - : image(image), image_rect(image_rect) {} - const SkImage* image; + PositionDrawImage(sk_sp<const SkImage> image, const gfx::Rect& image_rect) + : image(std::move(image)), image_rect(image_rect) {} + sk_sp<const SkImage> image; gfx::Rect image_rect; }; @@ -71,14 +73,14 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectTest) { // |---|---|---|---| // | x | | x | | // |---|---|---|---| - skia::RefPtr<SkImage> discardable_image[4][4]; + sk_sp<SkImage> discardable_image[4][4]; for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { if ((x + y) & 1) { discardable_image[y][x] = CreateDiscardableImage(gfx::Size(500, 500)); SkPaint paint; content_layer_client.add_draw_image( - discardable_image[y][x].get(), gfx::Point(x * 512 + 6, y * 512 + 6), + discardable_image[y][x], gfx::Point(x * 512 + 6, y * 512 + 6), paint); } } @@ -105,8 +107,8 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectTest) { image_map, gfx::Rect(x * 512, y * 512, 500, 500)); if ((x + y) & 1) { EXPECT_EQ(1u, images.size()) << x << " " << y; - EXPECT_TRUE(images[0].image == discardable_image[y][x].get()) - << x << " " << y; + EXPECT_TRUE(images[0].image == discardable_image[y][x]) << x << " " + << y; EXPECT_EQ(gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500), images[0].image_rect); } else { @@ -119,14 +121,14 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectTest) { std::vector<PositionDrawImage> images = GetDiscardableImagesInRect(image_map, gfx::Rect(512, 512, 2048, 2048)); EXPECT_EQ(4u, images.size()); - EXPECT_TRUE(images[0].image == discardable_image[1][2].get()); + EXPECT_TRUE(images[0].image == discardable_image[1][2]); EXPECT_EQ(gfx::Rect(2 * 512 + 6, 512 + 6, 500, 500), images[0].image_rect); - EXPECT_TRUE(images[1].image == discardable_image[2][1].get()); + EXPECT_TRUE(images[1].image == discardable_image[2][1]); EXPECT_EQ(gfx::Rect(512 + 6, 2 * 512 + 6, 500, 500), images[1].image_rect); - EXPECT_TRUE(images[2].image == discardable_image[2][3].get()); + EXPECT_TRUE(images[2].image == discardable_image[2][3]); EXPECT_EQ(gfx::Rect(3 * 512 + 6, 2 * 512 + 6, 500, 500), images[2].image_rect); - EXPECT_TRUE(images[3].image == discardable_image[3][2].get()); + EXPECT_TRUE(images[3].image == discardable_image[3][2]); EXPECT_EQ(gfx::Rect(2 * 512 + 6, 3 * 512 + 6, 500, 500), images[3].image_rect); } @@ -148,14 +150,14 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectNonZeroLayer) { // |---|---|---|---| // | x | | x | | // |---|---|---|---| - skia::RefPtr<SkImage> discardable_image[4][4]; + sk_sp<SkImage> discardable_image[4][4]; for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { if ((x + y) & 1) { discardable_image[y][x] = CreateDiscardableImage(gfx::Size(500, 500)); SkPaint paint; content_layer_client.add_draw_image( - discardable_image[y][x].get(), + discardable_image[y][x], gfx::Point(1024 + x * 512 + 6, y * 512 + 6), paint); } } @@ -182,8 +184,8 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectNonZeroLayer) { image_map, gfx::Rect(1024 + x * 512, y * 512, 500, 500)); if ((x + y) & 1) { EXPECT_EQ(1u, images.size()) << x << " " << y; - EXPECT_TRUE(images[0].image == discardable_image[y][x].get()) - << x << " " << y; + EXPECT_TRUE(images[0].image == discardable_image[y][x]) << x << " " + << y; EXPECT_EQ(gfx::Rect(1024 + x * 512 + 6, y * 512 + 6, 500, 500), images[0].image_rect); } else { @@ -196,16 +198,16 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectNonZeroLayer) { std::vector<PositionDrawImage> images = GetDiscardableImagesInRect( image_map, gfx::Rect(1024 + 512, 512, 2048, 2048)); EXPECT_EQ(4u, images.size()); - EXPECT_TRUE(images[0].image == discardable_image[1][2].get()); + EXPECT_TRUE(images[0].image == discardable_image[1][2]); EXPECT_EQ(gfx::Rect(1024 + 2 * 512 + 6, 512 + 6, 500, 500), images[0].image_rect); - EXPECT_TRUE(images[1].image == discardable_image[2][1].get()); + EXPECT_TRUE(images[1].image == discardable_image[2][1]); EXPECT_EQ(gfx::Rect(1024 + 512 + 6, 2 * 512 + 6, 500, 500), images[1].image_rect); - EXPECT_TRUE(images[2].image == discardable_image[2][3].get()); + EXPECT_TRUE(images[2].image == discardable_image[2][3]); EXPECT_EQ(gfx::Rect(1024 + 3 * 512 + 6, 2 * 512 + 6, 500, 500), images[2].image_rect); - EXPECT_TRUE(images[3].image == discardable_image[3][2].get()); + EXPECT_TRUE(images[3].image == discardable_image[3][2]); EXPECT_EQ(gfx::Rect(1024 + 2 * 512 + 6, 3 * 512 + 6, 500, 500), images[3].image_rect); } @@ -248,14 +250,14 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectOnePixelQuery) { // |---|---|---|---| // | x | | x | | // |---|---|---|---| - skia::RefPtr<SkImage> discardable_image[4][4]; + sk_sp<SkImage> discardable_image[4][4]; for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { if ((x + y) & 1) { discardable_image[y][x] = CreateDiscardableImage(gfx::Size(500, 500)); SkPaint paint; content_layer_client.add_draw_image( - discardable_image[y][x].get(), gfx::Point(x * 512 + 6, y * 512 + 6), + discardable_image[y][x], gfx::Point(x * 512 + 6, y * 512 + 6), paint); } } @@ -282,8 +284,8 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectOnePixelQuery) { image_map, gfx::Rect(x * 512 + 256, y * 512 + 256, 1, 1)); if ((x + y) & 1) { EXPECT_EQ(1u, images.size()) << x << " " << y; - EXPECT_TRUE(images[0].image == discardable_image[y][x].get()) - << x << " " << y; + EXPECT_TRUE(images[0].image == discardable_image[y][x]) << x << " " + << y; EXPECT_EQ(gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500), images[0].image_rect); } else { @@ -298,10 +300,10 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectMassiveImage) { FakeContentLayerClient content_layer_client; content_layer_client.set_bounds(visible_rect.size()); - skia::RefPtr<SkImage> discardable_image; - discardable_image = CreateDiscardableImage(gfx::Size(1 << 25, 1 << 25)); + sk_sp<SkImage> discardable_image = + CreateDiscardableImage(gfx::Size(1 << 25, 1 << 25)); SkPaint paint; - content_layer_client.add_draw_image(discardable_image.get(), gfx::Point(0, 0), + content_layer_client.add_draw_image(discardable_image, gfx::Point(0, 0), paint); FakeRecordingSource recording_source; @@ -321,7 +323,7 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectMassiveImage) { std::vector<PositionDrawImage> images = GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1)); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image == discardable_image.get()); + EXPECT_TRUE(images[0].image == discardable_image); EXPECT_EQ(gfx::Rect(0, 0, 1 << 25, 1 << 25), images[0].image_rect); } @@ -330,26 +332,25 @@ TEST_F(DiscardableImageMapTest, PaintDestroyedWhileImageIsDrawn) { FakeContentLayerClient content_layer_client; content_layer_client.set_bounds(visible_rect.size()); - skia::RefPtr<SkImage> discardable_image; - discardable_image = CreateDiscardableImage(gfx::Size(10, 10)); + sk_sp<SkImage> discardable_image = CreateDiscardableImage(gfx::Size(10, 10)); DiscardableImageMap image_map; { DiscardableImageMap::ScopedMetadataGenerator generator(&image_map, visible_rect.size()); { - scoped_ptr<SkPaint> paint(new SkPaint()); + std::unique_ptr<SkPaint> paint(new SkPaint()); generator.canvas()->saveLayer(gfx::RectToSkRect(visible_rect), paint.get()); } - generator.canvas()->drawImage(discardable_image.get(), 0, 0, nullptr); + generator.canvas()->drawImage(discardable_image, 0, 0, nullptr); generator.canvas()->restore(); } std::vector<PositionDrawImage> images = GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1)); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image == discardable_image.get()); + EXPECT_TRUE(images[0].image == discardable_image); } } // namespace cc diff --git a/chromium/cc/playback/display_item.h b/chromium/cc/playback/display_item.h index 3f61adb3a95..bc1eae605bd 100644 --- a/chromium/cc/playback/display_item.h +++ b/chromium/cc/playback/display_item.h @@ -7,7 +7,8 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/debug/traced_value.h" #include "third_party/skia/include/core/SkPicture.h" diff --git a/chromium/cc/playback/display_item_list.cc b/chromium/cc/playback/display_item_list.cc index 91f9cf297a4..3ad738ab7db 100644 --- a/chromium/cc/playback/display_item_list.cc +++ b/chromium/cc/playback/display_item_list.cc @@ -89,10 +89,11 @@ DisplayItemList::DisplayItemList(gfx::Rect layer_rect, if (settings_.use_cached_picture) { SkRTreeFactory factory; recorder_.reset(new SkPictureRecorder()); - canvas_ = skia::SharePtr(recorder_->beginRecording( - layer_rect_.width(), layer_rect_.height(), &factory)); - canvas_->translate(-layer_rect_.x(), -layer_rect_.y()); - canvas_->clipRect(gfx::RectToSkRect(layer_rect_)); + + SkCanvas* canvas = recorder_->beginRecording( + layer_rect_.width(), layer_rect_.height(), &factory); + canvas->translate(-layer_rect_.x(), -layer_rect_.y()); + canvas->clipRect(gfx::RectToSkRect(layer_rect_)); } } @@ -146,8 +147,8 @@ void DisplayItemList::Raster(SkCanvas* canvas, void DisplayItemList::ProcessAppendedItem(const DisplayItem* item) { if (settings_.use_cached_picture) { - DCHECK(canvas_); - item->Raster(canvas_.get(), gfx::Rect(), nullptr); + DCHECK(recorder_); + item->Raster(recorder_->getRecordingCanvas(), gfx::Rect(), nullptr); } if (!retain_individual_display_items_) { items_.Clear(); @@ -155,10 +156,10 @@ void DisplayItemList::ProcessAppendedItem(const DisplayItem* item) { } void DisplayItemList::RasterIntoCanvas(const DisplayItem& item) { - DCHECK(canvas_); + DCHECK(recorder_); DCHECK(!retain_individual_display_items_); - item.Raster(canvas_.get(), gfx::Rect(), nullptr); + item.Raster(recorder_->getRecordingCanvas(), gfx::Rect(), nullptr); } bool DisplayItemList::RetainsIndividualDisplayItems() const { @@ -166,6 +167,7 @@ bool DisplayItemList::RetainsIndividualDisplayItems() const { } void DisplayItemList::Finalize() { + TRACE_EVENT0("cc", "DisplayItemList::Finalize"); // TODO(dtrainor): Need to deal with serializing visual_rects_. // http://crbug.com/568757. DCHECK(!retain_individual_display_items_ || @@ -189,9 +191,6 @@ void DisplayItemList::Finalize() { picture_memory_usage_ = SkPictureUtils::ApproximateBytesUsed(picture_.get()); recorder_.reset(); - canvas_.clear(); - is_suitable_for_gpu_rasterization_ = - picture_->suitableForGpuRasterization(nullptr); } } @@ -200,7 +199,9 @@ bool DisplayItemList::IsSuitableForGpuRasterization() const { } int DisplayItemList::ApproximateOpCount() const { - return approximate_op_count_; + if (retain_individual_display_items_) + return approximate_op_count_; + return picture_ ? picture_->approximateOpCount() : 0; } size_t DisplayItemList::ApproximateMemoryUsage() const { @@ -237,9 +238,9 @@ bool DisplayItemList::ShouldBeAnalyzedForSolidColor() const { return ApproximateOpCount() <= kOpCountThatIsOkToAnalyze; } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> DisplayItemList::AsValue(bool include_items) const { - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); state->BeginDictionary("params"); @@ -308,8 +309,4 @@ void DisplayItemList::GetDiscardableImagesInRect( image_map_.GetDiscardableImagesInRect(rect, raster_scale, images); } -bool DisplayItemList::MayHaveDiscardableImages() const { - return !image_map_.empty(); -} - } // namespace cc diff --git a/chromium/cc/playback/display_item_list.h b/chromium/cc/playback/display_item_list.h index 5d33d24795a..6660f363267 100644 --- a/chromium/cc/playback/display_item_list.h +++ b/chromium/cc/playback/display_item_list.h @@ -6,19 +6,19 @@ #define CC_PLAYBACK_DISPLAY_ITEM_LIST_H_ #include <stddef.h> + +#include <memory> #include <utility> #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/trace_event/trace_event.h" #include "cc/base/cc_export.h" #include "cc/base/contiguous_container.h" #include "cc/playback/discardable_image_map.h" #include "cc/playback/display_item.h" #include "cc/playback/display_item_list_settings.h" -#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/geometry/rect.h" @@ -66,7 +66,7 @@ class CC_EXPORT DisplayItemList // 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_. + // approximate_op_count_. void RasterIntoCanvas(const DisplayItem& display_item); // Because processing happens in this function, all the set up for @@ -79,10 +79,6 @@ class CC_EXPORT DisplayItemList auto* item = &items_.AllocateAndConstruct<DisplayItemType>( std::forward<Args>(args)...); approximate_op_count_ += item->ApproximateOpCount(); - // TODO(crbug.com/513016): None of the items might individually trigger a - // veto even though they collectively have enough "bad" operations that a - // corresponding flattened Picture would get vetoed. - is_suitable_for_gpu_rasterization_ &= item->IsSuitableForGpuRasterization(); ProcessAppendedItem(item); return *item; } @@ -91,6 +87,9 @@ class CC_EXPORT DisplayItemList // applicable, create an internally cached SkPicture. void Finalize(); + void SetIsSuitableForGpuRasterization(bool is_suitable) { + is_suitable_for_gpu_rasterization_ = is_suitable; + } bool IsSuitableForGpuRasterization() const; int ApproximateOpCount() const; size_t ApproximateMemoryUsage() const; @@ -98,7 +97,7 @@ class CC_EXPORT DisplayItemList bool RetainsIndividualDisplayItems() const; - scoped_ptr<base::trace_event::ConvertableToTraceFormat> AsValue( + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue( bool include_items) const; void EmitTraceSnapshot() const; @@ -107,7 +106,6 @@ class CC_EXPORT DisplayItemList void GetDiscardableImagesInRect(const gfx::Rect& rect, float raster_scale, std::vector<DrawImage>* images); - bool MayHaveDiscardableImages() const; gfx::Rect VisualRectForTesting(int index) { return visual_rects_[index]; } @@ -128,8 +126,7 @@ class CC_EXPORT DisplayItemList std::vector<gfx::Rect> visual_rects_; sk_sp<SkPicture> picture_; - scoped_ptr<SkPictureRecorder> recorder_; - skia::RefPtr<SkCanvas> canvas_; + std::unique_ptr<SkPictureRecorder> recorder_; const DisplayItemListSettings settings_; bool retain_individual_display_items_; diff --git a/chromium/cc/playback/display_item_list_unittest.cc b/chromium/cc/playback/display_item_list_unittest.cc index 67d890fdfc9..41ae5bac507 100644 --- a/chromium/cc/playback/display_item_list_unittest.cc +++ b/chromium/cc/playback/display_item_list_unittest.cc @@ -8,6 +8,7 @@ #include <vector> +#include "base/memory/ptr_util.h" #include "cc/output/filter_operation.h" #include "cc/output/filter_operations.h" #include "cc/playback/clip_display_item.h" @@ -21,7 +22,6 @@ #include "cc/proto/display_item.pb.h" #include "cc/test/fake_image_serialization_processor.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/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -46,12 +46,12 @@ void AppendFirstSerializationTestPicture(scoped_refptr<DisplayItemList> list, const gfx::Size& layer_size) { gfx::PointF offset(2.f, 3.f); SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; + sk_sp<SkCanvas> canvas; SkPaint red_paint; red_paint.setColor(SK_ColorRED); - canvas = skia::SharePtr(recorder.beginRecording(SkRect::MakeXYWH( + canvas = sk_ref_sp(recorder.beginRecording(SkRect::MakeXYWH( offset.x(), offset.y(), layer_size.width(), layer_size.height()))); canvas->translate(offset.x(), offset.y()); canvas->drawRectCoords(0.f, 0.f, 4.f, 4.f, red_paint); @@ -63,12 +63,12 @@ void AppendSecondSerializationTestPicture(scoped_refptr<DisplayItemList> list, const gfx::Size& layer_size) { gfx::PointF offset(2.f, 2.f); SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; + sk_sp<SkCanvas> canvas; SkPaint blue_paint; blue_paint.setColor(SK_ColorBLUE); - canvas = skia::SharePtr(recorder.beginRecording(SkRect::MakeXYWH( + canvas = sk_ref_sp(recorder.beginRecording(SkRect::MakeXYWH( offset.x(), offset.y(), layer_size.width(), layer_size.height()))); canvas->translate(offset.x(), offset.y()); canvas->drawRectCoords(3.f, 3.f, 7.f, 7.f, blue_paint); @@ -80,9 +80,9 @@ void ValidateDisplayItemListSerialization(const gfx::Size& layer_size, scoped_refptr<DisplayItemList> list) { list->Finalize(); - scoped_ptr<FakeImageSerializationProcessor> + std::unique_ptr<FakeImageSerializationProcessor> fake_image_serialization_processor = - make_scoped_ptr(new FakeImageSerializationProcessor); + base::WrapUnique(new FakeImageSerializationProcessor); // Serialize and deserialize the DisplayItemList. proto::DisplayItemList proto; @@ -255,7 +255,7 @@ TEST(DisplayItemListTest, SerializeTransformItem) { TEST(DisplayItemListTest, SingleDrawingItem) { gfx::Rect layer_rect(100, 100); SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; + sk_sp<SkCanvas> canvas; SkPaint blue_paint; blue_paint.setColor(SK_ColorBLUE); SkPaint red_paint; @@ -267,8 +267,8 @@ TEST(DisplayItemListTest, SingleDrawingItem) { gfx::PointF offset(8.f, 9.f); gfx::RectF recording_rect(offset, gfx::SizeF(layer_rect.size())); - canvas = skia::SharePtr( - recorder.beginRecording(gfx::RectFToSkRect(recording_rect))); + canvas = + sk_ref_sp(recorder.beginRecording(gfx::RectFToSkRect(recording_rect))); canvas->translate(offset.x(), offset.y()); canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint); canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint); @@ -297,7 +297,7 @@ TEST(DisplayItemListTest, SingleDrawingItem) { TEST(DisplayItemListTest, ClipItem) { gfx::Rect layer_rect(100, 100); SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; + sk_sp<SkCanvas> canvas; SkPaint blue_paint; blue_paint.setColor(SK_ColorBLUE); SkPaint red_paint; @@ -310,7 +310,7 @@ TEST(DisplayItemListTest, ClipItem) { gfx::PointF first_offset(8.f, 9.f); gfx::RectF first_recording_rect(first_offset, gfx::SizeF(layer_rect.size())); - canvas = skia::SharePtr( + canvas = sk_ref_sp( recorder.beginRecording(gfx::RectFToSkRect(first_recording_rect))); canvas->translate(first_offset.x(), first_offset.y()); canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint); @@ -324,7 +324,7 @@ TEST(DisplayItemListTest, ClipItem) { gfx::PointF second_offset(2.f, 3.f); gfx::RectF second_recording_rect(second_offset, gfx::SizeF(layer_rect.size())); - canvas = skia::SharePtr( + canvas = sk_ref_sp( recorder.beginRecording(gfx::RectFToSkRect(second_recording_rect))); canvas->translate(second_offset.x(), second_offset.y()); canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint); @@ -357,7 +357,7 @@ TEST(DisplayItemListTest, ClipItem) { TEST(DisplayItemListTest, TransformItem) { gfx::Rect layer_rect(100, 100); SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; + sk_sp<SkCanvas> canvas; SkPaint blue_paint; blue_paint.setColor(SK_ColorBLUE); SkPaint red_paint; @@ -370,7 +370,7 @@ TEST(DisplayItemListTest, TransformItem) { gfx::PointF first_offset(8.f, 9.f); gfx::RectF first_recording_rect(first_offset, gfx::SizeF(layer_rect.size())); - canvas = skia::SharePtr( + canvas = sk_ref_sp( recorder.beginRecording(gfx::RectFToSkRect(first_recording_rect))); canvas->translate(first_offset.x(), first_offset.y()); canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint); @@ -384,7 +384,7 @@ TEST(DisplayItemListTest, TransformItem) { gfx::PointF second_offset(2.f, 3.f); gfx::RectF second_recording_rect(second_offset, gfx::SizeF(layer_rect.size())); - canvas = skia::SharePtr( + canvas = sk_ref_sp( recorder.beginRecording(gfx::RectFToSkRect(second_recording_rect))); canvas->translate(second_offset.x(), second_offset.y()); canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint); @@ -426,8 +426,7 @@ TEST(DisplayItemListTest, FilterItem) { sk_sp<SkSurface> source_surface = SkSurface::MakeRasterN32Premul(50, 50); SkCanvas* source_canvas = source_surface->getCanvas(); source_canvas->clear(SkColorSetRGB(128, 128, 128)); - skia::RefPtr<SkImage> source_image = - skia::AdoptRef(source_surface->newImageSnapshot()); + sk_sp<SkImage> source_image = source_surface->makeImageSnapshot(); // For most SkImageFilters, the |dst| bounds computed by computeFastBounds are // dependent on the provided |src| bounds. This means, for example, that @@ -440,8 +439,7 @@ TEST(DisplayItemListTest, FilterItem) { // incorrect clipping of filter output. To test for this, we include an // SkImageSource filter in |filters|. Here, |src| is |filter_bounds|, defined // below. - skia::RefPtr<SkImageFilter> image_filter = - skia::AdoptRef(SkImageSource::Create(source_image.get())); + sk_sp<SkImageFilter> image_filter = SkImageSource::Make(source_image); filters.Append(FilterOperation::CreateReferenceFilter(image_filter)); filters.Append(FilterOperation::CreateBrightnessFilter(0.5f)); gfx::RectF filter_bounds(10.f, 10.f, 50.f, 50.f); @@ -468,7 +466,7 @@ TEST(DisplayItemListTest, FilterItem) { TEST(DisplayItemListTest, CompactingItems) { gfx::Rect layer_rect(100, 100); SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; + sk_sp<SkCanvas> canvas; SkPaint blue_paint; blue_paint.setColor(SK_ColorBLUE); SkPaint red_paint; @@ -483,8 +481,8 @@ TEST(DisplayItemListTest, CompactingItems) { scoped_refptr<DisplayItemList> list_without_caching = DisplayItemList::Create(layer_rect, no_caching_settings); - canvas = skia::SharePtr( - recorder.beginRecording(gfx::RectFToSkRect(recording_rect))); + canvas = + sk_ref_sp(recorder.beginRecording(gfx::RectFToSkRect(recording_rect))); canvas->translate(offset.x(), offset.y()); canvas->drawRectCoords(0.f, 0.f, 60.f, 60.f, red_paint); canvas->drawRectCoords(50.f, 50.f, 75.f, 75.f, blue_paint); @@ -507,129 +505,6 @@ TEST(DisplayItemListTest, CompactingItems) { EXPECT_EQ(0, memcmp(pixels, expected_pixels, 4 * 100 * 100)); } -TEST(DisplayItemListTest, IsSuitableForGpuRasterizationWithCachedPicture) { - gfx::Rect layer_rect(1000, 1000); - SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; - - DisplayItemListSettings settings; - settings.use_cached_picture = true; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(layer_rect, settings); - 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); - - sk_sp<SkPicture> suitable_picture = recorder.finishRecordingAsPicture(); - list->CreateAndAppendItem<DrawingDisplayItem>(kVisualRect, suitable_picture); - list->Finalize(); - - // A single DrawingDisplayItem with a large AA concave path shouldn't trigger - // a veto. - EXPECT_TRUE(list->IsSuitableForGpuRasterization()); - - // Now check the RasterIntoCanvas path. - list = DisplayItemList::Create(layer_rect, settings); - DrawingDisplayItem suitable_item(suitable_picture); - list->RasterIntoCanvas(suitable_item); - list->Finalize(); - EXPECT_TRUE(list->IsSuitableForGpuRasterization()); - - list = DisplayItemList::Create(layer_rect, settings); - canvas = - skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect))); - for (int i = 0; i < 10; ++i) - canvas->drawPath(path, paint); - sk_sp<SkPicture> unsuitable_picture = recorder.finishRecordingAsPicture(); - list->CreateAndAppendItem<DrawingDisplayItem>(kVisualRect, - unsuitable_picture); - list->Finalize(); - - // A single DrawingDisplayItem with several large AA concave paths should - // trigger a veto. - EXPECT_FALSE(list->IsSuitableForGpuRasterization()); - - // Now check the RasterIntoCanvas path. - list = DisplayItemList::Create(layer_rect, settings); - DrawingDisplayItem unsuitable_item(unsuitable_picture); - list->RasterIntoCanvas(unsuitable_item); - list->Finalize(); - EXPECT_FALSE(list->IsSuitableForGpuRasterization()); -} - -TEST(DisplayItemListTest, IsSuitableForGpuRasterizationWithoutCachedPicture) { - gfx::Rect layer_rect(1000, 1000); - SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas; - skia::RefPtr<SkPicture> picture; - - DisplayItemListSettings settings; - settings.use_cached_picture = false; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(layer_rect, settings); - 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); - - list->CreateAndAppendItem<DrawingDisplayItem>( - kVisualRect, recorder.finishRecordingAsPicture()); - 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, settings); - canvas = - skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect))); - for (int i = 0; i < 10; ++i) - canvas->drawPath(path, paint); - list->CreateAndAppendItem<DrawingDisplayItem>( - kVisualRect, recorder.finishRecordingAsPicture()); - list->Finalize(); - - // A single DrawingDisplayItem with several large AA concave paths should - // trigger a veto. - EXPECT_FALSE(list->IsSuitableForGpuRasterization()); - - list = DisplayItemList::Create(layer_rect, settings); - for (int i = 0; i < 10; ++i) { - canvas = - skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect))); - canvas->drawPath(path, paint); - list->CreateAndAppendItem<DrawingDisplayItem>( - kVisualRect, recorder.finishRecordingAsPicture()); - } - 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; diff --git a/chromium/cc/playback/draw_image.cc b/chromium/cc/playback/draw_image.cc index 17aef315aea..2b1779f9568 100644 --- a/chromium/cc/playback/draw_image.cc +++ b/chromium/cc/playback/draw_image.cc @@ -30,23 +30,19 @@ DrawImage::DrawImage() scale_(SkSize::Make(1.f, 1.f)), matrix_is_decomposable_(true) {} -DrawImage::DrawImage(const SkImage* image, +DrawImage::DrawImage(sk_sp<const SkImage> image, const SkIRect& src_rect, SkFilterQuality filter_quality, const SkMatrix& matrix) - : image_(image), + : image_(std::move(image)), src_rect_(src_rect), filter_quality_(filter_quality), matrix_(matrix) { matrix_is_decomposable_ = ExtractScale(matrix_, &scale_); } -DrawImage::DrawImage(const DrawImage& other) - : image_(other.image_), - src_rect_(other.src_rect_), - filter_quality_(other.filter_quality_), - matrix_(other.matrix_), - scale_(other.scale_), - matrix_is_decomposable_(other.matrix_is_decomposable_) {} +DrawImage::DrawImage(const DrawImage& other) = default; + +DrawImage::~DrawImage() = default; } // namespace cc diff --git a/chromium/cc/playback/draw_image.h b/chromium/cc/playback/draw_image.h index 83b10ba3da9..4daa16075de 100644 --- a/chromium/cc/playback/draw_image.h +++ b/chromium/cc/playback/draw_image.h @@ -9,6 +9,8 @@ #include "third_party/skia/include/core/SkFilterQuality.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkRect.h" +#include "third_party/skia/include/core/SkRefCnt.h" namespace cc { @@ -17,18 +19,19 @@ namespace cc { class CC_EXPORT DrawImage { public: DrawImage(); - DrawImage(const SkImage* image, + DrawImage(sk_sp<const SkImage> image, const SkIRect& src_rect, SkFilterQuality filter_quality, const SkMatrix& matrix); DrawImage(const DrawImage& other); + ~DrawImage(); - const SkImage* image() const { return image_; } + const sk_sp<const SkImage>& image() const { return image_; } const SkSize& scale() const { return scale_; } const SkIRect src_rect() const { return src_rect_; } SkFilterQuality filter_quality() const { return filter_quality_; } bool matrix_is_decomposable() const { return matrix_is_decomposable_; } - const SkMatrix& matrix() { return matrix_; } + const SkMatrix& matrix() const { return matrix_; } DrawImage ApplyScale(float scale) const { SkMatrix scaled_matrix = matrix_; @@ -37,7 +40,7 @@ class CC_EXPORT DrawImage { } private: - const SkImage* image_; + sk_sp<const SkImage> image_; SkIRect src_rect_; SkFilterQuality filter_quality_; SkMatrix matrix_; diff --git a/chromium/cc/playback/drawing_display_item.cc b/chromium/cc/playback/drawing_display_item.cc index 9d8b9786fb8..8bf18b3efdc 100644 --- a/chromium/cc/playback/drawing_display_item.cc +++ b/chromium/cc/playback/drawing_display_item.cc @@ -9,6 +9,7 @@ #include <string> #include "base/strings/stringprintf.h" +#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "base/values.h" #include "cc/debug/picture_debug_util.h" @@ -61,12 +62,15 @@ void DrawingDisplayItem::SetNew(sk_sp<const SkPicture> picture) { void DrawingDisplayItem::ToProtobuf( proto::DisplayItem* proto, ImageSerializationProcessor* image_serialization_processor) const { + TRACE_EVENT0("cc.remote", "DrawingDisplayItem::ToProtobuf"); proto->set_type(proto::DisplayItem::Type_Drawing); proto::DrawingDisplayItem* details = proto->mutable_drawing_item(); // Just use skia's serialize() method for now. if (picture_) { + TRACE_EVENT0("cc.remote", + "DrawingDisplayItem::ToProtobuf SkPicture::Serialize"); SkDynamicMemoryWStream stream; picture_->serialize(&stream, image_serialization_processor->GetPixelSerializer()); @@ -136,8 +140,4 @@ int DrawingDisplayItem::ApproximateOpCount() const { return picture_->approximateOpCount(); } -bool DrawingDisplayItem::IsSuitableForGpuRasterization() const { - return picture_->suitableForGpuRasterization(NULL); -} - } // namespace cc diff --git a/chromium/cc/playback/drawing_display_item.h b/chromium/cc/playback/drawing_display_item.h index 0e7c640154f..e7463803e83 100644 --- a/chromium/cc/playback/drawing_display_item.h +++ b/chromium/cc/playback/drawing_display_item.h @@ -7,7 +7,8 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/playback/display_item.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -40,7 +41,6 @@ class CC_EXPORT DrawingDisplayItem : public DisplayItem { size_t ExternalMemoryUsage() const override; int ApproximateOpCount() const; - bool IsSuitableForGpuRasterization() const; void CloneTo(DrawingDisplayItem* item) const; diff --git a/chromium/cc/playback/filter_display_item.cc b/chromium/cc/playback/filter_display_item.cc index af42baa84cb..23992295a73 100644 --- a/chromium/cc/playback/filter_display_item.cc +++ b/chromium/cc/playback/filter_display_item.cc @@ -11,10 +11,10 @@ #include "cc/output/render_surface_filters.h" #include "cc/proto/display_item.pb.h" #include "cc/proto/gfx_conversions.h" -#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkPaint.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/skia_util.h" @@ -63,14 +63,13 @@ void FilterDisplayItem::Raster(SkCanvas* canvas, canvas->save(); canvas->translate(bounds_.x(), bounds_.y()); - skia::RefPtr<SkImageFilter> image_filter = - RenderSurfaceFilters::BuildImageFilter( - filters_, gfx::SizeF(bounds_.width(), bounds_.height())); + sk_sp<SkImageFilter> image_filter = RenderSurfaceFilters::BuildImageFilter( + filters_, gfx::SizeF(bounds_.width(), bounds_.height())); SkRect boundaries = SkRect::MakeWH(bounds_.width(), bounds_.height()); SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); - paint.setImageFilter(image_filter.get()); + paint.setImageFilter(std::move(image_filter)); canvas->saveLayer(&boundaries, &paint); canvas->translate(-bounds_.x(), -bounds_.y()); diff --git a/chromium/cc/playback/filter_display_item.h b/chromium/cc/playback/filter_display_item.h index b385538ec6f..afeedd43abd 100644 --- a/chromium/cc/playback/filter_display_item.h +++ b/chromium/cc/playback/filter_display_item.h @@ -7,7 +7,9 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/output/filter_operations.h" #include "cc/playback/display_item.h" @@ -35,7 +37,6 @@ class CC_EXPORT FilterDisplayItem : public DisplayItem { size_t ExternalMemoryUsage() const override; int ApproximateOpCount() const { return 1; } - bool IsSuitableForGpuRasterization() const { return true; } private: void SetNew(const FilterOperations& filters, const gfx::RectF& bounds); @@ -50,8 +51,8 @@ class CC_EXPORT EndFilterDisplayItem : public DisplayItem { explicit EndFilterDisplayItem(const proto::DisplayItem& proto); ~EndFilterDisplayItem() override; - static scoped_ptr<EndFilterDisplayItem> Create() { - return make_scoped_ptr(new EndFilterDisplayItem()); + static std::unique_ptr<EndFilterDisplayItem> Create() { + return base::WrapUnique(new EndFilterDisplayItem()); } void ToProtobuf(proto::DisplayItem* proto, diff --git a/chromium/cc/playback/float_clip_display_item.h b/chromium/cc/playback/float_clip_display_item.h index 41d9acebfa7..b049c09c191 100644 --- a/chromium/cc/playback/float_clip_display_item.h +++ b/chromium/cc/playback/float_clip_display_item.h @@ -7,9 +7,10 @@ #include <stddef.h> +#include <memory> #include <vector> -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/playback/display_item.h" #include "ui/gfx/geometry/rect_f.h" @@ -36,7 +37,6 @@ class CC_EXPORT FloatClipDisplayItem : public DisplayItem { size_t ExternalMemoryUsage() const override; int ApproximateOpCount() const { return 1; } - bool IsSuitableForGpuRasterization() const { return true; } private: void SetNew(const gfx::RectF& clip_rect); @@ -50,8 +50,8 @@ class CC_EXPORT EndFloatClipDisplayItem : public DisplayItem { explicit EndFloatClipDisplayItem(const proto::DisplayItem& proto); ~EndFloatClipDisplayItem() override; - static scoped_ptr<EndFloatClipDisplayItem> Create() { - return make_scoped_ptr(new EndFloatClipDisplayItem()); + static std::unique_ptr<EndFloatClipDisplayItem> Create() { + return base::WrapUnique(new EndFloatClipDisplayItem()); } void ToProtobuf(proto::DisplayItem* proto, diff --git a/chromium/cc/playback/image_hijack_canvas.cc b/chromium/cc/playback/image_hijack_canvas.cc index d0c5c5c72b5..15c42a7abef 100644 --- a/chromium/cc/playback/image_hijack_canvas.cc +++ b/chromium/cc/playback/image_hijack_canvas.cc @@ -4,9 +4,9 @@ #include "cc/playback/image_hijack_canvas.h" +#include "base/optional.h" #include "cc/playback/discardable_image_map.h" #include "cc/tiles/image_decode_controller.h" -#include "third_party/skia/include/core/SkTLazy.h" namespace cc { namespace { @@ -20,21 +20,22 @@ SkIRect RoundOutRect(const SkRect& rect) { class ScopedDecodedImageLock { public: ScopedDecodedImageLock(ImageDecodeController* image_decode_controller, - const SkImage* image, + sk_sp<const SkImage> image, const SkRect& src_rect, const SkMatrix& matrix, const SkPaint* paint) : image_decode_controller_(image_decode_controller), - draw_image_(image, + draw_image_(std::move(image), RoundOutRect(src_rect), paint ? paint->getFilterQuality() : kNone_SkFilterQuality, matrix), decoded_draw_image_( image_decode_controller_->GetDecodedImageForDraw(draw_image_)) { - DCHECK(image->isLazyGenerated()); - if (paint) - decoded_paint_.set(*paint)->setFilterQuality( - decoded_draw_image_.filter_quality()); + DCHECK(draw_image_.image()->isLazyGenerated()); + if (paint) { + decoded_paint_ = *paint; + decoded_paint_->setFilterQuality(decoded_draw_image_.filter_quality()); + } } ~ScopedDecodedImageLock() { @@ -43,14 +44,15 @@ class ScopedDecodedImageLock { } const DecodedDrawImage& decoded_image() const { return decoded_draw_image_; } - const SkPaint* decoded_paint() const { return decoded_paint_.getMaybeNull(); } + const SkPaint* decoded_paint() const { + return decoded_paint_ ? &decoded_paint_.value() : nullptr; + } private: ImageDecodeController* image_decode_controller_; DrawImage draw_image_; DecodedDrawImage decoded_draw_image_; - // TODO(fmalita): use base::Optional when it becomes available - SkTLazy<SkPaint> decoded_paint_; + base::Optional<SkPaint> decoded_paint_; }; } // namespace @@ -82,7 +84,7 @@ void ImageHijackCanvas::onDrawImage(const SkImage* image, SkMatrix ctm = getTotalMatrix(); ScopedDecodedImageLock scoped_lock( - image_decode_controller_, image, + image_decode_controller_, sk_ref_sp(image), SkRect::MakeIWH(image->width(), image->height()), ctm, paint); const DecodedDrawImage& decoded_image = scoped_lock.decoded_image(); if (!decoded_image.image()) @@ -98,7 +100,7 @@ void ImageHijackCanvas::onDrawImage(const SkImage* image, SkNWayCanvas::scale(1.f / (decoded_image.scale_adjustment().width()), 1.f / (decoded_image.scale_adjustment().height())); } - SkNWayCanvas::onDrawImage(decoded_image.image(), x, y, decoded_paint); + SkNWayCanvas::onDrawImage(decoded_image.image().get(), x, y, decoded_paint); if (need_scale) SkNWayCanvas::restore(); } @@ -122,8 +124,8 @@ void ImageHijackCanvas::onDrawImageRect(const SkImage* image, matrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit); matrix.postConcat(getTotalMatrix()); - ScopedDecodedImageLock scoped_lock(image_decode_controller_, image, *src, - matrix, paint); + ScopedDecodedImageLock scoped_lock(image_decode_controller_, sk_ref_sp(image), + *src, matrix, paint); const DecodedDrawImage& decoded_image = scoped_lock.decoded_image(); if (!decoded_image.image()) return; @@ -140,7 +142,7 @@ void ImageHijackCanvas::onDrawImageRect(const SkImage* image, adjusted_src.x() * x_scale, adjusted_src.y() * y_scale, adjusted_src.width() * x_scale, adjusted_src.height() * y_scale); } - SkNWayCanvas::onDrawImageRect(decoded_image.image(), &adjusted_src, dst, + SkNWayCanvas::onDrawImageRect(decoded_image.image().get(), &adjusted_src, dst, decoded_paint, constraint); } diff --git a/chromium/cc/playback/image_hijack_canvas.h b/chromium/cc/playback/image_hijack_canvas.h index 07dc185a94c..65d53556922 100644 --- a/chromium/cc/playback/image_hijack_canvas.h +++ b/chromium/cc/playback/image_hijack_canvas.h @@ -6,7 +6,6 @@ #define CC_PLAYBACK_IMAGE_HIJACK_CANVAS_H_ #include "base/macros.h" -#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/utils/SkNWayCanvas.h" namespace cc { diff --git a/chromium/cc/playback/raster_source.cc b/chromium/cc/playback/raster_source.cc index d8ce85a52fb..292d92512f1 100644 --- a/chromium/cc/playback/raster_source.cc +++ b/chromium/cc/playback/raster_source.cc @@ -15,7 +15,6 @@ #include "skia/ext/analysis_canvas.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" -#include "third_party/skia/include/core/SkTLazy.h" #include "ui/gfx/geometry/rect_conversions.h" namespace cc { @@ -78,11 +77,16 @@ void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, SkipImageCanvas canvas(raster_canvas); RasterCommon(&canvas, nullptr, canvas_bitmap_rect, canvas_playback_rect, contents_scale); - } else if (settings.use_image_hijack_canvas && - display_list_->MayHaveDiscardableImages()) { + } else if (settings.use_image_hijack_canvas) { const SkImageInfo& info = raster_canvas->imageInfo(); + ImageHijackCanvas canvas(info.width(), info.height(), image_decode_controller_); + // Before adding the canvas, make sure that the ImageHijackCanvas is aware + // of the current transform, which may affect the clip bounds. Since we + // query the clip bounds of the current canvas to get the list of draw + // commands to process, this is important to produce correct content. + canvas.setMatrix(raster_canvas->getTotalMatrix()); canvas.addCanvas(raster_canvas); RasterCommon(&canvas, nullptr, canvas_bitmap_rect, canvas_playback_rect, diff --git a/chromium/cc/playback/raster_source.h b/chromium/cc/playback/raster_source.h index 46d1a852279..3a2139d3d2a 100644 --- a/chromium/cc/playback/raster_source.h +++ b/chromium/cc/playback/raster_source.h @@ -7,10 +7,10 @@ #include <stddef.h> +#include <memory> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/debug/rendering_stats_instrumentation.h" #include "cc/playback/recording_source.h" diff --git a/chromium/cc/playback/raster_source_unittest.cc b/chromium/cc/playback/raster_source_unittest.cc index 7efbaf937a6..21340a250dc 100644 --- a/chromium/cc/playback/raster_source_unittest.cc +++ b/chromium/cc/playback/raster_source_unittest.cc @@ -2,15 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/playback/raster_source.h" + #include <stddef.h> -#include "base/memory/scoped_ptr.h" -#include "cc/playback/raster_source.h" +#include <memory> + #include "cc/test/fake_recording_source.h" #include "cc/test/skia_common.h" -#include "skia/ext/refptr.h" +#include "cc/tiles/software_image_decode_controller.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkPixelRef.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkShader.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size_conversions.h" @@ -21,7 +24,7 @@ namespace { TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) { gfx::Size layer_bounds(400, 400); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); SkPaint solid_paint; @@ -92,7 +95,7 @@ TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) { TEST(RasterSourceTest, AnalyzeIsSolidScaled) { gfx::Size layer_bounds(400, 400); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); SkColor solid_color = SkColorSetARGB(255, 12, 23, 34); @@ -163,7 +166,7 @@ TEST(RasterSourceTest, AnalyzeIsSolidScaled) { TEST(RasterSourceTest, AnalyzeIsSolidEmpty) { gfx::Size layer_bounds(400, 400); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); recording_source->Rerecord(); @@ -181,10 +184,10 @@ TEST(RasterSourceTest, AnalyzeIsSolidEmpty) { TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) { gfx::Size layer_bounds(512, 512); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); - skia::RefPtr<SkImage> discardable_image[2][2]; + sk_sp<SkImage> discardable_image[2][2]; discardable_image[0][0] = CreateDiscardableImage(gfx::Size(32, 32)); discardable_image[0][1] = CreateDiscardableImage(gfx::Size(32, 32)); discardable_image[1][1] = CreateDiscardableImage(gfx::Size(32, 32)); @@ -195,11 +198,9 @@ TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) { // |---|---| // | | x | // |---|---| - recording_source->add_draw_image(discardable_image[0][0].get(), - gfx::Point(0, 0)); - recording_source->add_draw_image(discardable_image[0][1].get(), - gfx::Point(260, 0)); - recording_source->add_draw_image(discardable_image[1][1].get(), + recording_source->add_draw_image(discardable_image[0][0], gfx::Point(0, 0)); + recording_source->add_draw_image(discardable_image[0][1], gfx::Point(260, 0)); + recording_source->add_draw_image(discardable_image[1][1], gfx::Point(260, 260)); recording_source->SetGenerateDiscardableImagesMetadata(true); recording_source->Rerecord(); @@ -212,7 +213,7 @@ TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) { std::vector<DrawImage> images; raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_EQ(discardable_image[0][0].get(), images[0].image()); + EXPECT_EQ(discardable_image[0][0], images[0].image()); } // Shifted tile sized iterators. These should find only one pixel ref. { @@ -220,7 +221,7 @@ TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) { raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_EQ(discardable_image[1][1].get(), images[0].image()); + EXPECT_EQ(discardable_image[1][1], images[0].image()); } // Ensure there's no discardable pixel refs in the empty cell { @@ -234,9 +235,9 @@ TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) { std::vector<DrawImage> images; raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), 1.f, &images); EXPECT_EQ(3u, images.size()); - EXPECT_EQ(discardable_image[0][0].get(), images[0].image()); - EXPECT_EQ(discardable_image[0][1].get(), images[1].image()); - EXPECT_EQ(discardable_image[1][1].get(), images[2].image()); + EXPECT_EQ(discardable_image[0][0], images[0].image()); + EXPECT_EQ(discardable_image[0][1], images[1].image()); + EXPECT_EQ(discardable_image[1][1], images[2].image()); } } @@ -245,7 +246,7 @@ TEST(RasterSourceTest, RasterFullContents) { float contents_scale = 1.5f; float raster_divisions = 2.f; - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); recording_source->SetBackgroundColor(SK_ColorBLACK); recording_source->SetClearCanvasWithDebugColor(false); @@ -311,7 +312,7 @@ TEST(RasterSourceTest, RasterPartialContents) { gfx::Size layer_bounds(3, 5); float contents_scale = 1.5f; - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); recording_source->SetBackgroundColor(SK_ColorGREEN); recording_source->SetClearCanvasWithDebugColor(false); @@ -403,7 +404,7 @@ TEST(RasterSourceTest, RasterPartialClear) { gfx::Size partial_bounds(2, 4); float contents_scale = 1.5f; - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); recording_source->SetBackgroundColor(SK_ColorGREEN); recording_source->SetRequiresClear(true); @@ -449,7 +450,7 @@ TEST(RasterSourceTest, RasterPartialClear) { } } - scoped_ptr<FakeRecordingSource> recording_source_light = + std::unique_ptr<FakeRecordingSource> recording_source_light = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); recording_source_light->SetBackgroundColor(SK_ColorGREEN); recording_source_light->SetRequiresClear(true); @@ -492,7 +493,7 @@ TEST(RasterSourceTest, RasterContentsTransparent) { gfx::Size layer_bounds(5, 3); float contents_scale = 0.5f; - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); recording_source->SetBackgroundColor(SK_ColorTRANSPARENT); recording_source->SetRequiresClear(true); @@ -524,7 +525,7 @@ TEST(RasterSourceTest, RasterContentsTransparent) { TEST(RasterSourceTest, GetPictureMemoryUsageIncludesClientReportedMemory) { const size_t kReportedMemoryUsageInBytes = 100 * 1024 * 1024; gfx::Size layer_bounds(5, 3); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); recording_source->set_reported_memory_usage(kReportedMemoryUsageInBytes); recording_source->Rerecord(); @@ -536,5 +537,64 @@ TEST(RasterSourceTest, GetPictureMemoryUsageIncludesClientReportedMemory) { EXPECT_LT(total_memory_usage, 2 * kReportedMemoryUsageInBytes); } +TEST(RasterSourceTest, ImageHijackCanvasRespectsSharedCanvasTransform) { + gfx::Size size(100, 100); + + // Create a recording source that is filled with red and every corner is + // green (4x4 rects in the corner are green to account for blending when + // scaling). Note that we paint an image first, so that we can force image + // hijack canvas to be used. + std::unique_ptr<FakeRecordingSource> recording_source = + FakeRecordingSource::CreateFilledRecordingSource(size); + + // 1. Paint the image. + recording_source->add_draw_image(CreateDiscardableImage(gfx::Size(5, 5)), + gfx::Point(0, 0)); + + // 2. Cover everything in red. + SkPaint paint; + paint.setColor(SK_ColorRED); + recording_source->add_draw_rect_with_paint(gfx::Rect(size), paint); + + // 3. Draw 4x4 green rects into every corner. + paint.setColor(SK_ColorGREEN); + recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 4, 4), paint); + recording_source->add_draw_rect_with_paint( + gfx::Rect(size.width() - 4, 0, 4, 4), paint); + recording_source->add_draw_rect_with_paint( + gfx::Rect(0, size.height() - 4, 4, 4), paint); + recording_source->add_draw_rect_with_paint( + gfx::Rect(size.width() - 4, size.height() - 4, 4, 4), paint); + + recording_source->SetGenerateDiscardableImagesMetadata(true); + recording_source->Rerecord(); + + bool can_use_lcd = true; + scoped_refptr<RasterSource> raster_source = + recording_source->CreateRasterSource(can_use_lcd); + SoftwareImageDecodeController controller; + raster_source->SetImageDecodeController(&controller); + + SkBitmap bitmap; + bitmap.allocN32Pixels(size.width() * 0.5f, size.height() * 0.25f); + SkCanvas canvas(bitmap); + canvas.scale(0.5f, 0.25f); + + RasterSource::PlaybackSettings settings; + settings.playback_to_shared_canvas = true; + settings.use_image_hijack_canvas = true; + raster_source->PlaybackToCanvas(&canvas, gfx::Rect(size), gfx::Rect(size), + 1.f, settings); + + EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); + EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(49, 0)); + EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 24)); + EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(49, 24)); + for (int x = 0; x < 49; ++x) + EXPECT_EQ(SK_ColorRED, bitmap.getColor(x, 12)); + for (int y = 0; y < 24; ++y) + EXPECT_EQ(SK_ColorRED, bitmap.getColor(24, y)); +} + } // namespace } // namespace cc diff --git a/chromium/cc/playback/recording_source.cc b/chromium/cc/playback/recording_source.cc index 4cd414c0bd1..feaae880757 100644 --- a/chromium/cc/playback/recording_source.cc +++ b/chromium/cc/playback/recording_source.cc @@ -9,7 +9,6 @@ #include <algorithm> #include "base/numerics/safe_math.h" -#include "cc/base/histograms.h" #include "cc/base/region.h" #include "cc/layers/content_layer_client.h" #include "cc/playback/display_item_list.h" @@ -26,15 +25,6 @@ const bool kDefaultClearCanvasSetting = false; const bool kDefaultClearCanvasSetting = true; #endif -// Note that the name of the historgram doesn't match the class name -// (DisplayListRecordingSource vs RecordingSource). This is due to the fact that -// the histograms are being monitored under this particular name. -// TODO(vmpstr): Update the histograms. -DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER( - ScopedRecordingSourceUpdateTimer, - "Compositing.%s.DisplayListRecordingSource.UpdateUs", - "Compositing.%s.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs"); - } // namespace namespace cc { @@ -114,6 +104,7 @@ void RecordingSource::UpdateInvalidationForNewViewport( } void RecordingSource::FinishDisplayItemListUpdate() { + TRACE_EVENT0("cc", "RecordingSource::FinishDisplayItemListUpdate"); DetermineIfSolidColor(); display_list_->EmitTraceSnapshot(); if (generate_discardable_images_metadata_) @@ -133,14 +124,10 @@ bool RecordingSource::UpdateAndExpandInvalidation( const gfx::Size& layer_size, int frame_number, RecordingMode recording_mode) { - ScopedRecordingSourceUpdateTimer timer; bool updated = false; - // TODO(chrishtr): delete this conditional once synchronized paint launches. - if (size_ != layer_size) { + if (size_ != layer_size) size_ = layer_size; - updated = true; - } invalidation_.Swap(invalidation); invalidation_.Clear(); @@ -153,12 +140,6 @@ bool RecordingSource::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().GetCheckedArea()); - if (!updated && !invalidation->Intersects(recorded_viewport_)) return false; @@ -247,6 +228,8 @@ void RecordingSource::DetermineIfSolidColor() { if (!display_list_->ShouldBeAnalyzedForSolidColor()) return; + TRACE_EVENT1("cc", "RecordingSource::DetermineIfSolidColor", "opcount", + display_list_->ApproximateOpCount()); gfx::Size layer_size = GetSize(); skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height()); display_list_->Raster(&canvas, nullptr, gfx::Rect(), 1.f); diff --git a/chromium/cc/playback/recording_source.h b/chromium/cc/playback/recording_source.h index 7da3e64f013..9e5aa7e95ae 100644 --- a/chromium/cc/playback/recording_source.h +++ b/chromium/cc/playback/recording_source.h @@ -7,9 +7,10 @@ #include <stddef.h> +#include <memory> + #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/base/invalidation_region.h" #include "third_party/skia/include/core/SkColor.h" diff --git a/chromium/cc/playback/recording_source_unittest.cc b/chromium/cc/playback/recording_source_unittest.cc index b4b8d250413..878242db4d3 100644 --- a/chromium/cc/playback/recording_source_unittest.cc +++ b/chromium/cc/playback/recording_source_unittest.cc @@ -4,6 +4,7 @@ #include <vector> +#include "base/memory/ptr_util.h" #include "cc/base/region.h" #include "cc/playback/raster_source.h" #include "cc/proto/recording_source.pb.h" @@ -12,14 +13,15 @@ #include "cc/test/fake_recording_source.h" #include "cc/test/skia_common.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkRefCnt.h" namespace cc { namespace { -scoped_ptr<FakeRecordingSource> CreateRecordingSource( +std::unique_ptr<FakeRecordingSource> CreateRecordingSource( const gfx::Rect& viewport) { gfx::Rect layer_rect(viewport.right(), viewport.bottom()); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateRecordingSource(viewport, layer_rect.size()); return recording_source; } @@ -32,9 +34,9 @@ scoped_refptr<RasterSource> CreateRasterSource( } void ValidateRecordingSourceSerialization(FakeRecordingSource* source) { - scoped_ptr<FakeImageSerializationProcessor> + std::unique_ptr<FakeImageSerializationProcessor> fake_image_serialization_processor = - make_scoped_ptr(new FakeImageSerializationProcessor); + base::WrapUnique(new FakeImageSerializationProcessor); proto::RecordingSource proto; source->ToProtobuf(&proto, fake_image_serialization_processor.get()); @@ -48,7 +50,7 @@ void ValidateRecordingSourceSerialization(FakeRecordingSource* source) { TEST(RecordingSourceTest, TestNullDisplayListSerialization) { gfx::Rect recorded_viewport(0, 0, 256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); recording_source->SetDisplayListUsesCachedPicture(false); recording_source->SetGenerateDiscardableImagesMetadata(true); @@ -61,7 +63,7 @@ TEST(RecordingSourceTest, TestNullDisplayListSerialization) { TEST(RecordingSourceTest, TestEmptySerializationDeserialization) { gfx::Rect recorded_viewport(0, 0, 256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); recording_source->SetDisplayListUsesCachedPicture(false); recording_source->SetGenerateDiscardableImagesMetadata(true); @@ -73,7 +75,7 @@ TEST(RecordingSourceTest, TestEmptySerializationDeserialization) { TEST(RecordingSourceTest, TestPopulatedSerializationDeserialization) { gfx::Rect recorded_viewport(0, 0, 256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); recording_source->SetDisplayListUsesCachedPicture(false); @@ -97,10 +99,10 @@ TEST(RecordingSourceTest, TestPopulatedSerializationDeserialization) { TEST(RecordingSourceTest, DiscardableImagesWithTransform) { gfx::Rect recorded_viewport(256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource( recorded_viewport.size()); - skia::RefPtr<SkImage> discardable_image[2][2]; + sk_sp<SkImage> discardable_image[2][2]; gfx::Transform identity_transform; discardable_image[0][0] = CreateDiscardableImage(gfx::Size(32, 32)); // Translate transform is equivalent to moving using point. @@ -120,11 +122,11 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { gfx::RectF rotate_rect = rect; rotate_transform.TransformRect(&rotate_rect); - recording_source->add_draw_image_with_transform(discardable_image[0][0].get(), + recording_source->add_draw_image_with_transform(discardable_image[0][0], identity_transform); - recording_source->add_draw_image_with_transform(discardable_image[1][0].get(), + recording_source->add_draw_image_with_transform(discardable_image[1][0], translate_transform); - recording_source->add_draw_image_with_transform(discardable_image[1][1].get(), + recording_source->add_draw_image_with_transform(discardable_image[1][1], rotate_transform); recording_source->SetGenerateDiscardableImagesMetadata(true); recording_source->Rerecord(); @@ -140,8 +142,8 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), 1.f, &images); EXPECT_EQ(2u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[0][0].get()); - EXPECT_TRUE(images[1].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[0][0]); + EXPECT_TRUE(images[1].image() == discardable_image[1][1]); } // Shifted tile sized iterators. These should find only one pixel ref. @@ -150,7 +152,7 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 140, 128, 128), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } // The rotated bitmap would still be in the top right tile. @@ -159,7 +161,7 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } // Layer sized iterators. These should find all pixel refs. @@ -169,9 +171,9 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { &images); EXPECT_EQ(3u, images.size()); // Top left tile with bitmap[0][0] and bitmap[1][1]. - EXPECT_TRUE(images[0].image() == discardable_image[0][0].get()); - EXPECT_TRUE(images[1].image() == discardable_image[1][0].get()); - EXPECT_TRUE(images[2].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[0][0]); + EXPECT_TRUE(images[1].image() == discardable_image[1][0]); + EXPECT_TRUE(images[2].image() == discardable_image[1][1]); } // Verify different raster scales @@ -188,7 +190,7 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { TEST(RecordingSourceTest, NoGatherImageEmptyImages) { gfx::Rect recorded_viewport(0, 0, 256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); recording_source->SetGenerateDiscardableImagesMetadata(false); recording_source->Rerecord(); @@ -208,7 +210,7 @@ TEST(RecordingSourceTest, NoGatherImageEmptyImages) { TEST(RecordingSourceTest, EmptyImages) { gfx::Rect recorded_viewport(0, 0, 256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); recording_source->SetGenerateDiscardableImagesMetadata(true); recording_source->Rerecord(); @@ -242,7 +244,7 @@ TEST(RecordingSourceTest, EmptyImages) { TEST(RecordingSourceTest, NoDiscardableImages) { gfx::Rect recorded_viewport(0, 0, 256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); SkPaint simple_paint; @@ -251,8 +253,8 @@ TEST(RecordingSourceTest, NoDiscardableImages) { SkBitmap non_discardable_bitmap; non_discardable_bitmap.allocN32Pixels(128, 128); non_discardable_bitmap.setImmutable(); - skia::RefPtr<SkImage> non_discardable_image = - skia::AdoptRef(SkImage::NewFromBitmap(non_discardable_bitmap)); + sk_sp<SkImage> non_discardable_image = + SkImage::MakeFromBitmap(non_discardable_bitmap); recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 256, 256), simple_paint); @@ -262,12 +264,9 @@ TEST(RecordingSourceTest, NoDiscardableImages) { simple_paint); recording_source->add_draw_rect_with_paint(gfx::Rect(0, 512, 256, 256), simple_paint); - recording_source->add_draw_image(non_discardable_image.get(), - gfx::Point(128, 0)); - recording_source->add_draw_image(non_discardable_image.get(), - gfx::Point(0, 128)); - recording_source->add_draw_image(non_discardable_image.get(), - gfx::Point(150, 150)); + recording_source->add_draw_image(non_discardable_image, gfx::Point(128, 0)); + recording_source->add_draw_image(non_discardable_image, gfx::Point(0, 128)); + recording_source->add_draw_image(non_discardable_image, gfx::Point(150, 150)); recording_source->SetGenerateDiscardableImagesMetadata(true); recording_source->Rerecord(); @@ -300,10 +299,10 @@ TEST(RecordingSourceTest, NoDiscardableImages) { TEST(RecordingSourceTest, DiscardableImages) { gfx::Rect recorded_viewport(0, 0, 256, 256); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); - skia::RefPtr<SkImage> discardable_image[2][2]; + sk_sp<SkImage> discardable_image[2][2]; discardable_image[0][0] = CreateDiscardableImage(gfx::Size(32, 32)); discardable_image[1][0] = CreateDiscardableImage(gfx::Size(32, 32)); discardable_image[1][1] = CreateDiscardableImage(gfx::Size(32, 32)); @@ -314,11 +313,9 @@ TEST(RecordingSourceTest, DiscardableImages) { // |---|---| // | x | x | // |---|---| - recording_source->add_draw_image(discardable_image[0][0].get(), - gfx::Point(0, 0)); - recording_source->add_draw_image(discardable_image[1][0].get(), - gfx::Point(0, 130)); - recording_source->add_draw_image(discardable_image[1][1].get(), + recording_source->add_draw_image(discardable_image[0][0], gfx::Point(0, 0)); + recording_source->add_draw_image(discardable_image[1][0], gfx::Point(0, 130)); + recording_source->add_draw_image(discardable_image[1][1], gfx::Point(140, 140)); recording_source->SetGenerateDiscardableImagesMetadata(true); recording_source->Rerecord(); @@ -332,7 +329,7 @@ TEST(RecordingSourceTest, DiscardableImages) { raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[0][0].get()); + EXPECT_TRUE(images[0].image() == discardable_image[0][0]); } // Shifted tile sized iterators. These should find only one image. @@ -341,7 +338,7 @@ TEST(RecordingSourceTest, DiscardableImages) { raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 140, 128, 128), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } // Ensure there's no discardable images in the empty cell @@ -358,25 +355,25 @@ TEST(RecordingSourceTest, DiscardableImages) { raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, &images); EXPECT_EQ(3u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[0][0].get()); - EXPECT_TRUE(images[1].image() == discardable_image[1][0].get()); - EXPECT_TRUE(images[2].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[0][0]); + EXPECT_TRUE(images[1].image() == discardable_image[1][0]); + EXPECT_TRUE(images[2].image() == discardable_image[1][1]); } } TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) { gfx::Rect recorded_viewport(0, 0, 512, 512); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = CreateRecordingSource(recorded_viewport); SkBitmap non_discardable_bitmap; non_discardable_bitmap.allocN32Pixels(512, 512); non_discardable_bitmap.setImmutable(); - skia::RefPtr<SkImage> non_discardable_image = - skia::AdoptRef(SkImage::NewFromBitmap(non_discardable_bitmap)); + sk_sp<SkImage> non_discardable_image = + SkImage::MakeFromBitmap(non_discardable_bitmap); - skia::RefPtr<SkImage> discardable_image[2][2]; + sk_sp<SkImage> discardable_image[2][2]; discardable_image[0][0] = CreateDiscardableImage(gfx::Size(128, 128)); discardable_image[0][1] = CreateDiscardableImage(gfx::Size(128, 128)); discardable_image[1][1] = CreateDiscardableImage(gfx::Size(128, 128)); @@ -388,13 +385,10 @@ TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) { // |---|---| // | | x | // |---|---| - recording_source->add_draw_image(non_discardable_image.get(), - gfx::Point(0, 0)); - recording_source->add_draw_image(discardable_image[0][0].get(), - gfx::Point(0, 0)); - recording_source->add_draw_image(discardable_image[0][1].get(), - gfx::Point(260, 0)); - recording_source->add_draw_image(discardable_image[1][1].get(), + recording_source->add_draw_image(non_discardable_image, gfx::Point(0, 0)); + recording_source->add_draw_image(discardable_image[0][0], gfx::Point(0, 0)); + recording_source->add_draw_image(discardable_image[0][1], gfx::Point(260, 0)); + recording_source->add_draw_image(discardable_image[1][1], gfx::Point(260, 260)); recording_source->SetGenerateDiscardableImagesMetadata(true); recording_source->Rerecord(); @@ -408,7 +402,7 @@ TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) { raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[0][0].get()); + EXPECT_TRUE(images[0].image() == discardable_image[0][0]); } // Shifted tile sized iterators. These should find only one image. { @@ -416,7 +410,7 @@ TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) { raster_source->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), 1.f, &images); EXPECT_EQ(1u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } // Ensure there's no discardable images in the empty cell { @@ -431,9 +425,9 @@ TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) { raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), 1.f, &images); EXPECT_EQ(3u, images.size()); - EXPECT_TRUE(images[0].image() == discardable_image[0][0].get()); - EXPECT_TRUE(images[1].image() == discardable_image[0][1].get()); - EXPECT_TRUE(images[2].image() == discardable_image[1][1].get()); + EXPECT_TRUE(images[0].image() == discardable_image[0][0]); + EXPECT_TRUE(images[1].image() == discardable_image[0][1]); + EXPECT_TRUE(images[2].image() == discardable_image[1][1]); } } diff --git a/chromium/cc/playback/transform_display_item.h b/chromium/cc/playback/transform_display_item.h index 7c1d934f550..9246ae2d75f 100644 --- a/chromium/cc/playback/transform_display_item.h +++ b/chromium/cc/playback/transform_display_item.h @@ -7,7 +7,9 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/playback/display_item.h" #include "ui/gfx/transform.h" @@ -34,7 +36,6 @@ class CC_EXPORT TransformDisplayItem : public DisplayItem { size_t ExternalMemoryUsage() const override; int ApproximateOpCount() const { return 1; } - bool IsSuitableForGpuRasterization() const { return true; } private: void SetNew(const gfx::Transform& transform); @@ -48,8 +49,8 @@ class CC_EXPORT EndTransformDisplayItem : public DisplayItem { explicit EndTransformDisplayItem(const proto::DisplayItem& proto); ~EndTransformDisplayItem() override; - static scoped_ptr<EndTransformDisplayItem> Create() { - return make_scoped_ptr(new EndTransformDisplayItem()); + static std::unique_ptr<EndTransformDisplayItem> Create() { + return base::WrapUnique(new EndTransformDisplayItem()); } void ToProtobuf(proto::DisplayItem* proto, diff --git a/chromium/cc/proto/begin_main_frame_and_commit_state.proto b/chromium/cc/proto/begin_main_frame_and_commit_state.proto index 9881131273c..724201a2365 100644 --- a/chromium/cc/proto/begin_main_frame_and_commit_state.proto +++ b/chromium/cc/proto/begin_main_frame_and_commit_state.proto @@ -47,4 +47,6 @@ message BeginMainFrameAndCommitState { optional ScrollAndScaleSet scroll_info = 3; optional int64 memory_allocation_limit_bytes = 4; optional bool evicted_ui_resources = 5; -}
\ No newline at end of file + optional bool has_fixed_raster_scale_blurry_content = 6; + optional bool has_fixed_raster_scale_potential_performance_regression = 7; +} diff --git a/chromium/cc/proto/cc_conversions.cc b/chromium/cc/proto/cc_conversions.cc index 7e466f373a1..92da5634e2e 100644 --- a/chromium/cc/proto/cc_conversions.cc +++ b/chromium/cc/proto/cc_conversions.cc @@ -22,4 +22,27 @@ Region RegionFromProto(const proto::Region& proto) { return region; } +proto::SolidColorScrollbarLayerProperties::ScrollbarOrientation +ScrollbarOrientationToProto(const ScrollbarOrientation& orientation) { + switch (orientation) { + case ScrollbarOrientation::HORIZONTAL: + return proto::SolidColorScrollbarLayerProperties::HORIZONTAL; + case ScrollbarOrientation::VERTICAL: + return proto::SolidColorScrollbarLayerProperties::VERTICAL; + } + return proto::SolidColorScrollbarLayerProperties::HORIZONTAL; +} + +ScrollbarOrientation ScrollbarOrientationFromProto( + const proto::SolidColorScrollbarLayerProperties::ScrollbarOrientation& + proto) { + switch (proto) { + case proto::SolidColorScrollbarLayerProperties::HORIZONTAL: + return ScrollbarOrientation::HORIZONTAL; + case proto::SolidColorScrollbarLayerProperties::VERTICAL: + return ScrollbarOrientation::VERTICAL; + } + return ScrollbarOrientation::HORIZONTAL; +} + } // namespace cc diff --git a/chromium/cc/proto/cc_conversions.h b/chromium/cc/proto/cc_conversions.h index 4060e6f5a0f..78c697b8896 100644 --- a/chromium/cc/proto/cc_conversions.h +++ b/chromium/cc/proto/cc_conversions.h @@ -6,6 +6,8 @@ #define CC_PROTO_CC_CONVERSIONS_H_ #include "cc/base/cc_export.h" +#include "cc/input/scrollbar.h" +#include "cc/proto/layer.pb.h" namespace cc { class Region; @@ -19,6 +21,13 @@ class Region; CC_EXPORT void RegionToProto(const Region& region, proto::Region* proto); CC_EXPORT Region RegionFromProto(const proto::Region& proto); +// Conversion methods for ScrollbarOrientation. +CC_EXPORT proto::SolidColorScrollbarLayerProperties::ScrollbarOrientation +ScrollbarOrientationToProto(const ScrollbarOrientation& orientation); +CC_EXPORT ScrollbarOrientation ScrollbarOrientationFromProto( + const proto::SolidColorScrollbarLayerProperties::ScrollbarOrientation& + proto); + } // namespace cc #endif // CC_PROTO_CC_CONVERSIONS_H_ diff --git a/chromium/cc/proto/cc_conversions_unittest.cc b/chromium/cc/proto/cc_conversions_unittest.cc index 8612dda7d09..cb9bdd591ec 100644 --- a/chromium/cc/proto/cc_conversions_unittest.cc +++ b/chromium/cc/proto/cc_conversions_unittest.cc @@ -50,5 +50,16 @@ TEST(RegionTest, OverlappingRectSubtractProtoConversion) { VerifySerializeAndDeserializeProto(region); } +TEST(ScrollbarOrientationTest, ScrollbarOrientationToProtoConversion) { + ASSERT_NE(ScrollbarOrientation::HORIZONTAL, ScrollbarOrientation::VERTICAL); + ScrollbarOrientation orientation = ScrollbarOrientation::HORIZONTAL; + EXPECT_EQ(orientation, ScrollbarOrientationFromProto( + ScrollbarOrientationToProto(orientation))); + + orientation = ScrollbarOrientation::VERTICAL; + EXPECT_EQ(orientation, ScrollbarOrientationFromProto( + ScrollbarOrientationToProto(orientation))); +} + } // namespace } // namespace cc diff --git a/chromium/cc/proto/gfx_conversions.cc b/chromium/cc/proto/gfx_conversions.cc index 3abc59fcd7c..1d01a9a766e 100644 --- a/chromium/cc/proto/gfx_conversions.cc +++ b/chromium/cc/proto/gfx_conversions.cc @@ -100,6 +100,9 @@ gfx::SizeF ProtoToSizeF(const proto::SizeF& proto) { void TransformToProto(const gfx::Transform& transform, proto::Transform* proto) { + if (transform.IsIdentity()) + return; + for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { proto->add_matrix(transform.matrix().get(i, j)); @@ -110,6 +113,7 @@ void TransformToProto(const gfx::Transform& transform, gfx::Transform ProtoToTransform(const proto::Transform& proto) { if (proto.matrix_size() == 0) return gfx::Transform(); + gfx::Transform transform(gfx::Transform::kSkipInitialization); DCHECK_EQ(16, proto.matrix_size()); for (int i = 0; i < 4; i++) { diff --git a/chromium/cc/proto/gfx_conversions_unittest.cc b/chromium/cc/proto/gfx_conversions_unittest.cc index 1132304374b..2f35a03059f 100644 --- a/chromium/cc/proto/gfx_conversions_unittest.cc +++ b/chromium/cc/proto/gfx_conversions_unittest.cc @@ -192,6 +192,13 @@ TEST(GfxProtoConversionsTest, SerializeDeserializeTransform) { // Test ProtoToTransform EXPECT_EQ(transform, ProtoToTransform(proto)); + + // Test for identity transforms. + gfx::Transform transform2; + EXPECT_TRUE(transform2.IsIdentity()); + proto::Transform proto2; + TransformToProto(transform2, &proto2); + EXPECT_EQ(transform2, ProtoToTransform(proto2)); } TEST(GfxProtoConversionsTest, SerializeDeserializeVector2dF) { diff --git a/chromium/cc/proto/image_serialization_processor.h b/chromium/cc/proto/image_serialization_processor.h index 75b9936417e..2827eb4587c 100644 --- a/chromium/cc/proto/image_serialization_processor.h +++ b/chromium/cc/proto/image_serialization_processor.h @@ -6,7 +6,6 @@ #define CC_PROTO_IMAGE_SERIALIZATION_PROCESSOR_H_ #include "third_party/skia/include/core/SkPicture.h" -#include "third_party/skia/include/core/SkPixelSerializer.h" class SkPixelSerializer; diff --git a/chromium/cc/proto/layer.proto b/chromium/cc/proto/layer.proto index ed41f3f5969..209a565efc9 100644 --- a/chromium/cc/proto/layer.proto +++ b/chromium/cc/proto/layer.proto @@ -29,6 +29,7 @@ message LayerNode { LAYER = 1; PICTURE_LAYER = 2; HEADS_UP_DISPLAY_LAYER = 3; + SOLID_COLOR_SCROLLBAR_LAYER = 4; // TODO(nyquist): Add the rest of the necessary LayerTypes. }; @@ -63,6 +64,7 @@ message LayerProperties { // TODO(dtrainor): use a 'oneof' union when it's supported in Chromium. See // crbug.com/570371. optional PictureLayerProperties picture = 6; + optional SolidColorScrollbarLayerProperties solid_scrollbar = 7; } // NEXT ID: 54 @@ -79,7 +81,6 @@ message BaseLayerProperties { optional bool double_sided = 8; optional bool draws_content = 9; optional bool hide_layer_and_subtree = 10; - optional bool has_render_surface = 11; optional bool subtree_property_changed = 47; // TODO(nyquist): Add support for FilterOperation. See crbug.com/541321. // repeated FilterOperation filters = 12; @@ -107,6 +108,7 @@ message BaseLayerProperties { optional bool transform_is_invertible = 34; optional int32 sorting_context_id = 35; optional int32 num_descendants_that_draw_content = 36; + optional bool has_will_change_transform_hint = 48; optional int32 scroll_clip_layer_id = 37; optional bool user_scrollable_horizontal = 38; @@ -123,10 +125,7 @@ message BaseLayerProperties { optional Rect update_rect = 46; // TODO(nyquist): Figure out what to do with LayerAnimationController. - // optional LayerAnimationController layer_animation_controller = 48; - - // TODO(nyquist): Figure out what to do with FrameTimingRequests. - // repeated FrameTimingRequest frame_timing_requests = 49; + // optional LayerAnimationController layer_animation_controller = ???; } message PictureLayerProperties { @@ -138,3 +137,16 @@ message PictureLayerProperties { optional int64 update_source_frame_number = 6; } + +message SolidColorScrollbarLayerProperties { + enum ScrollbarOrientation { + HORIZONTAL = 0; + VERTICAL = 1; + }; + + optional int32 scroll_layer_id = 1; + optional int32 thumb_thickness = 2; + optional int32 track_start = 3; + optional bool is_left_side_vertical_scrollbar = 4; + optional ScrollbarOrientation orientation = 5; +} diff --git a/chromium/cc/proto/layer_tree_host.proto b/chromium/cc/proto/layer_tree_host.proto index 407061f720a..50616332076 100644 --- a/chromium/cc/proto/layer_tree_host.proto +++ b/chromium/cc/proto/layer_tree_host.proto @@ -6,7 +6,6 @@ syntax = "proto2"; import "layer.proto"; import "layer_selection_bound.proto"; -import "layer_tree_settings.proto"; import "layer_tree_debug_state.proto"; import "property_tree.proto"; import "size.proto"; diff --git a/chromium/cc/proto/layer_tree_settings.proto b/chromium/cc/proto/layer_tree_settings.proto index fa141f15c17..8a24623a3b3 100644 --- a/chromium/cc/proto/layer_tree_settings.proto +++ b/chromium/cc/proto/layer_tree_settings.proto @@ -52,7 +52,7 @@ message LayerTreeSettings { optional Size minimum_occlusion_tracking_size = 29; optional uint32 tiling_interest_area_padding = 30; optional float skewport_target_time_in_seconds = 31; - optional int32 skewport_extrapolation_limit_in_content_pixels = 32; + optional int32 skewport_extrapolation_limit_in_screen_pixels = 32; optional uint32 max_memory_for_prepaint_percentage = 33; optional bool use_zero_copy = 35; optional bool use_partial_raster = 36; @@ -69,4 +69,5 @@ message LayerTreeSettings { optional LayerTreeDebugState initial_debug_state = 49; optional bool use_mouse_wheel_gestures = 50; optional bool use_cached_picture_raster = 51; + optional bool async_worker_context_enabled = 52; } diff --git a/chromium/cc/proto/property_tree.proto b/chromium/cc/proto/property_tree.proto index cfcbc63f072..12dd474ffaf 100644 --- a/chromium/cc/proto/property_tree.proto +++ b/chromium/cc/proto/property_tree.proto @@ -19,7 +19,7 @@ package cc.proto; // cc/trees/property_tree.h // Proto for struct TransformNodeData. -// NEXT ID: 41 +// NEXT ID: 43 message TranformNodeData { optional Transform pre_local = 1; optional Transform local = 2; @@ -34,9 +34,11 @@ message TranformNodeData { optional int64 content_target_id = 10; optional int64 source_node_id = 11; optional bool needs_local_transform_update = 12; + optional bool node_and_ancestors_are_animated_or_invertible = 41; optional bool is_invertible = 13; optional bool ancestors_are_invertible = 14; - optional bool is_animated = 15; + optional bool has_potential_animation = 15; + optional bool is_currently_animating = 42; optional bool to_screen_is_potentially_animated = 16; optional bool has_only_translation_animations = 17; optional bool to_screen_has_scale_animation = 18; @@ -90,12 +92,12 @@ message EffectNodeData { optional bool has_render_surface = 3; optional bool has_copy_request = 4; optional bool has_background_filters = 5; - optional bool node_or_ancestor_has_background_filters = 13; - optional bool to_screen_opacity_is_animated = 14; - optional bool hidden_by_backface_visibility = 15; - optional bool double_sided = 16; + optional bool hidden_by_backface_visibility = 14; + optional bool double_sided = 13; optional bool is_drawn = 6; - optional bool has_animated_opacity = 7; + optional bool subtree_hidden = 15; + optional bool has_potential_opacity_animation = 7; + optional bool is_currently_animating_opacity = 16; optional bool effect_changed = 11; optional int64 num_copy_requests_in_subtree = 8; optional int64 transform_id = 9; @@ -186,7 +188,7 @@ message TransformTreeData { } // Proto for class PropertyTrees. -// NEXT ID: 14 +// NEXT ID: 16 message PropertyTrees { optional PropertyTree transform_tree = 1; optional PropertyTree effect_tree = 2; @@ -204,4 +206,5 @@ message PropertyTrees { optional Vector2dF inner_viewport_container_bounds_delta = 8; optional Vector2dF outer_viewport_container_bounds_delta = 9; optional Vector2dF inner_viewport_scroll_bounds_delta = 10; + repeated int64 always_use_active_tree_opacity_effect_ids = 15 [packed = true]; } diff --git a/chromium/cc/proto/skia_conversions.cc b/chromium/cc/proto/skia_conversions.cc index 84acdd4cdbb..545dc491ea7 100644 --- a/chromium/cc/proto/skia_conversions.cc +++ b/chromium/cc/proto/skia_conversions.cc @@ -27,17 +27,17 @@ SkPoint ProtoToSkPoint(const proto::PointF& proto) { SkRegion::Op SkRegionOpFromProto(proto::SkRegion::Op op) { switch (op) { - case proto::SkRegion::Op_Difference: + case proto::SkRegion::DIFFERENCE_: return SkRegion::Op::kDifference_Op; - case proto::SkRegion::Op_Intersect: + case proto::SkRegion::INTERSECT: return SkRegion::Op::kIntersect_Op; - case proto::SkRegion::Op_Union: + case proto::SkRegion::UNION: return SkRegion::Op::kUnion_Op; - case proto::SkRegion::Op_XOR: + case proto::SkRegion::XOR: return SkRegion::Op::kXOR_Op; - case proto::SkRegion::Op_ReverseDifference: + case proto::SkRegion::REVERSE_DIFFERENCE: return SkRegion::Op::kReverseDifference_Op; - case proto::SkRegion::Op_Replace: + case proto::SkRegion::REPLACE: return SkRegion::Op::kReplace_Op; } return SkRegion::Op::kDifference_Op; @@ -46,80 +46,80 @@ SkRegion::Op SkRegionOpFromProto(proto::SkRegion::Op op) { proto::SkRegion::Op SkRegionOpToProto(SkRegion::Op op) { switch (op) { case SkRegion::Op::kDifference_Op: - return proto::SkRegion::Op_Difference; + return proto::SkRegion::DIFFERENCE_; case SkRegion::Op::kIntersect_Op: - return proto::SkRegion::Op_Intersect; + return proto::SkRegion::INTERSECT; case SkRegion::Op::kUnion_Op: - return proto::SkRegion::Op_Union; + return proto::SkRegion::UNION; case SkRegion::Op::kXOR_Op: - return proto::SkRegion::Op_XOR; + return proto::SkRegion::XOR; case SkRegion::Op::kReverseDifference_Op: - return proto::SkRegion::Op_ReverseDifference; + return proto::SkRegion::REVERSE_DIFFERENCE; case SkRegion::Op::kReplace_Op: - return proto::SkRegion::Op_Replace; + return proto::SkRegion::REPLACE; } - return proto::SkRegion::Op_Difference; + return proto::SkRegion::DIFFERENCE_; } SkXfermode::Mode SkXfermodeModeFromProto(proto::SkXfermode::Mode mode) { switch (mode) { - case proto::SkXfermode::Mode_Clear: + case proto::SkXfermode::CLEAR_: return SkXfermode::Mode::kClear_Mode; - case proto::SkXfermode::Mode_Src: + case proto::SkXfermode::SRC: return SkXfermode::Mode::kSrc_Mode; - case proto::SkXfermode::Mode_Dst: + case proto::SkXfermode::DST: return SkXfermode::Mode::kDst_Mode; - case proto::SkXfermode::Mode_SrcOver: + case proto::SkXfermode::SRC_OVER: return SkXfermode::Mode::kSrcOver_Mode; - case proto::SkXfermode::Mode_DstOver: + case proto::SkXfermode::DST_OVER: return SkXfermode::Mode::kDstOver_Mode; - case proto::SkXfermode::Mode_SrcIn: + case proto::SkXfermode::SRC_IN: return SkXfermode::Mode::kSrcIn_Mode; - case proto::SkXfermode::Mode_DstIn: + case proto::SkXfermode::DST_IN: return SkXfermode::Mode::kDstIn_Mode; - case proto::SkXfermode::Mode_SrcOut: + case proto::SkXfermode::SRC_OUT: return SkXfermode::Mode::kSrcOut_Mode; - case proto::SkXfermode::Mode_DstOut: + case proto::SkXfermode::DST_OUT: return SkXfermode::Mode::kDstOut_Mode; - case proto::SkXfermode::Mode_SrcATop: + case proto::SkXfermode::SRC_A_TOP: return SkXfermode::Mode::kSrcATop_Mode; - case proto::SkXfermode::Mode_DstATop: + case proto::SkXfermode::DST_A_TOP: return SkXfermode::Mode::kDstATop_Mode; - case proto::SkXfermode::Mode_XOR: + case proto::SkXfermode::XOR: return SkXfermode::Mode::kXor_Mode; - case proto::SkXfermode::Mode_Plus: + case proto::SkXfermode::PLUS: return SkXfermode::Mode::kPlus_Mode; - case proto::SkXfermode::Mode_Modulate: + case proto::SkXfermode::MODULATE: return SkXfermode::Mode::kModulate_Mode; - case proto::SkXfermode::Mode_Screen: + case proto::SkXfermode::SCREEN: return SkXfermode::Mode::kScreen_Mode; - case proto::SkXfermode::Mode_Overlay: + case proto::SkXfermode::OVERLAY: return SkXfermode::Mode::kOverlay_Mode; - case proto::SkXfermode::Mode_Darken: + case proto::SkXfermode::DARKEN: return SkXfermode::Mode::kDarken_Mode; - case proto::SkXfermode::Mode_Lighten: + case proto::SkXfermode::LIGHTEN: return SkXfermode::Mode::kLighten_Mode; - case proto::SkXfermode::Mode_ColorDodge: + case proto::SkXfermode::COLOR_DODGE: return SkXfermode::Mode::kColorDodge_Mode; - case proto::SkXfermode::Mode_ColorBurn: + case proto::SkXfermode::COLOR_BURN: return SkXfermode::Mode::kColorBurn_Mode; - case proto::SkXfermode::Mode_HardLight: + case proto::SkXfermode::HARD_LIGHT: return SkXfermode::Mode::kHardLight_Mode; - case proto::SkXfermode::Mode_SoftLight: + case proto::SkXfermode::SOFT_LIGHT: return SkXfermode::Mode::kSoftLight_Mode; - case proto::SkXfermode::Mode_Difference: + case proto::SkXfermode::DIFFERENCE_: return SkXfermode::Mode::kDifference_Mode; - case proto::SkXfermode::Mode_Exclusion: + case proto::SkXfermode::EXCLUSION: return SkXfermode::Mode::kExclusion_Mode; - case proto::SkXfermode::Mode_Multiply: + case proto::SkXfermode::MULTIPLY: return SkXfermode::Mode::kMultiply_Mode; - case proto::SkXfermode::Mode_Hue: + case proto::SkXfermode::HUE: return SkXfermode::Mode::kHue_Mode; - case proto::SkXfermode::Mode_Saturation: + case proto::SkXfermode::SATURATION: return SkXfermode::Mode::kSaturation_Mode; - case proto::SkXfermode::Mode_Color: + case proto::SkXfermode::COLOR: return SkXfermode::Mode::kColor_Mode; - case proto::SkXfermode::Mode_Luminosity: + case proto::SkXfermode::LUMINOSITY: return SkXfermode::Mode::kLuminosity_Mode; } return SkXfermode::Mode::kClear_Mode; @@ -128,65 +128,65 @@ SkXfermode::Mode SkXfermodeModeFromProto(proto::SkXfermode::Mode mode) { proto::SkXfermode::Mode SkXfermodeModeToProto(SkXfermode::Mode mode) { switch (mode) { case SkXfermode::Mode::kClear_Mode: - return proto::SkXfermode::Mode_Clear; + return proto::SkXfermode::CLEAR_; case SkXfermode::Mode::kSrc_Mode: - return proto::SkXfermode::Mode_Src; + return proto::SkXfermode::SRC; case SkXfermode::Mode::kDst_Mode: - return proto::SkXfermode::Mode_Dst; + return proto::SkXfermode::DST; case SkXfermode::Mode::kSrcOver_Mode: - return proto::SkXfermode::Mode_SrcOver; + return proto::SkXfermode::SRC_OVER; case SkXfermode::Mode::kDstOver_Mode: - return proto::SkXfermode::Mode_DstOver; + return proto::SkXfermode::DST_OVER; case SkXfermode::Mode::kSrcIn_Mode: - return proto::SkXfermode::Mode_SrcIn; + return proto::SkXfermode::SRC_IN; case SkXfermode::Mode::kDstIn_Mode: - return proto::SkXfermode::Mode_DstIn; + return proto::SkXfermode::DST_IN; case SkXfermode::Mode::kSrcOut_Mode: - return proto::SkXfermode::Mode_SrcOut; + return proto::SkXfermode::SRC_OUT; case SkXfermode::Mode::kDstOut_Mode: - return proto::SkXfermode::Mode_DstOut; + return proto::SkXfermode::DST_OUT; case SkXfermode::Mode::kSrcATop_Mode: - return proto::SkXfermode::Mode_SrcATop; + return proto::SkXfermode::SRC_A_TOP; case SkXfermode::Mode::kDstATop_Mode: - return proto::SkXfermode::Mode_DstATop; + return proto::SkXfermode::DST_A_TOP; case SkXfermode::Mode::kXor_Mode: - return proto::SkXfermode::Mode_XOR; + return proto::SkXfermode::XOR; case SkXfermode::Mode::kPlus_Mode: - return proto::SkXfermode::Mode_Plus; + return proto::SkXfermode::PLUS; case SkXfermode::Mode::kModulate_Mode: - return proto::SkXfermode::Mode_Modulate; + return proto::SkXfermode::MODULATE; case SkXfermode::Mode::kScreen_Mode: - return proto::SkXfermode::Mode_Screen; + return proto::SkXfermode::SCREEN; case SkXfermode::Mode::kOverlay_Mode: - return proto::SkXfermode::Mode_Overlay; + return proto::SkXfermode::OVERLAY; case SkXfermode::Mode::kDarken_Mode: - return proto::SkXfermode::Mode_Darken; + return proto::SkXfermode::DARKEN; case SkXfermode::Mode::kLighten_Mode: - return proto::SkXfermode::Mode_Lighten; + return proto::SkXfermode::LIGHTEN; case SkXfermode::Mode::kColorDodge_Mode: - return proto::SkXfermode::Mode_ColorDodge; + return proto::SkXfermode::COLOR_DODGE; case SkXfermode::Mode::kColorBurn_Mode: - return proto::SkXfermode::Mode_ColorBurn; + return proto::SkXfermode::COLOR_BURN; case SkXfermode::Mode::kHardLight_Mode: - return proto::SkXfermode::Mode_HardLight; + return proto::SkXfermode::HARD_LIGHT; case SkXfermode::Mode::kSoftLight_Mode: - return proto::SkXfermode::Mode_SoftLight; + return proto::SkXfermode::SOFT_LIGHT; case SkXfermode::Mode::kDifference_Mode: - return proto::SkXfermode::Mode_Difference; + return proto::SkXfermode::DIFFERENCE_; case SkXfermode::Mode::kExclusion_Mode: - return proto::SkXfermode::Mode_Exclusion; + return proto::SkXfermode::EXCLUSION; case SkXfermode::Mode::kMultiply_Mode: - return proto::SkXfermode::Mode_Multiply; + return proto::SkXfermode::MULTIPLY; case SkXfermode::Mode::kHue_Mode: - return proto::SkXfermode::Mode_Hue; + return proto::SkXfermode::HUE; case SkXfermode::Mode::kSaturation_Mode: - return proto::SkXfermode::Mode_Saturation; + return proto::SkXfermode::SATURATION; case SkXfermode::Mode::kColor_Mode: - return proto::SkXfermode::Mode_Color; + return proto::SkXfermode::COLOR; case SkXfermode::Mode::kLuminosity_Mode: - return proto::SkXfermode::Mode_Luminosity; + return proto::SkXfermode::LUMINOSITY; } - return proto::SkXfermode::Mode_Clear; + return proto::SkXfermode::CLEAR_; } void SkRRectToProto(const SkRRect& rect, proto::SkRRect* proto) { diff --git a/chromium/cc/proto/skia_conversions.h b/chromium/cc/proto/skia_conversions.h index 6735cf18780..b7adf1d32db 100644 --- a/chromium/cc/proto/skia_conversions.h +++ b/chromium/cc/proto/skia_conversions.h @@ -13,7 +13,6 @@ class SkRegion; class SkRRect; -class SkXferMode; namespace cc { diff --git a/chromium/cc/proto/skregion.proto b/chromium/cc/proto/skregion.proto index 1f6b337e9b3..d45feddf9e2 100644 --- a/chromium/cc/proto/skregion.proto +++ b/chromium/cc/proto/skregion.proto @@ -10,11 +10,11 @@ package cc.proto; message SkRegion { enum Op { - Op_Difference = 0; - Op_Intersect = 1; - Op_Union = 2; - Op_XOR = 3; - Op_ReverseDifference = 4; - Op_Replace = 5; + DIFFERENCE_ = 0; // On Windows, winuser.h defines DIFFERENCE. + INTERSECT = 1; + UNION = 2; + XOR = 3; + REVERSE_DIFFERENCE = 4; + REPLACE = 5; } -}
\ No newline at end of file +} diff --git a/chromium/cc/proto/skxfermode.proto b/chromium/cc/proto/skxfermode.proto index b0b39630beb..349aa8b9ef4 100644 --- a/chromium/cc/proto/skxfermode.proto +++ b/chromium/cc/proto/skxfermode.proto @@ -10,37 +10,37 @@ package cc.proto; message SkXfermode { enum Mode { - Mode_Clear = 0; - Mode_Src = 1; - Mode_Dst = 2; - Mode_SrcOver = 3; - Mode_DstOver = 4; - Mode_SrcIn = 5; - Mode_DstIn = 6; - Mode_SrcOut = 7; - Mode_DstOut = 8; - Mode_SrcATop = 9; - Mode_DstATop = 10; - Mode_XOR = 11; - Mode_Plus = 12; - Mode_Modulate = 13; + CLEAR_ = 0; // Clear() is a method for protos. + SRC = 1; + DST = 2; + SRC_OVER = 3; + DST_OVER = 4; + SRC_IN = 5; + DST_IN = 6; + SRC_OUT = 7; + DST_OUT = 8; + SRC_A_TOP = 9; + DST_A_TOP = 10; + XOR = 11; + PLUS = 12; + MODULATE = 13; - Mode_Screen = 14; + SCREEN = 14; - Mode_Overlay = 15; - Mode_Darken = 16; - Mode_Lighten = 17; - Mode_ColorDodge = 18; - Mode_ColorBurn = 19; - Mode_HardLight = 20; - Mode_SoftLight = 21; - Mode_Difference = 22; - Mode_Exclusion = 23; - Mode_Multiply = 24; + OVERLAY = 15; + DARKEN = 16; + LIGHTEN = 17; + COLOR_DODGE = 18; + COLOR_BURN = 19; + HARD_LIGHT = 20; + SOFT_LIGHT = 21; + DIFFERENCE_ = 22; + EXCLUSION = 23; + MULTIPLY = 24; - Mode_Hue = 25; - Mode_Saturation = 26; - Mode_Color = 27; - Mode_Luminosity = 28; + HUE = 25; + SATURATION = 26; + COLOR = 27; + LUMINOSITY = 28; } -}
\ No newline at end of file +} diff --git a/chromium/cc/proto/transform.proto b/chromium/cc/proto/transform.proto index 68862ee4e0b..eeb84a01fd0 100644 --- a/chromium/cc/proto/transform.proto +++ b/chromium/cc/proto/transform.proto @@ -9,5 +9,7 @@ option optimize_for = LITE_RUNTIME; package cc.proto; message Transform { + // If the matrix is not set, the deserializer will assume an identity + // transform. repeated float matrix = 1 [packed = true]; } diff --git a/chromium/cc/quads/content_draw_quad_base.h b/chromium/cc/quads/content_draw_quad_base.h index da8a472f008..52b1850f264 100644 --- a/chromium/cc/quads/content_draw_quad_base.h +++ b/chromium/cc/quads/content_draw_quad_base.h @@ -5,7 +5,8 @@ #ifndef CC_QUADS_CONTENT_DRAW_QUAD_BASE_H_ #define CC_QUADS_CONTENT_DRAW_QUAD_BASE_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" #include "ui/gfx/geometry/rect_f.h" diff --git a/chromium/cc/quads/debug_border_draw_quad.h b/chromium/cc/quads/debug_border_draw_quad.h index 7023ab23b5d..1a205b3304e 100644 --- a/chromium/cc/quads/debug_border_draw_quad.h +++ b/chromium/cc/quads/debug_border_draw_quad.h @@ -5,7 +5,8 @@ #ifndef CC_QUADS_DEBUG_BORDER_DRAW_QUAD_H_ #define CC_QUADS_DEBUG_BORDER_DRAW_QUAD_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" #include "third_party/skia/include/core/SkColor.h" diff --git a/chromium/cc/quads/draw_polygon.cc b/chromium/cc/quads/draw_polygon.cc index a300c92026a..86cb8731942 100644 --- a/chromium/cc/quads/draw_polygon.cc +++ b/chromium/cc/quads/draw_polygon.cc @@ -8,27 +8,26 @@ #include <vector> +#include "base/memory/ptr_util.h" #include "cc/output/bsp_compare_result.h" #include "cc/quads/draw_quad.h" namespace { // This threshold controls how "thick" a plane is. If a point's distance is -// <= |compare_threshold|, then it is considered on the plane. Only when this -// boundary is crossed do we consider doing splitting. -static const float compare_threshold = 0.1f; -// |split_threshold| is lower in this case because we want the points created -// during splitting to be well within the range of |compare_threshold| for -// comparison purposes. The splitting operation will produce intersection points -// that fit within a tighter distance to the splitting plane as a result of this -// value. By using a value >= |compare_threshold| we run the risk of creating -// points that SHOULD be intersecting the "thick plane", but actually fail to -// test positively for it because |split_threshold| allowed them to be outside -// this range. -// This is really supposd to be compare_threshold / 2.0f, but that would -// create another static initializer. +// <= |split_threshold|, then it is considered on the plane for the purpose of +// polygon splitting. static const float split_threshold = 0.05f; static const float normalized_threshold = 0.001f; + +void PointInterpolate(const gfx::Point3F& from, + const gfx::Point3F& to, + double delta, + gfx::Point3F* out) { + out->SetPoint(from.x() + (to.x() - from.x()) * delta, + from.y() + (to.y() - from.y()) * delta, + from.z() + (to.z() - from.z()) * delta); +} } // namespace namespace cc { @@ -45,6 +44,8 @@ DrawPolygon::DrawPolygon(const DrawQuad* original, points_.push_back(in_points[i]); } normal_ = normal; + DCHECK_LE((ConstructNormal(), (normal_ - normal).Length()), + normalized_threshold); } // This takes the original DrawQuad that this polygon should be based on, @@ -72,14 +73,15 @@ DrawPolygon::DrawPolygon(const DrawQuad* original_ref, for (int i = 0; i < num_vertices_in_clipped_quad; i++) { points_.push_back(points[i]); } + transform.TransformVector(&normal_); ConstructNormal(); } DrawPolygon::~DrawPolygon() { } -scoped_ptr<DrawPolygon> DrawPolygon::CreateCopy() { - scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon()); +std::unique_ptr<DrawPolygon> DrawPolygon::CreateCopy() { + std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon()); new_polygon->order_index_ = order_index_; new_polygon->original_ref_ = original_ref_; new_polygon->points_.reserve(points_.size()); @@ -98,18 +100,22 @@ scoped_ptr<DrawPolygon> DrawPolygon::CreateCopy() { // Averaging a few near diagonal cross products is pretty good in that case. // void DrawPolygon::ConstructNormal() { - normal_.set_x(0.0f); - normal_.set_y(0.0f); - normal_.set_z(0.0f); + gfx::Vector3dF new_normal(0.0f, 0.0f, 0.0f); int delta = points_.size() / 2; for (size_t i = 1; i + delta < points_.size(); i++) { - normal_ += + new_normal += CrossProduct(points_[i] - points_[0], points_[i + delta] - points_[0]); } - float normal_magnitude = normal_.Length(); + float normal_magnitude = new_normal.Length(); + // Here we constrain the new normal to point in the same sense as the old one. + // This allows us to handle winding-reversing transforms better. + if (gfx::DotProduct(normal_, new_normal) < 0.0) { + normal_magnitude *= -1.0; + } if (normal_magnitude != 0 && normal_magnitude != 1) { - normal_.Scale(1.0f / normal_magnitude); + new_normal.Scale(1.0f / normal_magnitude); } + normal_ = new_normal; } #if defined(OS_WIN) @@ -125,89 +131,6 @@ float DrawPolygon::SignedPointDistance(const gfx::Point3F& point) const { return gfx::DotProduct(point - points_[0], normal_); } -// Checks whether or not shape a lies on the front or back side of b, or -// whether they should be considered coplanar. If on the back side, we -// say A_BEFORE_B because it should be drawn in that order. -// Assumes that layers are split and there are no intersecting planes. -BspCompareResult DrawPolygon::SideCompare(const DrawPolygon& a, - const DrawPolygon& b) { - // Let's make sure that this is normalized. Without this SignedPointDistance - // will not be right, but putting the check in there will validate it - // redundantly for each point. - DCHECK_GE(normalized_threshold, std::abs(b.normal_.LengthSquared() - 1.0f)); - - int pos_count = 0; - int neg_count = 0; - for (size_t i = 0; i < a.points_.size(); i++) { - float sign = b.SignedPointDistance(a.points_[i]); - - if (sign < -compare_threshold) { - ++neg_count; - } else if (sign > compare_threshold) { - ++pos_count; - } - - if (pos_count && neg_count) { - return BSP_SPLIT; - } - } - - if (pos_count) { - return BSP_FRONT; - } - if (neg_count) { - return BSP_BACK; - } - - double dot = gfx::DotProduct(a.normal_, b.normal_); - if ((dot >= 0.0f && a.order_index_ >= b.order_index_) || - (dot <= 0.0f && a.order_index_ <= b.order_index_)) { - // The sign of the dot product of the normals along with document order - // determine which side it goes on, the vertices are ambiguous. - return BSP_COPLANAR_BACK; - } - - return BSP_COPLANAR_FRONT; -} - -static bool LineIntersectPlane(const gfx::Point3F& line_start, - const gfx::Point3F& line_end, - const gfx::Point3F& plane_origin, - const gfx::Vector3dF& plane_normal, - gfx::Point3F* intersection, - float distance_threshold) { - gfx::Vector3dF start_to_origin_vector = plane_origin - line_start; - gfx::Vector3dF end_to_origin_vector = plane_origin - line_end; - - double start_distance = gfx::DotProduct(start_to_origin_vector, plane_normal); - double end_distance = gfx::DotProduct(end_to_origin_vector, plane_normal); - - // The case where one vertex lies on the thick-plane and the other - // is outside of it. - if (std::abs(start_distance) <= distance_threshold && - std::abs(end_distance) > distance_threshold) { - intersection->SetPoint(line_start.x(), line_start.y(), line_start.z()); - return true; - } - - // This is the case where we clearly cross the thick-plane. - if ((start_distance > distance_threshold && - end_distance < -distance_threshold) || - (start_distance < -distance_threshold && - end_distance > distance_threshold)) { - gfx::Vector3dF v = line_end - line_start; - float total_distance = std::abs(start_distance) + std::abs(end_distance); - float lerp_factor = std::abs(start_distance) / total_distance; - - intersection->SetPoint(line_start.x() + (v.x() * lerp_factor), - line_start.y() + (v.y() * lerp_factor), - line_start.z() + (v.z() * lerp_factor)); - - return true; - } - return false; -} - // This function is separate from ApplyTransform because it is often unnecessary // to transform the normal with the rest of the polygon. // When drawing these polygons, it is necessary to move them back into layer @@ -243,6 +166,7 @@ void DrawPolygon::ApplyTransform(const gfx::Transform& transform) { // be transformed along with the vertices. void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) { ApplyTransform(transform); + transform.TransformVector(&normal_); ConstructNormal(); } @@ -256,84 +180,138 @@ void DrawPolygon::TransformToLayerSpace( normal_ = gfx::Vector3dF(0.0f, 0.0f, -1.0f); } -bool DrawPolygon::Split(const DrawPolygon& splitter, - scoped_ptr<DrawPolygon>* front, - scoped_ptr<DrawPolygon>* back) { - gfx::Point3F intersections[2]; - std::vector<gfx::Point3F> out_points[2]; - // vertex_before stores the index of the vertex before its matching - // intersection. - // i.e. vertex_before[0] stores the vertex we saw before we crossed the plane - // which resulted in the line/plane intersection giving us intersections[0]. - size_t vertex_before[2]; - size_t points_size = points_.size(); - size_t current_intersection = 0; - - size_t current_vertex = 0; - // We will only have two intersection points because we assume all polygons - // are convex. - while (current_intersection < 2) { - if (LineIntersectPlane(points_[(current_vertex % points_size)], - points_[(current_vertex + 1) % points_size], - splitter.points_[0], - splitter.normal_, - &intersections[current_intersection], - split_threshold)) { - vertex_before[current_intersection] = current_vertex % points_size; - current_intersection++; - // We found both intersection points so we're done already. - if (current_intersection == 2) { - break; - } - } - if (current_vertex++ > (points_size)) { - break; +// Split |polygon| based upon |this|, leaving the results in |front| and |back|. +// If |polygon| is not split by |this|, then move it to either |front| or |back| +// depending on its orientation relative to |this|. Sets |is_coplanar| to true +// if |polygon| is actually coplanar with |this| (in which case whether it is +// front facing or back facing is determined by the dot products of normals, and +// document order). +void DrawPolygon::SplitPolygon(std::unique_ptr<DrawPolygon> polygon, + std::unique_ptr<DrawPolygon>* front, + std::unique_ptr<DrawPolygon>* back, + bool* is_coplanar) const { + DCHECK_GE(normalized_threshold, std::abs(normal_.LengthSquared() - 1.0f)); + + const size_t num_points = polygon->points_.size(); + const auto next = [num_points](size_t i) { return (i + 1) % num_points; }; + const auto prev = [num_points](size_t i) { + return (i + num_points - 1) % num_points; + }; + + std::vector<float> vertex_distance; + size_t pos_count = 0; + size_t neg_count = 0; + + // Compute plane distances for each vertex of polygon. + vertex_distance.resize(num_points); + for (size_t i = 0; i < num_points; i++) { + vertex_distance[i] = SignedPointDistance(polygon->points_[i]); + if (vertex_distance[i] < -split_threshold) { + ++neg_count; + } else if (vertex_distance[i] > split_threshold) { + ++pos_count; + } else { + vertex_distance[i] = 0.0; } } - DCHECK_EQ(current_intersection, static_cast<size_t>(2)); - - // Since we found both the intersection points, we can begin building the - // vertex set for both our new polygons. - size_t start1 = (vertex_before[0] + 1) % points_size; - size_t start2 = (vertex_before[1] + 1) % points_size; - size_t points_remaining = points_size; - - // First polygon. - out_points[0].push_back(intersections[0]); - DCHECK_GE(vertex_before[1], start1); - for (size_t i = start1; i <= vertex_before[1]; i++) { - out_points[0].push_back(points_[i]); - --points_remaining; - } - out_points[0].push_back(intersections[1]); - - // Second polygon. - out_points[1].push_back(intersections[1]); - size_t index = start2; - for (size_t i = 0; i < points_remaining; i++) { - out_points[1].push_back(points_[index % points_size]); - ++index; + + // Handle non-splitting cases. + if (!pos_count && !neg_count) { + double dot = gfx::DotProduct(normal_, polygon->normal_); + if ((dot >= 0.0f && polygon->order_index_ >= order_index_) || + (dot <= 0.0f && polygon->order_index_ <= order_index_)) { + *back = std::move(polygon); + } else { + *front = std::move(polygon); + } + *is_coplanar = true; + return; } - out_points[1].push_back(intersections[0]); - - // Give both polygons the original splitting polygon's ID, so that they'll - // still be sorted properly in co-planar instances. - scoped_ptr<DrawPolygon> poly1( - new DrawPolygon(original_ref_, out_points[0], normal_, order_index_)); - scoped_ptr<DrawPolygon> poly2( - new DrawPolygon(original_ref_, out_points[1], normal_, order_index_)); - - DCHECK_GE(poly1->points().size(), 3u); - DCHECK_GE(poly2->points().size(), 3u); - - if (SideCompare(*poly1, splitter) == BSP_FRONT) { - *front = std::move(poly1); - *back = std::move(poly2); - } else { - *front = std::move(poly2); - *back = std::move(poly1); + + *is_coplanar = false; + if (!neg_count) { + *front = std::move(polygon); + return; + } else if (!pos_count) { + *back = std::move(polygon); + return; } - return true; + + // There should be at most two points that are considered to be on the thick + // plane. If this is not the case, then the polygon is not convex. + DCHECK_LE(num_points - pos_count - neg_count, 2u); + + // Handle splitting case. + size_t front_begin; + size_t back_begin; + size_t pre_front_begin; + size_t pre_back_begin; + + // Find the first vertex that is part of the front split polygon. + front_begin = std::find_if(vertex_distance.begin(), vertex_distance.end(), + [](float val) { return val > 0.0; }) - + vertex_distance.begin(); + while (vertex_distance[pre_front_begin = prev(front_begin)] > 0.0) + front_begin = pre_front_begin; + + // Find the first vertex that is part of the back split polygon. + back_begin = std::find_if(vertex_distance.begin(), vertex_distance.end(), + [](float val) { return val < 0.0; }) - + vertex_distance.begin(); + while (vertex_distance[pre_back_begin = prev(back_begin)] < 0.0) + back_begin = pre_back_begin; + + DCHECK(vertex_distance[front_begin] > 0.0); + DCHECK(vertex_distance[pre_front_begin] <= 0.0); + DCHECK(vertex_distance[back_begin] < 0.0); + DCHECK(vertex_distance[pre_back_begin] >= 0.0); + + gfx::Point3F pre_pos_intersection; + gfx::Point3F pre_neg_intersection; + + // Compute the intersection points. N.B.: If the "pre" vertex is on + // the thick plane, then the intersection will be at the same point, because + // we set vertex_distance to 0 in this case. + PointInterpolate( + polygon->points_[pre_front_begin], polygon->points_[front_begin], + -vertex_distance[pre_front_begin] / + gfx::DotProduct(normal_, polygon->points_[front_begin] - + polygon->points_[pre_front_begin]), + &pre_pos_intersection); + PointInterpolate( + polygon->points_[pre_back_begin], polygon->points_[back_begin], + -vertex_distance[pre_back_begin] / + gfx::DotProduct(normal_, polygon->points_[back_begin] - + polygon->points_[pre_back_begin]), + &pre_neg_intersection); + + // Build the front and back polygons. + std::vector<gfx::Point3F> out_points; + + out_points.push_back(pre_pos_intersection); + do { + out_points.push_back(polygon->points_[front_begin]); + front_begin = next(front_begin); + } while (vertex_distance[front_begin] > 0.0); + out_points.push_back(pre_neg_intersection); + *front = + base::MakeUnique<DrawPolygon>(polygon->original_ref_, out_points, + polygon->normal_, polygon->order_index_); + + out_points.clear(); + + out_points.push_back(pre_neg_intersection); + do { + out_points.push_back(polygon->points_[back_begin]); + back_begin = next(back_begin); + } while (vertex_distance[back_begin] < 0.0); + out_points.push_back(pre_pos_intersection); + *back = + base::MakeUnique<DrawPolygon>(polygon->original_ref_, out_points, + polygon->normal_, polygon->order_index_); + + DCHECK_GE((*front)->points().size(), 3u); + DCHECK_GE((*back)->points().size(), 3u); } // This algorithm takes the first vertex in the polygon and uses that as a diff --git a/chromium/cc/quads/draw_polygon.h b/chromium/cc/quads/draw_polygon.h index 668d9f2dc28..2dc642cde31 100644 --- a/chromium/cc/quads/draw_polygon.h +++ b/chromium/cc/quads/draw_polygon.h @@ -40,14 +40,11 @@ class CC_EXPORT DrawPolygon { // Split will only return true if it determines that we got back 2 // intersection points. Only when it returns true will front and back both be // valid new polygons that are on opposite sides of the splitting plane. - bool Split(const DrawPolygon& splitter, - scoped_ptr<DrawPolygon>* front, - scoped_ptr<DrawPolygon>* back); + void SplitPolygon(std::unique_ptr<DrawPolygon> polygon, + std::unique_ptr<DrawPolygon>* front, + std::unique_ptr<DrawPolygon>* back, + bool* is_coplanar) const; float SignedPointDistance(const gfx::Point3F& point) const; - // Checks polygon a against polygon b and returns which side it lies on, or - // whether it crosses (necessitating a split in the BSP tree). - static BspCompareResult SideCompare(const DrawPolygon& a, - const DrawPolygon& b); void ToQuads2D(std::vector<gfx::QuadF>* quads) const; void TransformToScreenSpace(const gfx::Transform& transform); void TransformToLayerSpace(const gfx::Transform& inverse_transform); @@ -57,7 +54,7 @@ class CC_EXPORT DrawPolygon { const DrawQuad* original_ref() const { return original_ref_; } int order_index() const { return order_index_; } bool is_split() const { return is_split_; } - scoped_ptr<DrawPolygon> CreateCopy(); + std::unique_ptr<DrawPolygon> CreateCopy(); void RecomputeNormalForTesting(); diff --git a/chromium/cc/quads/draw_polygon_unittest.cc b/chromium/cc/quads/draw_polygon_unittest.cc index eb6d1625986..40090ec7659 100644 --- a/chromium/cc/quads/draw_polygon_unittest.cc +++ b/chromium/cc/quads/draw_polygon_unittest.cc @@ -12,6 +12,7 @@ #include <limits> #include <vector> +#include "base/memory/ptr_util.h" #include "cc/output/bsp_compare_result.h" #include "cc/quads/draw_polygon.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,11 +31,20 @@ namespace { #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ DrawPolygon name(NULL, points_vector, normal, polygon_id) -#define CREATE_TEST_DRAW_POLYGON(name, points_vector, polygon_id) \ - DrawPolygon name(NULL, points_vector, gfx::Vector3dF(1, 2, 3), polygon_id); \ +#define CREATE_NEW_DRAW_POLYGON_PTR(name, points_vector, normal, polygon_id) \ + std::unique_ptr<DrawPolygon> name(base::MakeUnique<DrawPolygon>( \ + nullptr, points_vector, normal, polygon_id)) + +#define CREATE_TEST_DRAW_FORWARD_POLYGON(name, points_vector, id) \ + DrawPolygon name(NULL, points_vector, gfx::Vector3dF(0, 0, 1.0f), id); \ + name.RecomputeNormalForTesting() + +#define CREATE_TEST_DRAW_REVERSE_POLYGON(name, points_vector, id) \ + DrawPolygon name(NULL, points_vector, gfx::Vector3dF(0, 0, -1.0f), id); \ name.RecomputeNormalForTesting() -#define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \ +#define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \ + LOG(WARNING) << "a=" << a << " b= " << b << " diff=" << std::abs(a - b); \ EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon()); #define EXPECT_POINT_EQ(point_a, point_b) \ @@ -55,6 +65,36 @@ static void ValidatePoints(const DrawPolygon& polygon, } } +static void ValidatePointsWithinDeltaOf(const DrawPolygon& polygon, + const std::vector<gfx::Point3F>& points, + float delta) { + EXPECT_EQ(polygon.points().size(), points.size()); + for (size_t i = 0; i < points.size(); i++) { + EXPECT_LE((polygon.points()[i] - points[i]).Length(), delta); + } +} + +std::unique_ptr<DrawPolygon> ClonePolygon(const DrawPolygon& polygon) { + return base::MakeUnique<DrawPolygon>(polygon.original_ref(), polygon.points(), + polygon.normal(), polygon.order_index()); +} + +// Classifies polygon a with respect to b +BspCompareResult SideCompare(const DrawPolygon& a, const DrawPolygon& b) { + std::unique_ptr<DrawPolygon> front; + std::unique_ptr<DrawPolygon> back; + bool is_coplanar; + b.SplitPolygon(ClonePolygon(a), &front, &back, &is_coplanar); + if (is_coplanar) { + return (front != nullptr) ? BSP_COPLANAR_FRONT : BSP_COPLANAR_BACK; + } + if (front == nullptr) + return BSP_BACK; + if (back == nullptr) + return BSP_FRONT; + return BSP_SPLIT; +} + // A simple square in a plane. TEST(DrawPolygonConstructionTest, NormalNormal) { gfx::Transform Identity; @@ -70,21 +110,10 @@ TEST(DrawPolygonConstructionTest, TestNormal) { vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); - CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); + CREATE_TEST_DRAW_FORWARD_POLYGON(polygon, vertices, 1); EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); } -TEST(DrawPolygonConstructionTest, InverseNormal) { - std::vector<gfx::Point3F> vertices; - vertices.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); - vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); - vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); - vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); - - CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); - EXPECT_NORMAL(polygon, 0.0f, 0.0f, -1.0f); -} - TEST(DrawPolygonConstructionTest, ClippedNormal) { std::vector<gfx::Point3F> vertices; vertices.push_back(gfx::Point3F(0.1f, 10.0f, 0.0f)); @@ -94,7 +123,7 @@ TEST(DrawPolygonConstructionTest, ClippedNormal) { vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); - CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); + CREATE_TEST_DRAW_FORWARD_POLYGON(polygon, vertices, 1); EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); } @@ -104,7 +133,7 @@ TEST(DrawPolygonConstructionTest, SlimTriangleNormal) { vertices.push_back(gfx::Point3F(5000.0f, 0.0f, 0.0f)); vertices.push_back(gfx::Point3F(10000.0f, 1.0f, 0.0f)); - CREATE_TEST_DRAW_POLYGON(polygon, vertices, 2); + CREATE_TEST_DRAW_FORWARD_POLYGON(polygon, vertices, 2); EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); } @@ -117,36 +146,83 @@ TEST(DrawPolygonConstructionTest, ManyVertexNormal) { vertices_d.push_back(gfx::Point3F(cos(i * M_PI / 50) + 99.0f, sin(i * M_PI / 50) + 99.0f, 100.0f)); } - CREATE_TEST_DRAW_POLYGON(polygon_c, vertices_c, 3); + CREATE_TEST_DRAW_FORWARD_POLYGON(polygon_c, vertices_c, 3); EXPECT_NORMAL(polygon_c, 0.0f, 0.0f, 1.0f); - CREATE_TEST_DRAW_POLYGON(polygon_d, vertices_d, 4); + CREATE_TEST_DRAW_FORWARD_POLYGON(polygon_d, vertices_d, 4); EXPECT_NORMAL(polygon_c, 0.0f, 0.0f, 1.0f); } // A simple rect being transformed. -TEST(DrawPolygonConstructionTest, DizzyNormal) { +TEST(DrawPolygonConstructionTest, SimpleNormal) { gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); gfx::Transform transform_i(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); DrawPolygon polygon_i(NULL, src, transform_i, 1); EXPECT_NORMAL(polygon_i, 0.0f, 0.0f, 1.0f); +} - gfx::Transform tranform_a(0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - DrawPolygon polygon_a(NULL, src, tranform_a, 2); - EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f); +TEST(DrawPolygonConstructionTest, DISABLED_NormalInvertXY) { + gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); + + gfx::Transform transform(0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + DrawPolygon polygon_a(NULL, src, transform, 2); + + EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, 1.0f); +} + +TEST(DrawPolygonConstructionTest, DISABLED_NormalInvertXZ) { + gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); + + gfx::Transform transform(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1); + DrawPolygon polygon_b(NULL, src, transform, 3); + + EXPECT_NORMAL(polygon_b, 1.0f, 0.0f, 0.0f); +} + +TEST(DrawPolygonConstructionTest, DISABLED_NormalInvertYZ) { + gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); + + gfx::Transform transform(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1); + DrawPolygon polygon_c(NULL, src, transform, 4); + + EXPECT_NORMAL(polygon_c, 0.0f, 1.0f, 0.0f); +} + +TEST(DrawPolygonConstructionTest, NormalRotate90) { + gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); - gfx::Transform tranform_b(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1); - DrawPolygon polygon_b(NULL, src, tranform_b, 3); - EXPECT_NORMAL(polygon_b, -1.0f, 0.0f, 0.0f); + gfx::Transform transform(0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1); + DrawPolygon polygon_b(NULL, src, transform, 3); - gfx::Transform tranform_c(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1); - DrawPolygon polygon_c(NULL, src, tranform_c, 4); - EXPECT_NORMAL(polygon_c, 0.0f, -1.0f, 0.0f); + EXPECT_NORMAL(polygon_b, 0.0f, 0.0f, 1.0f); +} + +TEST(DrawPolygonConstructionTest, InvertXNormal) { + gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); + + gfx::Transform transform(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + DrawPolygon polygon_d(NULL, src, transform, 5); + + EXPECT_NORMAL(polygon_d, 0.0f, 0.0f, 1.0f); +} + +TEST(DrawPolygonConstructionTest, InvertYNormal) { + gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); + + gfx::Transform transform(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + DrawPolygon polygon_d(NULL, src, transform, 5); + + EXPECT_NORMAL(polygon_d, 0.0f, 0.0f, 1.0f); +} + +TEST(DrawPolygonConstructionTest, InvertZNormal) { + gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); + + gfx::Transform transform(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1); + DrawPolygon polygon_d(NULL, src, transform, 5); - gfx::Transform tranform_d(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - DrawPolygon polygon_d(NULL, src, tranform_d, 5); EXPECT_NORMAL(polygon_d, 0.0f, 0.0f, -1.0f); } @@ -168,7 +244,7 @@ TEST(DrawPolygonSplitTest, NearlyTouchingOrder) { CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, normal, 0); CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, normal, 1); - EXPECT_EQ(BSP_BACK, DrawPolygon::SideCompare(polygon_b, polygon_a)); + EXPECT_EQ(BSP_BACK, SideCompare(polygon_b, polygon_a)); } // Two quads are definitely not touching and so no split should occur. @@ -194,7 +270,7 @@ TEST(DrawPolygonSplitTest, NotClearlyInFront) { CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, normal_a, 0); CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, normal_b, 1); - EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(polygon_b, polygon_a)); + EXPECT_EQ(BSP_FRONT, SideCompare(polygon_b, polygon_a)); } // Two quads are definitely not touching and so no split should occur. @@ -206,19 +282,20 @@ TEST(DrawPolygonSplitTest, NotTouchingNoSplit) { vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); std::vector<gfx::Point3F> vertices_b; vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); + vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 15.0f)); vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f)); - vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f)); - vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); + vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f)); - CREATE_NEW_DRAW_POLYGON( - polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); - CREATE_NEW_DRAW_POLYGON( - polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); + CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, + gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); + CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, + gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); - EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(polygon_b, polygon_a)); + EXPECT_EQ(BSP_FRONT, SideCompare(polygon_b, polygon_a)); } -// One quad is resting against another, but doesn't cross its plane so no split +// One quad is resting against another, but doesn't cross its plane so no +// split // should occur. TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) { std::vector<gfx::Point3F> vertices_a; @@ -228,16 +305,16 @@ TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) { vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); std::vector<gfx::Point3F> vertices_b; vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); + vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -10.0f)); vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f)); - vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f)); - vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); + vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); - CREATE_NEW_DRAW_POLYGON( - polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); - CREATE_NEW_DRAW_POLYGON( - polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); + CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, + gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); + CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, + gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); - EXPECT_EQ(BSP_BACK, DrawPolygon::SideCompare(polygon_b, polygon_a)); + EXPECT_EQ(BSP_BACK, SideCompare(polygon_b, polygon_a)); } // One quad intersects another and becomes two pieces. @@ -253,18 +330,20 @@ TEST(DrawPolygonSplitTest, BasicSplit) { vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f)); vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); - CREATE_NEW_DRAW_POLYGON( - polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); - CREATE_NEW_DRAW_POLYGON( - polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); + CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a, + gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); + CREATE_NEW_DRAW_POLYGON_PTR(polygon_b, vertices_b, + gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); - EXPECT_EQ(BSP_SPLIT, DrawPolygon::SideCompare(polygon_b, polygon_a)); + std::unique_ptr<DrawPolygon> front_polygon; + std::unique_ptr<DrawPolygon> back_polygon; + bool is_coplanar; - scoped_ptr<DrawPolygon> front_polygon; - scoped_ptr<DrawPolygon> back_polygon; - polygon_b.Split(polygon_a, &front_polygon, &back_polygon); - EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(*front_polygon, polygon_a)); - EXPECT_EQ(BSP_BACK, DrawPolygon::SideCompare(*back_polygon, polygon_a)); + polygon_a->SplitPolygon(std::move(polygon_b), &front_polygon, &back_polygon, + &is_coplanar); + EXPECT_FALSE(is_coplanar); + EXPECT_TRUE(front_polygon != nullptr); + EXPECT_TRUE(back_polygon != nullptr); std::vector<gfx::Point3F> test_points_a; test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); @@ -297,21 +376,20 @@ TEST(DrawPolygonSplitTest, AngledSplit) { vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f)); vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f)); - CREATE_NEW_DRAW_POLYGON( - polygon_a, vertices_a, gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0); - CREATE_NEW_DRAW_POLYGON( - polygon_b, vertices_b, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 1); - - EXPECT_EQ(BSP_SPLIT, DrawPolygon::SideCompare(polygon_a, polygon_b)); + CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a, + gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0); + CREATE_NEW_DRAW_POLYGON_PTR(polygon_b, vertices_b, + gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 1); - scoped_ptr<DrawPolygon> front_polygon; - scoped_ptr<DrawPolygon> back_polygon; - polygon_a.Split(polygon_b, &front_polygon, &back_polygon); - EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(*front_polygon, polygon_b)); - EXPECT_EQ(BSP_BACK, DrawPolygon::SideCompare(*back_polygon, polygon_b)); + std::unique_ptr<DrawPolygon> front_polygon; + std::unique_ptr<DrawPolygon> back_polygon; + bool is_coplanar; - EXPECT_EQ(3u, front_polygon->points().size()); - EXPECT_EQ(5u, back_polygon->points().size()); + polygon_b->SplitPolygon(std::move(polygon_a), &front_polygon, &back_polygon, + &is_coplanar); + EXPECT_FALSE(is_coplanar); + EXPECT_TRUE(front_polygon != nullptr); + EXPECT_TRUE(back_polygon != nullptr); std::vector<gfx::Point3F> test_points_a; test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); @@ -324,8 +402,8 @@ TEST(DrawPolygonSplitTest, AngledSplit) { test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); - ValidatePoints(*(front_polygon.get()), test_points_a); - ValidatePoints(*(back_polygon.get()), test_points_b); + ValidatePointsWithinDeltaOf(*(front_polygon.get()), test_points_a, 1e-6f); + ValidatePointsWithinDeltaOf(*(back_polygon.get()), test_points_b, 1e-6f); } TEST(DrawPolygonTransformTest, TransformNormal) { @@ -333,13 +411,8 @@ TEST(DrawPolygonTransformTest, TransformNormal) { vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f)); vertices_a.push_back(gfx::Point3F(-1.0f, 0.0f, -1.0f)); vertices_a.push_back(gfx::Point3F(0.0f, 1.0f, 0.0f)); - CREATE_NEW_DRAW_POLYGON( - polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0); - // Check we believe your little white lie. - EXPECT_NORMAL(polygon_a, 0.707107f, 0.0f, -0.707107f); - - polygon_a.RecomputeNormalForTesting(); - // Check that we recompute it more accurately. + CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, + gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2), 0); EXPECT_NORMAL(polygon_a, sqrt(2) / 2, 0.0f, -sqrt(2) / 2); gfx::Transform transform; diff --git a/chromium/cc/quads/draw_quad.cc b/chromium/cc/quads/draw_quad.cc index e5d0e142939..d5edffeb192 100644 --- a/chromium/cc/quads/draw_quad.cc +++ b/chromium/cc/quads/draw_quad.cc @@ -12,7 +12,6 @@ #include "cc/base/math_util.h" #include "cc/debug/traced_value.h" #include "cc/quads/debug_border_draw_quad.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/picture_draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" #include "cc/quads/solid_color_draw_quad.h" diff --git a/chromium/cc/quads/draw_quad.h b/chromium/cc/quads/draw_quad.h index 4b6ae59b363..854980d2f0a 100644 --- a/chromium/cc/quads/draw_quad.h +++ b/chromium/cc/quads/draw_quad.h @@ -38,7 +38,6 @@ class CC_EXPORT DrawQuad { enum Material { INVALID, DEBUG_BORDER, - IO_SURFACE_CONTENT, PICTURE_CONTENT, RENDER_PASS, SOLID_COLOR, diff --git a/chromium/cc/quads/draw_quad_perftest.cc b/chromium/cc/quads/draw_quad_perftest.cc index 08ce6d07b29..99b9c970fe6 100644 --- a/chromium/cc/quads/draw_quad_perftest.cc +++ b/chromium/cc/quads/draw_quad_perftest.cc @@ -73,7 +73,7 @@ class DrawQuadPerfTest : public testing::Test { 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); + nearest_neighbor, false); quads->push_back(quad); } } @@ -98,7 +98,7 @@ class DrawQuadPerfTest : public testing::Test { } private: - scoped_ptr<RenderPass> render_pass_; + std::unique_ptr<RenderPass> render_pass_; SharedQuadState* shared_state_; LapTimer timer_; }; diff --git a/chromium/cc/quads/draw_quad_unittest.cc b/chromium/cc/quads/draw_quad_unittest.cc index 1059470cbd0..b4af80b8e12 100644 --- a/chromium/cc/quads/draw_quad_unittest.cc +++ b/chromium/cc/quads/draw_quad_unittest.cc @@ -13,7 +13,6 @@ #include "cc/base/math_util.h" #include "cc/output/filter_operations.h" #include "cc/quads/debug_border_draw_quad.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/largest_draw_quad.h" #include "cc/quads/picture_draw_quad.h" #include "cc/quads/render_pass.h" @@ -43,11 +42,11 @@ TEST(DrawQuadTest, CopySharedQuadState) { SkXfermode::Mode blend_mode = SkXfermode::kMultiply_Mode; int sorting_context_id = 65536; - scoped_ptr<SharedQuadState> state(new SharedQuadState); + std::unique_ptr<SharedQuadState> state(new SharedQuadState); 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); + std::unique_ptr<SharedQuadState> copy(new SharedQuadState); copy->CopyFrom(state.get()); EXPECT_EQ(quad_transform, copy->quad_to_target_transform); EXPECT_EQ(visible_layer_rect, copy->visible_quad_layer_rect); @@ -85,7 +84,7 @@ void CompareDrawQuad(DrawQuad* quad, } #define CREATE_SHARED_STATE() \ - scoped_ptr<RenderPass> render_pass = RenderPass::Create(); \ + std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); \ SharedQuadState* shared_state(CreateSharedQuadState(render_pass.get())); \ SharedQuadState* copy_shared_state = \ render_pass->CreateAndAppendSharedQuadState(); \ @@ -405,30 +404,6 @@ TEST(DrawQuadTest, CopyDebugBorderDrawQuad) { EXPECT_EQ(width, copy_quad->width); } -TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) { - gfx::Rect opaque_rect(33, 47, 10, 12); - gfx::Rect visible_rect(40, 50, 30, 20); - gfx::Size size(58, 95); - ResourceId resource_id = 72; - IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED; - CREATE_SHARED_STATE(); - - CREATE_QUAD_5_NEW(IOSurfaceDrawQuad, opaque_rect, visible_rect, size, - resource_id, orientation); - EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material); - 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(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(orientation, copy_quad->orientation); -} - TEST(DrawQuadTest, CopyRenderPassDrawQuad) { gfx::Rect visible_rect(40, 50, 30, 20); RenderPassId render_pass_id(22, 64); @@ -557,19 +532,13 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f }; bool y_flipped = true; bool nearest_neighbor = true; + bool secure_output_only = true; CREATE_SHARED_STATE(); - CREATE_QUAD_10_NEW(TextureDrawQuad, - opaque_rect, - visible_rect, - resource_id, - premultiplied_alpha, - uv_top_left, - uv_bottom_right, - SK_ColorTRANSPARENT, - vertex_opacity, - y_flipped, - nearest_neighbor); + CREATE_QUAD_11_NEW(TextureDrawQuad, opaque_rect, visible_rect, resource_id, + premultiplied_alpha, uv_top_left, uv_bottom_right, + SK_ColorTRANSPARENT, vertex_opacity, y_flipped, + nearest_neighbor, secure_output_only); EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material); EXPECT_EQ(visible_rect, copy_quad->visible_rect); EXPECT_EQ(opaque_rect, copy_quad->opaque_rect); @@ -580,11 +549,12 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4); EXPECT_EQ(y_flipped, copy_quad->y_flipped); EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor); + EXPECT_EQ(secure_output_only, copy_quad->secure_output_only); - CREATE_QUAD_9_ALL(TextureDrawQuad, resource_id, resource_size_in_pixels, - 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, + premultiplied_alpha, uv_top_left, uv_bottom_right, + SK_ColorTRANSPARENT, vertex_opacity, y_flipped, + nearest_neighbor, secure_output_only); EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material); EXPECT_EQ(resource_id, copy_quad->resource_id()); EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels()); @@ -594,6 +564,7 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4); EXPECT_EQ(y_flipped, copy_quad->y_flipped); EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor); + EXPECT_EQ(secure_output_only, copy_quad->secure_output_only); } TEST(DrawQuadTest, CopyTileDrawQuad) { @@ -757,21 +728,6 @@ TEST_F(DrawQuadIteratorTest, DebugBorderDrawQuad) { EXPECT_EQ(0, IterateAndCount(quad_new)); } -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); - ResourceId resource_id = 72; - IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED; - - CREATE_SHARED_STATE(); - CREATE_QUAD_5_NEW(IOSurfaceDrawQuad, opaque_rect, visible_rect, size, - resource_id, orientation); - 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()); -} - TEST_F(DrawQuadIteratorTest, RenderPassDrawQuad) { gfx::Rect visible_rect(40, 50, 30, 20); RenderPassId render_pass_id(22, 64); @@ -857,19 +813,13 @@ TEST_F(DrawQuadIteratorTest, TextureDrawQuad) { const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f }; bool y_flipped = true; bool nearest_neighbor = true; + bool secure_output_only = true; CREATE_SHARED_STATE(); - CREATE_QUAD_10_NEW(TextureDrawQuad, - opaque_rect, - visible_rect, - resource_id, - premultiplied_alpha, - uv_top_left, - uv_bottom_right, - SK_ColorTRANSPARENT, - vertex_opacity, - y_flipped, - nearest_neighbor); + CREATE_QUAD_11_NEW(TextureDrawQuad, opaque_rect, visible_rect, resource_id, + premultiplied_alpha, uv_top_left, uv_bottom_right, + SK_ColorTRANSPARENT, vertex_opacity, y_flipped, + nearest_neighbor, secure_output_only); EXPECT_EQ(resource_id, quad_new->resource_id()); EXPECT_EQ(1, IterateAndCount(quad_new)); EXPECT_EQ(resource_id + 1, quad_new->resource_id()); @@ -958,9 +908,6 @@ TEST(DrawQuadTest, LargestQuadType) { case DrawQuad::DEBUG_BORDER: largest = std::max(largest, sizeof(DebugBorderDrawQuad)); break; - case DrawQuad::IO_SURFACE_CONTENT: - largest = std::max(largest, sizeof(IOSurfaceDrawQuad)); - break; case DrawQuad::PICTURE_CONTENT: largest = std::max(largest, sizeof(PictureDrawQuad)); break; @@ -1002,9 +949,6 @@ TEST(DrawQuadTest, LargestQuadType) { case DrawQuad::DEBUG_BORDER: LOG(ERROR) << "DebugBorderDrawQuad " << sizeof(DebugBorderDrawQuad); break; - case DrawQuad::IO_SURFACE_CONTENT: - LOG(ERROR) << "IOSurfaceDrawQuad " << sizeof(IOSurfaceDrawQuad); - break; case DrawQuad::PICTURE_CONTENT: LOG(ERROR) << "PictureDrawQuad " << sizeof(PictureDrawQuad); break; diff --git a/chromium/cc/quads/io_surface_draw_quad.cc b/chromium/cc/quads/io_surface_draw_quad.cc deleted file mode 100644 index 1ed0021d780..00000000000 --- a/chromium/cc/quads/io_surface_draw_quad.cc +++ /dev/null @@ -1,73 +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/quads/io_surface_draw_quad.h" - -#include "base/logging.h" -#include "base/trace_event/trace_event_argument.h" -#include "base/values.h" -#include "cc/base/math_util.h" - -namespace cc { - -IOSurfaceDrawQuad::IOSurfaceDrawQuad() : orientation(FLIPPED) {} - -void IOSurfaceDrawQuad::SetNew(const SharedQuadState* shared_quad_state, - const gfx::Rect& rect, - const gfx::Rect& opaque_rect, - const gfx::Rect& visible_rect, - const gfx::Size& io_surface_size, - unsigned io_surface_resource_id, - Orientation orientation) { - bool needs_blending = false; - DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect, - opaque_rect, visible_rect, needs_blending); - this->io_surface_size = io_surface_size; - resources.ids[kIOSurfaceResourceIdIndex] = io_surface_resource_id; - resources.count = 1; - this->orientation = orientation; -} - -void IOSurfaceDrawQuad::SetAll(const SharedQuadState* shared_quad_state, - const gfx::Rect& rect, - const gfx::Rect& opaque_rect, - const gfx::Rect& visible_rect, - bool needs_blending, - const gfx::Size& io_surface_size, - unsigned io_surface_resource_id, - Orientation orientation) { - DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect, - opaque_rect, visible_rect, needs_blending); - this->io_surface_size = io_surface_size; - resources.ids[kIOSurfaceResourceIdIndex] = io_surface_resource_id; - resources.count = 1; - this->orientation = orientation; -} - -const IOSurfaceDrawQuad* IOSurfaceDrawQuad::MaterialCast( - const DrawQuad* quad) { - DCHECK(quad->material == DrawQuad::IO_SURFACE_CONTENT); - return static_cast<const IOSurfaceDrawQuad*>(quad); -} - -void IOSurfaceDrawQuad::ExtendValue( - base::trace_event::TracedValue* value) const { - MathUtil::AddToTracedValue("io_surface_size", io_surface_size, value); - - value->SetInteger("io_surface_resource_id", - resources.ids[kIOSurfaceResourceIdIndex]); - const char* orientation_string = NULL; - switch (orientation) { - case FLIPPED: - orientation_string = "flipped"; - break; - case UNFLIPPED: - orientation_string = "unflipped"; - break; - } - - value->SetString("orientation", orientation_string); -} - -} // namespace cc diff --git a/chromium/cc/quads/io_surface_draw_quad.h b/chromium/cc/quads/io_surface_draw_quad.h deleted file mode 100644 index 9deb8fa0954..00000000000 --- a/chromium/cc/quads/io_surface_draw_quad.h +++ /dev/null @@ -1,61 +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_QUADS_IO_SURFACE_DRAW_QUAD_H_ -#define CC_QUADS_IO_SURFACE_DRAW_QUAD_H_ - -#include <stddef.h> - -#include "base/memory/scoped_ptr.h" -#include "cc/base/cc_export.h" -#include "cc/quads/draw_quad.h" -#include "ui/gfx/geometry/size.h" - -namespace cc { - -class CC_EXPORT IOSurfaceDrawQuad : public DrawQuad { - public: - enum Orientation { - FLIPPED, - UNFLIPPED, - ORIENTATION_LAST = UNFLIPPED - }; - - IOSurfaceDrawQuad(); - - void SetNew(const SharedQuadState* shared_quad_state, - const gfx::Rect& rect, - const gfx::Rect& opaque_rect, - const gfx::Rect& visible_rect, - const gfx::Size& io_surface_size, - unsigned io_surface_resource_id, - Orientation orientation); - - void SetAll(const SharedQuadState* shared_quad_state, - const gfx::Rect& rect, - const gfx::Rect& opaque_rect, - const gfx::Rect& visible_rect, - bool needs_blending, - const gfx::Size& io_surface_size, - unsigned io_surface_resource_id, - Orientation orientation); - - gfx::Size io_surface_size; - Orientation orientation; - - 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; -}; - -} // namespace cc - -#endif // CC_QUADS_IO_SURFACE_DRAW_QUAD_H_ diff --git a/chromium/cc/quads/largest_draw_quad.cc b/chromium/cc/quads/largest_draw_quad.cc index cd5dd387d72..e499b39ceda 100644 --- a/chromium/cc/quads/largest_draw_quad.cc +++ b/chromium/cc/quads/largest_draw_quad.cc @@ -9,7 +9,6 @@ #include <algorithm> #include "cc/quads/debug_border_draw_quad.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/picture_draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" #include "cc/quads/solid_color_draw_quad.h" @@ -37,9 +36,6 @@ size_t LargestDrawQuadSize() { static_assert(sizeof(DebugBorderDrawQuad) <= kLargestDrawQuadSize, "Largest Draw Quad size needs update. DebugBorderDrawQuad is " "currently largest."); - static_assert(sizeof(IOSurfaceDrawQuad) <= kLargestDrawQuadSize, - "Largest Draw Quad size needs update. IOSurfaceDrawQuad is " - "currently largest."); static_assert(sizeof(PictureDrawQuad) <= kLargestDrawQuadSize, "Largest Draw Quad size needs update. PictureDrawQuad is " "currently largest."); diff --git a/chromium/cc/quads/picture_draw_quad.h b/chromium/cc/quads/picture_draw_quad.h index 27abd611eb1..b9286b73729 100644 --- a/chromium/cc/quads/picture_draw_quad.h +++ b/chromium/cc/quads/picture_draw_quad.h @@ -5,8 +5,9 @@ #ifndef CC_QUADS_PICTURE_DRAW_QUAD_H_ #define CC_QUADS_PICTURE_DRAW_QUAD_H_ +#include <memory> + #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/playback/raster_source.h" #include "cc/quads/content_draw_quad_base.h" diff --git a/chromium/cc/quads/render_pass.cc b/chromium/cc/quads/render_pass.cc index 15ed6a4fab5..0a868e3e057 100644 --- a/chromium/cc/quads/render_pass.cc +++ b/chromium/cc/quads/render_pass.cc @@ -8,6 +8,7 @@ #include <algorithm> +#include "base/memory/ptr_util.h" #include "base/numerics/safe_conversions.h" #include "base/trace_event/trace_event_argument.h" #include "base/values.h" @@ -16,7 +17,6 @@ #include "cc/output/copy_output_request.h" #include "cc/quads/debug_border_draw_quad.h" #include "cc/quads/draw_quad.h" -#include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/largest_draw_quad.h" #include "cc/quads/picture_draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" @@ -39,17 +39,18 @@ QuadList::QuadList(size_t default_size_to_reserve) : ListContainer<DrawQuad>(LargestDrawQuadSize(), default_size_to_reserve) { } -scoped_ptr<RenderPass> RenderPass::Create() { - return make_scoped_ptr(new RenderPass()); +std::unique_ptr<RenderPass> RenderPass::Create() { + return base::WrapUnique(new RenderPass()); } -scoped_ptr<RenderPass> RenderPass::Create(size_t num_layers) { - return make_scoped_ptr(new RenderPass(num_layers)); +std::unique_ptr<RenderPass> RenderPass::Create(size_t num_layers) { + return base::WrapUnique(new RenderPass(num_layers)); } -scoped_ptr<RenderPass> RenderPass::Create(size_t shared_quad_state_list_size, - size_t quad_list_size) { - return make_scoped_ptr( +std::unique_ptr<RenderPass> RenderPass::Create( + size_t shared_quad_state_list_size, + size_t quad_list_size) { + return base::WrapUnique( new RenderPass(shared_quad_state_list_size, quad_list_size)); } @@ -82,8 +83,8 @@ RenderPass::~RenderPass() { "cc::RenderPass", id.AsTracingId()); } -scoped_ptr<RenderPass> RenderPass::Copy(RenderPassId new_id) const { - scoped_ptr<RenderPass> copy_pass( +std::unique_ptr<RenderPass> RenderPass::Copy(RenderPassId new_id) const { + std::unique_ptr<RenderPass> copy_pass( Create(shared_quad_state_list.size(), quad_list.size())); copy_pass->SetAll(new_id, output_rect, @@ -94,14 +95,14 @@ scoped_ptr<RenderPass> RenderPass::Copy(RenderPassId new_id) const { } // static -void RenderPass::CopyAll(const std::vector<scoped_ptr<RenderPass>>& in, - std::vector<scoped_ptr<RenderPass>>* out) { +void RenderPass::CopyAll(const std::vector<std::unique_ptr<RenderPass>>& in, + std::vector<std::unique_ptr<RenderPass>>* out) { for (const auto& source : in) { // Since we can't copy these, it's wrong to use CopyAll in a situation where // you may have copy_requests present. DCHECK_EQ(source->copy_requests.size(), 0u); - scoped_ptr<RenderPass> copy_pass(Create( + std::unique_ptr<RenderPass> copy_pass(Create( source->shared_quad_state_list.size(), source->quad_list.size())); copy_pass->SetAll(source->id, source->output_rect, @@ -228,9 +229,6 @@ DrawQuad* RenderPass::CopyFromAndAppendDrawQuad( case DrawQuad::DEBUG_BORDER: CopyFromAndAppendTypedDrawQuad<DebugBorderDrawQuad>(quad); break; - case DrawQuad::IO_SURFACE_CONTENT: - CopyFromAndAppendTypedDrawQuad<IOSurfaceDrawQuad>(quad); - break; case DrawQuad::PICTURE_CONTENT: CopyFromAndAppendTypedDrawQuad<PictureDrawQuad>(quad); break; diff --git a/chromium/cc/quads/render_pass.h b/chromium/cc/quads/render_pass.h index 3f7775d97cf..9c6bb598735 100644 --- a/chromium/cc/quads/render_pass.h +++ b/chromium/cc/quads/render_pass.h @@ -18,7 +18,6 @@ #include "cc/base/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" #include "ui/gfx/transform.h" @@ -57,18 +56,18 @@ class CC_EXPORT RenderPass { public: ~RenderPass(); - static scoped_ptr<RenderPass> Create(); - static scoped_ptr<RenderPass> Create(size_t num_layers); - static scoped_ptr<RenderPass> Create(size_t shared_quad_state_list_size, - size_t quad_list_size); + static std::unique_ptr<RenderPass> Create(); + static std::unique_ptr<RenderPass> Create(size_t num_layers); + static std::unique_ptr<RenderPass> Create(size_t shared_quad_state_list_size, + size_t quad_list_size); // A shallow copy of the render pass, which does not include its quads or copy // requests. - scoped_ptr<RenderPass> Copy(RenderPassId new_id) const; + std::unique_ptr<RenderPass> Copy(RenderPassId new_id) const; // A deep copy of the render passes in the list including the quads. - static void CopyAll(const std::vector<scoped_ptr<RenderPass>>& in, - std::vector<scoped_ptr<RenderPass>>* out); + static void CopyAll(const std::vector<std::unique_ptr<RenderPass>>& in, + std::vector<std::unique_ptr<RenderPass>>* out); void SetNew(RenderPassId id, const gfx::Rect& output_rect, @@ -115,7 +114,7 @@ class CC_EXPORT RenderPass { // contents as a bitmap, and give a copy of the bitmap to each callback in // this list. This property should not be serialized between compositors, as // it only makes sense in the root compositor. - std::vector<scoped_ptr<CopyOutputRequest>> copy_requests; + std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests; QuadList quad_list; SharedQuadStateList shared_quad_state_list; @@ -134,7 +133,7 @@ class CC_EXPORT RenderPass { DISALLOW_COPY_AND_ASSIGN(RenderPass); }; -using RenderPassList = std::vector<scoped_ptr<RenderPass>>; +using RenderPassList = std::vector<std::unique_ptr<RenderPass>>; using RenderPassIdHashMap = std::unordered_map<RenderPassId, RenderPass*, RenderPassIdHash>; diff --git a/chromium/cc/quads/render_pass_draw_quad.h b/chromium/cc/quads/render_pass_draw_quad.h index 2591ac87fa0..94461a1a328 100644 --- a/chromium/cc/quads/render_pass_draw_quad.h +++ b/chromium/cc/quads/render_pass_draw_quad.h @@ -7,7 +7,8 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/output/filter_operations.h" #include "cc/quads/draw_quad.h" diff --git a/chromium/cc/quads/render_pass_unittest.cc b/chromium/cc/quads/render_pass_unittest.cc index b833a0ce1b9..0a4e7221880 100644 --- a/chromium/cc/quads/render_pass_unittest.cc +++ b/chromium/cc/quads/render_pass_unittest.cc @@ -6,6 +6,7 @@ #include <stddef.h> +#include "base/memory/ptr_util.h" #include "cc/base/math_util.h" #include "cc/output/copy_output_request.h" #include "cc/quads/render_pass_draw_quad.h" @@ -28,7 +29,7 @@ struct RenderPassSize { gfx::Rect output_rect; gfx::Rect damage_rect; bool has_transparent_background; - std::vector<scoped_ptr<CopyOutputRequest>> copy_callbacks; + std::vector<std::unique_ptr<CopyOutputRequest>> copy_callbacks; }; static void CompareRenderPassLists(const RenderPassList& expected_list, @@ -69,7 +70,7 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) { gfx::Rect damage_rect(56, 123, 19, 43); bool has_transparent_background = true; - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetAll(id, output_rect, damage_rect, @@ -95,7 +96,7 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) { RenderPassId new_id(63, 4); - scoped_ptr<RenderPass> copy = pass->Copy(new_id); + std::unique_ptr<RenderPass> copy = pass->Copy(new_id); EXPECT_EQ(new_id, copy->id); EXPECT_EQ(pass->output_rect, copy->output_rect); EXPECT_EQ(pass->transform_to_root_target, copy->transform_to_root_target); @@ -120,7 +121,7 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) { gfx::Rect damage_rect(56, 123, 19, 43); bool has_transparent_background = true; - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetAll(id, output_rect, damage_rect, @@ -181,7 +182,7 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) { gfx::Rect contrib_damage_rect(11, 16, 10, 15); bool contrib_has_transparent_background = true; - scoped_ptr<RenderPass> contrib = RenderPass::Create(); + std::unique_ptr<RenderPass> contrib = RenderPass::Create(); contrib->SetAll(contrib_id, contrib_output_rect, contrib_damage_rect, @@ -206,8 +207,8 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) { false); // And a RenderPassDrawQuad for the contributing pass. - scoped_ptr<RenderPassDrawQuad> pass_quad = - make_scoped_ptr(new RenderPassDrawQuad); + std::unique_ptr<RenderPassDrawQuad> pass_quad = + base::WrapUnique(new RenderPassDrawQuad); pass_quad->SetNew(pass->shared_quad_state_list.back(), contrib_output_rect, contrib_output_rect, @@ -239,7 +240,7 @@ TEST(RenderPassTest, CopyAllWithCulledQuads) { gfx::Rect damage_rect(56, 123, 19, 43); bool has_transparent_background = true; - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetAll(id, output_rect, damage_rect, diff --git a/chromium/cc/quads/shared_quad_state.h b/chromium/cc/quads/shared_quad_state.h index a66c7bcac2f..35da669c309 100644 --- a/chromium/cc/quads/shared_quad_state.h +++ b/chromium/cc/quads/shared_quad_state.h @@ -5,7 +5,8 @@ #ifndef CC_QUADS_SHARED_QUAD_STATE_H_ #define CC_QUADS_SHARED_QUAD_STATE_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/geometry/rect.h" diff --git a/chromium/cc/quads/solid_color_draw_quad.h b/chromium/cc/quads/solid_color_draw_quad.h index 8b950411ded..97ab1e23881 100644 --- a/chromium/cc/quads/solid_color_draw_quad.h +++ b/chromium/cc/quads/solid_color_draw_quad.h @@ -5,7 +5,8 @@ #ifndef CC_QUADS_SOLID_COLOR_DRAW_QUAD_H_ #define CC_QUADS_SOLID_COLOR_DRAW_QUAD_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" #include "third_party/skia/include/core/SkColor.h" diff --git a/chromium/cc/quads/stream_video_draw_quad.h b/chromium/cc/quads/stream_video_draw_quad.h index 8547b66c395..8137edb2b4e 100644 --- a/chromium/cc/quads/stream_video_draw_quad.h +++ b/chromium/cc/quads/stream_video_draw_quad.h @@ -7,7 +7,8 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" #include "ui/gfx/transform.h" diff --git a/chromium/cc/quads/surface_draw_quad.h b/chromium/cc/quads/surface_draw_quad.h index 86887cae8b3..890f3bf5d3f 100644 --- a/chromium/cc/quads/surface_draw_quad.h +++ b/chromium/cc/quads/surface_draw_quad.h @@ -5,7 +5,8 @@ #ifndef CC_QUADS_SURFACE_DRAW_QUAD_H_ #define CC_QUADS_SURFACE_DRAW_QUAD_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" #include "cc/surfaces/surface_id.h" diff --git a/chromium/cc/quads/texture_draw_quad.cc b/chromium/cc/quads/texture_draw_quad.cc index 6d4c64e966c..2cb6f5189c7 100644 --- a/chromium/cc/quads/texture_draw_quad.cc +++ b/chromium/cc/quads/texture_draw_quad.cc @@ -38,7 +38,8 @@ void TextureDrawQuad::SetNew(const SharedQuadState* shared_quad_state, SkColor background_color, const float vertex_opacity[4], bool y_flipped, - bool nearest_neighbor) { + bool nearest_neighbor, + bool secure_output_only) { bool needs_blending = vertex_opacity[0] != 1.0f || vertex_opacity[1] != 1.0f || vertex_opacity[2] != 1.0f || vertex_opacity[3] != 1.0f; DrawQuad::SetAll(shared_quad_state, DrawQuad::TEXTURE_CONTENT, rect, @@ -55,6 +56,7 @@ void TextureDrawQuad::SetNew(const SharedQuadState* shared_quad_state, this->vertex_opacity[3] = vertex_opacity[3]; this->y_flipped = y_flipped; this->nearest_neighbor = nearest_neighbor; + this->secure_output_only = secure_output_only; } void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state, @@ -70,7 +72,8 @@ void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state, SkColor background_color, const float vertex_opacity[4], bool y_flipped, - bool nearest_neighbor) { + bool nearest_neighbor, + bool secure_output_only) { DrawQuad::SetAll(shared_quad_state, DrawQuad::TEXTURE_CONTENT, rect, opaque_rect, visible_rect, needs_blending); resources.ids[kResourceIdIndex] = resource_id; @@ -86,6 +89,7 @@ void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state, this->vertex_opacity[3] = vertex_opacity[3]; this->y_flipped = y_flipped; this->nearest_neighbor = nearest_neighbor; + this->secure_output_only = secure_output_only; } const TextureDrawQuad* TextureDrawQuad::MaterialCast(const DrawQuad* quad) { diff --git a/chromium/cc/quads/texture_draw_quad.h b/chromium/cc/quads/texture_draw_quad.h index 5ec060eff4e..c9dd0df01ea 100644 --- a/chromium/cc/quads/texture_draw_quad.h +++ b/chromium/cc/quads/texture_draw_quad.h @@ -7,7 +7,8 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" #include "ui/gfx/geometry/rect_f.h" @@ -30,7 +31,8 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { SkColor background_color, const float vertex_opacity[4], bool y_flipped, - bool nearest_neighbor); + bool nearest_neighbor, + bool secure_output_only); void SetAll(const SharedQuadState* shared_quad_state, const gfx::Rect& rect, @@ -45,7 +47,8 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { SkColor background_color, const float vertex_opacity[4], bool y_flipped, - bool nearest_neighbor); + bool nearest_neighbor, + bool secure_output_only); bool premultiplied_alpha; gfx::PointF uv_top_left; @@ -54,6 +57,7 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { float vertex_opacity[4]; bool y_flipped; bool nearest_neighbor; + bool secure_output_only = false; struct OverlayResources { OverlayResources(); diff --git a/chromium/cc/quads/yuv_video_draw_quad.h b/chromium/cc/quads/yuv_video_draw_quad.h index 7193377adf4..1f53e8df877 100644 --- a/chromium/cc/quads/yuv_video_draw_quad.h +++ b/chromium/cc/quads/yuv_video_draw_quad.h @@ -7,7 +7,8 @@ #include <stddef.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" #include "ui/gfx/geometry/rect_f.h" diff --git a/chromium/cc/raster/bitmap_tile_task_worker_pool.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc index 783ec484195..b148860b21e 100644 --- a/chromium/cc/raster/bitmap_tile_task_worker_pool.cc +++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/raster/bitmap_tile_task_worker_pool.h" +#include "cc/raster/bitmap_raster_buffer_provider.h" #include <stddef.h> #include <stdint.h> @@ -10,12 +10,12 @@ #include <algorithm> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #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" @@ -50,7 +50,7 @@ class RasterBufferImpl : public RasterBuffer { << "Why are we rastering a tile that's not dirty?"; size_t stride = 0u; - TileTaskWorkerPool::PlaybackToMemory( + RasterBufferProvider::PlaybackToMemory( lock_.sk_bitmap().getPixels(), resource_->format(), resource_->size(), stride, raster_source, raster_full_rect, playback_rect, scale, playback_settings); @@ -67,82 +67,46 @@ class RasterBufferImpl : public RasterBuffer { } // namespace // static -scoped_ptr<TileTaskWorkerPool> BitmapTileTaskWorkerPool::Create( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, +std::unique_ptr<RasterBufferProvider> BitmapRasterBufferProvider::Create( ResourceProvider* resource_provider) { - return make_scoped_ptr<TileTaskWorkerPool>(new BitmapTileTaskWorkerPool( - task_runner, task_graph_runner, resource_provider)); + return base::WrapUnique<RasterBufferProvider>( + new BitmapRasterBufferProvider(resource_provider)); } -BitmapTileTaskWorkerPool::BitmapTileTaskWorkerPool( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, +BitmapRasterBufferProvider::BitmapRasterBufferProvider( ResourceProvider* resource_provider) - : task_runner_(task_runner), - task_graph_runner_(task_graph_runner), - namespace_token_(task_graph_runner->GetNamespaceToken()), - resource_provider_(resource_provider) {} + : resource_provider_(resource_provider) {} -BitmapTileTaskWorkerPool::~BitmapTileTaskWorkerPool() { -} +BitmapRasterBufferProvider::~BitmapRasterBufferProvider() {} -TileTaskRunner* BitmapTileTaskWorkerPool::AsTileTaskRunner() { - return this; +std::unique_ptr<RasterBuffer> +BitmapRasterBufferProvider::AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) { + return std::unique_ptr<RasterBuffer>(new RasterBufferImpl( + resource_provider_, resource, resource_content_id, previous_content_id)); } -void BitmapTileTaskWorkerPool::Shutdown() { - TRACE_EVENT0("cc", "BitmapTileTaskWorkerPool::Shutdown"); - - TaskGraph empty; - task_graph_runner_->ScheduleTasks(namespace_token_, &empty); - task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); +void BitmapRasterBufferProvider::ReleaseBufferForRaster( + std::unique_ptr<RasterBuffer> buffer) { + // Nothing to do here. RasterBufferImpl destructor cleans up after itself. } -void BitmapTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) { - TRACE_EVENT0("cc", "BitmapTileTaskWorkerPool::ScheduleTasks"); - - ScheduleTasksOnOriginThread(this, graph); - task_graph_runner_->ScheduleTasks(namespace_token_, graph); +void BitmapRasterBufferProvider::OrderingBarrier() { + // No need to sync resources as this provider does not use GL context. } -void BitmapTileTaskWorkerPool::CheckForCompletedTasks() { - TRACE_EVENT0("cc", "BitmapTileTaskWorkerPool::CheckForCompletedTasks"); - - task_graph_runner_->CollectCompletedTasks(namespace_token_, - &completed_tasks_); - for (Task::Vector::const_iterator it = completed_tasks_.begin(); - it != completed_tasks_.end(); ++it) { - TileTask* task = static_cast<TileTask*>(it->get()); - - task->WillComplete(); - task->CompleteOnOriginThread(this); - task->DidComplete(); - } - completed_tasks_.clear(); -} - -ResourceFormat BitmapTileTaskWorkerPool::GetResourceFormat( +ResourceFormat BitmapRasterBufferProvider::GetResourceFormat( bool must_support_alpha) const { return resource_provider_->best_texture_format(); } -bool BitmapTileTaskWorkerPool::GetResourceRequiresSwizzle( +bool BitmapRasterBufferProvider::GetResourceRequiresSwizzle( bool must_support_alpha) const { return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); } -scoped_ptr<RasterBuffer> BitmapTileTaskWorkerPool::AcquireBufferForRaster( - 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( - scoped_ptr<RasterBuffer> buffer) { - // Nothing to do here. RasterBufferImpl destructor cleans up after itself. -} +void BitmapRasterBufferProvider::Shutdown() {} } // namespace cc diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.h b/chromium/cc/raster/bitmap_raster_buffer_provider.h new file mode 100644 index 00000000000..04562262628 --- /dev/null +++ b/chromium/cc/raster/bitmap_raster_buffer_provider.h @@ -0,0 +1,55 @@ +// 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_RASTER_BITMAP_RASTER_BUFFER_PROVIDER_H_ +#define CC_RASTER_BITMAP_RASTER_BUFFER_PROVIDER_H_ + +#include <stdint.h> + +#include "base/macros.h" +#include "base/values.h" +#include "cc/raster/raster_buffer_provider.h" + +namespace base { +namespace trace_event { +class ConvertableToTraceFormat; +} +} + +namespace cc { +class ResourceProvider; + +class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider { + public: + ~BitmapRasterBufferProvider() override; + + static std::unique_ptr<RasterBufferProvider> Create( + ResourceProvider* resource_provider); + + // Overridden from RasterBufferProvider: + std::unique_ptr<RasterBuffer> AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) override; + void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override; + void OrderingBarrier() override; + ResourceFormat GetResourceFormat(bool must_support_alpha) const override; + bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; + void Shutdown() override; + + protected: + explicit BitmapRasterBufferProvider(ResourceProvider* resource_provider); + + private: + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue() + const; + + ResourceProvider* resource_provider_; + + DISALLOW_COPY_AND_ASSIGN(BitmapRasterBufferProvider); +}; + +} // namespace cc + +#endif // CC_RASTER_BITMAP_RASTER_BUFFER_PROVIDER_H_ diff --git a/chromium/cc/raster/bitmap_tile_task_worker_pool.h b/chromium/cc/raster/bitmap_tile_task_worker_pool.h deleted file mode 100644 index 7fea2b2dcfd..00000000000 --- a/chromium/cc/raster/bitmap_tile_task_worker_pool.h +++ /dev/null @@ -1,72 +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_RASTER_BITMAP_TILE_TASK_WORKER_POOL_H_ -#define CC_RASTER_BITMAP_TILE_TASK_WORKER_POOL_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "base/values.h" -#include "cc/raster/tile_task_runner.h" -#include "cc/raster/tile_task_worker_pool.h" - -namespace base { -namespace trace_event { -class ConvertableToTraceFormat; -} -} - -namespace cc { -class ResourceProvider; - -class CC_EXPORT BitmapTileTaskWorkerPool : public TileTaskWorkerPool, - public TileTaskRunner, - public TileTaskClient { - public: - ~BitmapTileTaskWorkerPool() override; - - static scoped_ptr<TileTaskWorkerPool> Create( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider); - - // Overridden from TileTaskWorkerPool: - TileTaskRunner* AsTileTaskRunner() override; - - // Overridden from TileTaskRunner: - void Shutdown() override; - void ScheduleTasks(TaskGraph* graph) override; - void CheckForCompletedTasks() override; - ResourceFormat GetResourceFormat(bool must_support_alpha) const override; - bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; - - // Overridden from TileTaskClient: - scoped_ptr<RasterBuffer> AcquireBufferForRaster( - const Resource* resource, - uint64_t resource_content_id, - uint64_t previous_content_id) override; - void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override; - - protected: - BitmapTileTaskWorkerPool(base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider); - - private: - scoped_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue() const; - - scoped_refptr<base::SequencedTaskRunner> task_runner_; - TaskGraphRunner* task_graph_runner_; - const NamespaceToken namespace_token_; - ResourceProvider* resource_provider_; - - Task::Vector completed_tasks_; - - DISALLOW_COPY_AND_ASSIGN(BitmapTileTaskWorkerPool); -}; - -} // namespace cc - -#endif // CC_RASTER_BITMAP_TILE_TASK_WORKER_POOL_H_ diff --git a/chromium/cc/raster/gpu_tile_task_worker_pool.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc index 27d0a465155..51d88982836 100644 --- a/chromium/cc/raster/gpu_tile_task_worker_pool.cc +++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/raster/gpu_tile_task_worker_pool.h" +#include "cc/raster/gpu_raster_buffer_provider.h" #include <stdint.h> #include <algorithm> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "cc/playback/raster_source.h" #include "cc/raster/gpu_rasterizer.h" -#include "cc/raster/raster_buffer.h" #include "cc/raster/scoped_gpu_raster.h" #include "cc/resources/resource.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -89,106 +89,62 @@ class RasterBufferImpl : public RasterBuffer { } // namespace // static -scoped_ptr<TileTaskWorkerPool> GpuTileTaskWorkerPool::Create( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, +std::unique_ptr<RasterBufferProvider> GpuRasterBufferProvider::Create( ContextProvider* context_provider, ResourceProvider* resource_provider, bool use_distance_field_text, int gpu_rasterization_msaa_sample_count) { - return make_scoped_ptr<TileTaskWorkerPool>(new GpuTileTaskWorkerPool( - task_runner, task_graph_runner, context_provider, resource_provider, - use_distance_field_text, gpu_rasterization_msaa_sample_count)); + return base::WrapUnique<RasterBufferProvider>(new GpuRasterBufferProvider( + context_provider, resource_provider, use_distance_field_text, + gpu_rasterization_msaa_sample_count)); } -GpuTileTaskWorkerPool::GpuTileTaskWorkerPool( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, +GpuRasterBufferProvider::GpuRasterBufferProvider( ContextProvider* context_provider, ResourceProvider* resource_provider, bool use_distance_field_text, int gpu_rasterization_msaa_sample_count) - : task_runner_(task_runner), - task_graph_runner_(task_graph_runner), - namespace_token_(task_graph_runner_->GetNamespaceToken()), - rasterizer_(new GpuRasterizer(context_provider, + : rasterizer_(new GpuRasterizer(context_provider, resource_provider, use_distance_field_text, gpu_rasterization_msaa_sample_count)) {} -GpuTileTaskWorkerPool::~GpuTileTaskWorkerPool() { - DCHECK_EQ(0u, completed_tasks_.size()); -} +GpuRasterBufferProvider::~GpuRasterBufferProvider() {} -TileTaskRunner* GpuTileTaskWorkerPool::AsTileTaskRunner() { - return this; +std::unique_ptr<RasterBuffer> GpuRasterBufferProvider::AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) { + return std::unique_ptr<RasterBuffer>(new RasterBufferImpl( + rasterizer_.get(), resource, resource_content_id, previous_content_id)); } -void GpuTileTaskWorkerPool::Shutdown() { - TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::Shutdown"); - - TaskGraph empty; - task_graph_runner_->ScheduleTasks(namespace_token_, &empty); - task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); +void GpuRasterBufferProvider::ReleaseBufferForRaster( + std::unique_ptr<RasterBuffer> buffer) { + // Nothing to do here. RasterBufferImpl destructor cleans up after itself. } -void GpuTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) { - TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::ScheduleTasks"); - - ScheduleTasksOnOriginThread(this, graph); +void GpuRasterBufferProvider::OrderingBarrier() { + TRACE_EVENT0("cc", "GpuRasterBufferProvider::OrderingBarrier"); - // Barrier to sync any new resources to the worker context. rasterizer_->resource_provider() ->output_surface() ->context_provider() ->ContextGL() ->OrderingBarrierCHROMIUM(); - - task_graph_runner_->ScheduleTasks(namespace_token_, graph); -} - -void GpuTileTaskWorkerPool::CheckForCompletedTasks() { - TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::CheckForCompletedTasks"); - - task_graph_runner_->CollectCompletedTasks(namespace_token_, - &completed_tasks_); - CompleteTasks(completed_tasks_); - completed_tasks_.clear(); } -ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat( +ResourceFormat GpuRasterBufferProvider::GetResourceFormat( bool must_support_alpha) const { return rasterizer_->resource_provider()->best_render_buffer_format(); } -bool GpuTileTaskWorkerPool::GetResourceRequiresSwizzle( +bool GpuRasterBufferProvider::GetResourceRequiresSwizzle( bool must_support_alpha) const { // This doesn't require a swizzle because we rasterize to the correct format. return false; } -void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) { - for (auto& task : tasks) { - TileTask* tile_task = static_cast<TileTask*>(task.get()); - - tile_task->WillComplete(); - tile_task->CompleteOnOriginThread(this); - tile_task->DidComplete(); - } - completed_tasks_.clear(); -} - -scoped_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster( - 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( - scoped_ptr<RasterBuffer> buffer) { - // Nothing to do here. RasterBufferImpl destructor cleans up after itself. -} +void GpuRasterBufferProvider::Shutdown() {} } // namespace cc diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.h b/chromium/cc/raster/gpu_raster_buffer_provider.h new file mode 100644 index 00000000000..3bbc806d59f --- /dev/null +++ b/chromium/cc/raster/gpu_raster_buffer_provider.h @@ -0,0 +1,52 @@ +// 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_RASTER_GPU_RASTER_BUFFER_PROVIDER_H_ +#define CC_RASTER_GPU_RASTER_BUFFER_PROVIDER_H_ + +#include <stdint.h> + +#include "base/macros.h" +#include "cc/raster/raster_buffer_provider.h" + +namespace cc { +class ContextProvider; +class GpuRasterizer; +class ResourceProvider; + +class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider { + public: + ~GpuRasterBufferProvider() override; + + static std::unique_ptr<RasterBufferProvider> Create( + ContextProvider* context_provider, + ResourceProvider* resource_provider, + bool use_distance_field_text, + int gpu_rasterization_msaa_sample_count); + + // Overridden from RasterBufferProvider: + std::unique_ptr<RasterBuffer> AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) override; + void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override; + void OrderingBarrier() override; + ResourceFormat GetResourceFormat(bool must_support_alpha) const override; + bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; + void Shutdown() override; + + private: + GpuRasterBufferProvider(ContextProvider* context_provider, + ResourceProvider* resource_provider, + bool use_distance_field_text, + int gpu_rasterization_msaa_sample_count); + + std::unique_ptr<GpuRasterizer> rasterizer_; + + DISALLOW_COPY_AND_ASSIGN(GpuRasterBufferProvider); +}; + +} // namespace cc + +#endif // CC_RASTER_GPU_RASTER_BUFFER_PROVIDER_H_ diff --git a/chromium/cc/raster/gpu_rasterizer.cc b/chromium/cc/raster/gpu_rasterizer.cc index f6e0288f5dd..f8f8b43d35e 100644 --- a/chromium/cc/raster/gpu_rasterizer.cc +++ b/chromium/cc/raster/gpu_rasterizer.cc @@ -49,7 +49,7 @@ void GpuRasterizer::RasterizeSource( SkPictureRecorder recorder; const gfx::Size size = write_lock->GetResourceSize(); const int flags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; - skia::RefPtr<SkCanvas> canvas = skia::SharePtr( + sk_sp<SkCanvas> canvas = sk_ref_sp( recorder.beginRecording(size.width(), size.height(), NULL, flags)); canvas->save(); raster_source->PlaybackToCanvas(canvas.get(), raster_full_rect, playback_rect, diff --git a/chromium/cc/raster/gpu_rasterizer.h b/chromium/cc/raster/gpu_rasterizer.h index d1951436d53..3e2c9e9d88a 100644 --- a/chromium/cc/raster/gpu_rasterizer.h +++ b/chromium/cc/raster/gpu_rasterizer.h @@ -44,7 +44,7 @@ class CC_EXPORT GpuRasterizer { bool use_distance_field_text_; int msaa_sample_count_; - friend class GpuTileTaskWorkerPool; + friend class GpuRasterBufferProvider; DISALLOW_COPY_AND_ASSIGN(GpuRasterizer); }; diff --git a/chromium/cc/raster/gpu_tile_task_worker_pool.h b/chromium/cc/raster/gpu_tile_task_worker_pool.h deleted file mode 100644 index 0577b51fdfb..00000000000 --- a/chromium/cc/raster/gpu_tile_task_worker_pool.h +++ /dev/null @@ -1,72 +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_RASTER_GPU_TILE_TASK_WORKER_POOL_H_ -#define CC_RASTER_GPU_TILE_TASK_WORKER_POOL_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "cc/raster/tile_task_runner.h" -#include "cc/raster/tile_task_worker_pool.h" - -namespace cc { -class ContextProvider; -class GpuRasterizer; -class ResourceProvider; - -class CC_EXPORT GpuTileTaskWorkerPool : public TileTaskWorkerPool, - public TileTaskRunner, - public TileTaskClient { - public: - ~GpuTileTaskWorkerPool() override; - - static scoped_ptr<TileTaskWorkerPool> Create( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, - ContextProvider* context_provider, - ResourceProvider* resource_provider, - bool use_distance_field_text, - int gpu_rasterization_msaa_sample_count); - - // Overridden from TileTaskWorkerPool: - TileTaskRunner* AsTileTaskRunner() override; - - // Overridden from TileTaskRunner: - void Shutdown() override; - void ScheduleTasks(TaskGraph* graph) override; - void CheckForCompletedTasks() override; - ResourceFormat GetResourceFormat(bool must_support_alpha) const override; - bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; - - // Overridden from TileTaskClient: - scoped_ptr<RasterBuffer> AcquireBufferForRaster( - const Resource* resource, - uint64_t resource_content_id, - uint64_t previous_content_id) override; - void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override; - - private: - GpuTileTaskWorkerPool(base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, - ContextProvider* context_provider, - ResourceProvider* resource_provider, - bool use_distance_field_text, - int gpu_rasterization_msaa_sample_count); - - void CompleteTasks(const Task::Vector& tasks); - - scoped_refptr<base::SequencedTaskRunner> task_runner_; - TaskGraphRunner* task_graph_runner_; - const NamespaceToken namespace_token_; - scoped_ptr<GpuRasterizer> rasterizer_; - - Task::Vector completed_tasks_; - - DISALLOW_COPY_AND_ASSIGN(GpuTileTaskWorkerPool); -}; - -} // namespace cc - -#endif // CC_RASTER_GPU_TILE_TASK_WORKER_POOL_H_ diff --git a/chromium/cc/raster/one_copy_tile_task_worker_pool.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc index 7fb123bb5a0..816820b02f3 100644 --- a/chromium/cc/raster/one_copy_tile_task_worker_pool.cc +++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/raster/one_copy_tile_task_worker_pool.h" +#include "cc/raster/one_copy_raster_buffer_provider.h" #include <stdint.h> @@ -12,7 +12,6 @@ #include "base/macros.h" #include "cc/base/math_util.h" -#include "cc/raster/raster_buffer.h" #include "cc/raster/staging_buffer_pool.h" #include "cc/resources/platform_color.h" #include "cc/resources/resource_format.h" @@ -28,7 +27,7 @@ namespace { class RasterBufferImpl : public RasterBuffer { public: - RasterBufferImpl(OneCopyTileTaskWorkerPool* worker_pool, + RasterBufferImpl(OneCopyRasterBufferProvider* worker_pool, ResourceProvider* resource_provider, ResourceFormat resource_format, const Resource* resource, @@ -54,7 +53,7 @@ class RasterBufferImpl : public RasterBuffer { } private: - OneCopyTileTaskWorkerPool* worker_pool_; + OneCopyRasterBufferProvider* worker_pool_; const Resource* resource_; ResourceProvider::ScopedWriteLockGL lock_; uint64_t previous_content_id_; @@ -69,32 +68,28 @@ const int kMaxBytesPerCopyOperation = 1024 * 1024 * 4; } // namespace // static -scoped_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create( +std::unique_ptr<RasterBufferProvider> OneCopyRasterBufferProvider::Create( base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, ContextProvider* context_provider, ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_partial_raster, int max_staging_buffer_usage_in_bytes, ResourceFormat preferred_tile_format) { - return make_scoped_ptr<TileTaskWorkerPool>(new OneCopyTileTaskWorkerPool( - task_runner, task_graph_runner, resource_provider, - max_copy_texture_chromium_size, use_partial_raster, - max_staging_buffer_usage_in_bytes, preferred_tile_format)); + return base::WrapUnique<RasterBufferProvider>(new OneCopyRasterBufferProvider( + task_runner, resource_provider, max_copy_texture_chromium_size, + use_partial_raster, max_staging_buffer_usage_in_bytes, + preferred_tile_format)); } -OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( +OneCopyRasterBufferProvider::OneCopyRasterBufferProvider( base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_partial_raster, int max_staging_buffer_usage_in_bytes, ResourceFormat preferred_tile_format) - : task_graph_runner_(task_graph_runner), - namespace_token_(task_graph_runner->GetNamespaceToken()), - resource_provider_(resource_provider), + : resource_provider_(resource_provider), max_bytes_per_copy_operation_( max_copy_texture_chromium_size ? std::min(kMaxBytesPerCopyOperation, @@ -108,55 +103,35 @@ OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( max_staging_buffer_usage_in_bytes); } -OneCopyTileTaskWorkerPool::~OneCopyTileTaskWorkerPool() { -} +OneCopyRasterBufferProvider::~OneCopyRasterBufferProvider() {} -TileTaskRunner* OneCopyTileTaskWorkerPool::AsTileTaskRunner() { - return this; +std::unique_ptr<RasterBuffer> +OneCopyRasterBufferProvider::AcquireBufferForRaster( + 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. + return base::WrapUnique<RasterBuffer>( + new RasterBufferImpl(this, resource_provider_, resource->format(), + resource, previous_content_id)); } -void OneCopyTileTaskWorkerPool::Shutdown() { - TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::Shutdown"); - - TaskGraph empty; - task_graph_runner_->ScheduleTasks(namespace_token_, &empty); - task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); - - staging_pool_->Shutdown(); +void OneCopyRasterBufferProvider::ReleaseBufferForRaster( + std::unique_ptr<RasterBuffer> buffer) { + // Nothing to do here. RasterBufferImpl destructor cleans up after itself. } -void OneCopyTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) { - TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::ScheduleTasks"); +void OneCopyRasterBufferProvider::OrderingBarrier() { + TRACE_EVENT0("cc", "OneCopyRasterBufferProvider::OrderingBarrier"); - ScheduleTasksOnOriginThread(this, graph); - - // Barrier to sync any new resources to the worker context. resource_provider_->output_surface() ->context_provider() ->ContextGL() ->OrderingBarrierCHROMIUM(); - - task_graph_runner_->ScheduleTasks(namespace_token_, graph); } -void OneCopyTileTaskWorkerPool::CheckForCompletedTasks() { - TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::CheckForCompletedTasks"); - - task_graph_runner_->CollectCompletedTasks(namespace_token_, - &completed_tasks_); - - for (Task::Vector::const_iterator it = completed_tasks_.begin(); - it != completed_tasks_.end(); ++it) { - TileTask* task = static_cast<TileTask*>(it->get()); - - task->WillComplete(); - task->CompleteOnOriginThread(this); - task->DidComplete(); - } - completed_tasks_.clear(); -} - -ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat( +ResourceFormat OneCopyRasterBufferProvider::GetResourceFormat( bool must_support_alpha) const { if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) && (DoesResourceFormatSupportAlpha(preferred_tile_format_) || @@ -167,28 +142,16 @@ ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat( return resource_provider_->best_texture_format(); } -bool OneCopyTileTaskWorkerPool::GetResourceRequiresSwizzle( +bool OneCopyRasterBufferProvider::GetResourceRequiresSwizzle( bool must_support_alpha) const { return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); } -scoped_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster( - 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. - return make_scoped_ptr<RasterBuffer>( - new RasterBufferImpl(this, resource_provider_, resource->format(), - resource, previous_content_id)); -} - -void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster( - scoped_ptr<RasterBuffer> buffer) { - // Nothing to do here. RasterBufferImpl destructor cleans up after itself. +void OneCopyRasterBufferProvider::Shutdown() { + staging_pool_->Shutdown(); } -void OneCopyTileTaskWorkerPool::PlaybackAndCopyOnWorkerThread( +void OneCopyRasterBufferProvider::PlaybackAndCopyOnWorkerThread( const Resource* resource, ResourceProvider::ScopedWriteLockGL* resource_lock, const RasterSource* raster_source, @@ -198,7 +161,7 @@ void OneCopyTileTaskWorkerPool::PlaybackAndCopyOnWorkerThread( const RasterSource::PlaybackSettings& playback_settings, uint64_t previous_content_id, uint64_t new_content_id) { - scoped_ptr<StagingBuffer> staging_buffer = + std::unique_ptr<StagingBuffer> staging_buffer = staging_pool_->AcquireStagingBuffer(resource, previous_content_id); PlaybackToStagingBuffer(staging_buffer.get(), resource, raster_source, @@ -212,7 +175,7 @@ void OneCopyTileTaskWorkerPool::PlaybackAndCopyOnWorkerThread( staging_pool_->ReleaseStagingBuffer(std::move(staging_buffer)); } -void OneCopyTileTaskWorkerPool::PlaybackToStagingBuffer( +void OneCopyRasterBufferProvider::PlaybackToStagingBuffer( StagingBuffer* staging_buffer, const Resource* resource, const RasterSource* raster_source, @@ -232,7 +195,7 @@ void OneCopyTileTaskWorkerPool::PlaybackToStagingBuffer( use_partial_raster_ ? gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT : gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - 0 /* surface_id */); + gpu::kNullSurfaceHandle); } gfx::Rect playback_rect = raster_full_rect; @@ -249,12 +212,12 @@ void OneCopyTileTaskWorkerPool::PlaybackToStagingBuffer( bool rv = buffer->Map(); DCHECK(rv); DCHECK(buffer->memory(0)); - // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides. + // RasterBufferProvider::PlaybackToMemory only supports unsigned strides. DCHECK_GE(buffer->stride(0), 0); DCHECK(!playback_rect.IsEmpty()) << "Why are we rastering a tile that's not dirty?"; - TileTaskWorkerPool::PlaybackToMemory( + RasterBufferProvider::PlaybackToMemory( buffer->memory(0), resource->format(), staging_buffer->size, buffer->stride(0), raster_source, raster_full_rect, playback_rect, scale, playback_settings); @@ -263,7 +226,7 @@ void OneCopyTileTaskWorkerPool::PlaybackToStagingBuffer( } } -void OneCopyTileTaskWorkerPool::CopyOnWorkerThread( +void OneCopyRasterBufferProvider::CopyOnWorkerThread( StagingBuffer* staging_buffer, const Resource* resource, ResourceProvider::ScopedWriteLockGL* resource_lock, @@ -332,8 +295,8 @@ void OneCopyTileTaskWorkerPool::CopyOnWorkerThread( gl->CompressedCopyTextureCHROMIUM(staging_buffer->texture_id, resource_lock->texture_id()); } else { - int bytes_per_row = - (BitsPerPixel(resource->format()) * resource->size().width()) / 8; + int bytes_per_row = ResourceUtil::UncheckedWidthInBytes<int>( + resource->size().width(), resource->format()); 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. diff --git a/chromium/cc/raster/one_copy_tile_task_worker_pool.h b/chromium/cc/raster/one_copy_raster_buffer_provider.h index c4614b1ac75..0c129faa16f 100644 --- a/chromium/cc/raster/one_copy_tile_task_worker_pool.h +++ b/chromium/cc/raster/one_copy_raster_buffer_provider.h @@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_RASTER_ONE_COPY_TILE_TASK_WORKER_POOL_H_ -#define CC_RASTER_ONE_COPY_TILE_TASK_WORKER_POOL_H_ +#ifndef CC_RASTER_ONE_COPY_RASTER_BUFFER_PROVIDER_H_ +#define CC_RASTER_ONE_COPY_RASTER_BUFFER_PROVIDER_H_ #include <stdint.h> #include "base/macros.h" #include "cc/output/context_provider.h" -#include "cc/raster/tile_task_runner.h" -#include "cc/raster/tile_task_worker_pool.h" +#include "cc/raster/raster_buffer_provider.h" #include "cc/resources/resource_provider.h" namespace cc { @@ -18,15 +17,12 @@ struct StagingBuffer; class StagingBufferPool; class ResourcePool; -class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool, - public TileTaskRunner, - public TileTaskClient { +class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider { public: - ~OneCopyTileTaskWorkerPool() override; + ~OneCopyRasterBufferProvider() override; - static scoped_ptr<TileTaskWorkerPool> Create( + static std::unique_ptr<RasterBufferProvider> Create( base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, ContextProvider* context_provider, ResourceProvider* resource_provider, int max_copy_texture_chromium_size, @@ -34,22 +30,16 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool, int max_staging_buffer_usage_in_bytes, ResourceFormat preferred_tile_format); - // Overridden from TileTaskWorkerPool: - TileTaskRunner* AsTileTaskRunner() override; - - // Overridden from TileTaskRunner: - void Shutdown() override; - void ScheduleTasks(TaskGraph* graph) override; - void CheckForCompletedTasks() override; - ResourceFormat GetResourceFormat(bool must_support_alpha) const override; - bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; - - // Overridden from TileTaskClient: - scoped_ptr<RasterBuffer> AcquireBufferForRaster( + // Overridden from RasterBufferProvider: + std::unique_ptr<RasterBuffer> AcquireBufferForRaster( const Resource* resource, uint64_t resource_content_id, uint64_t previous_content_id) override; - void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override; + void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override; + void OrderingBarrier() override; + ResourceFormat GetResourceFormat(bool must_support_alpha) const override; + bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; + void Shutdown() override; // Playback raster source and copy result into |resource|. void PlaybackAndCopyOnWorkerThread( @@ -64,13 +54,12 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool, uint64_t new_content_id); protected: - OneCopyTileTaskWorkerPool(base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider, - int max_copy_texture_chromium_size, - bool use_partial_raster, - int max_staging_buffer_usage_in_bytes, - ResourceFormat preferred_tile_format); + OneCopyRasterBufferProvider(base::SequencedTaskRunner* task_runner, + ResourceProvider* resource_provider, + int max_copy_texture_chromium_size, + bool use_partial_raster, + int max_staging_buffer_usage_in_bytes, + ResourceFormat preferred_tile_format); private: void PlaybackToStagingBuffer( @@ -90,8 +79,6 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool, uint64_t previous_content_id, uint64_t new_content_id); - TaskGraphRunner* task_graph_runner_; - const NamespaceToken namespace_token_; ResourceProvider* const resource_provider_; const int max_bytes_per_copy_operation_; bool use_partial_raster_; @@ -100,13 +87,11 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool, int bytes_scheduled_since_last_flush_; ResourceFormat preferred_tile_format_; - scoped_ptr<StagingBufferPool> staging_pool_; - - Task::Vector completed_tasks_; + std::unique_ptr<StagingBufferPool> staging_pool_; - DISALLOW_COPY_AND_ASSIGN(OneCopyTileTaskWorkerPool); + DISALLOW_COPY_AND_ASSIGN(OneCopyRasterBufferProvider); }; } // namespace cc -#endif // CC_RASTER_ONE_COPY_TILE_TASK_WORKER_POOL_H_ +#endif // CC_RASTER_ONE_COPY_RASTER_BUFFER_PROVIDER_H_ diff --git a/chromium/cc/raster/tile_task_worker_pool.cc b/chromium/cc/raster/raster_buffer_provider.cc index 2efd928b245..67b839c2f3a 100644 --- a/chromium/cc/raster/tile_task_worker_pool.cc +++ b/chromium/cc/raster/raster_buffer_provider.cc @@ -2,39 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/raster/tile_task_worker_pool.h" +#include "cc/raster/raster_buffer_provider.h" #include <stddef.h> #include "base/trace_event/trace_event.h" #include "cc/playback/raster_source.h" #include "cc/raster/texture_compressor.h" +#include "cc/resources/platform_color.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSurface.h" namespace cc { -TileTaskWorkerPool::TileTaskWorkerPool() {} +RasterBufferProvider::RasterBufferProvider() {} -TileTaskWorkerPool::~TileTaskWorkerPool() {} - -// static -void TileTaskWorkerPool::ScheduleTasksOnOriginThread(TileTaskClient* client, - TaskGraph* graph) { - TRACE_EVENT0("cc", "TileTaskWorkerPool::ScheduleTasksOnOriginThread"); - - for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); - it != graph->nodes.end(); ++it) { - TaskGraph::Node& node = *it; - TileTask* task = static_cast<TileTask*>(node.task); - - if (!task->HasBeenScheduled()) { - task->WillSchedule(); - task->ScheduleOnOriginThread(client); - task->DidSchedule(); - } - } -} +RasterBufferProvider::~RasterBufferProvider() {} namespace { @@ -59,7 +42,7 @@ bool IsSupportedPlaybackToMemoryFormat(ResourceFormat format) { } // anonymous namespace // static -void TileTaskWorkerPool::PlaybackToMemory( +void RasterBufferProvider::PlaybackToMemory( void* memory, ResourceFormat format, const gfx::Size& size, @@ -69,7 +52,7 @@ void TileTaskWorkerPool::PlaybackToMemory( const gfx::Rect& canvas_playback_rect, float scale, const RasterSource::PlaybackSettings& playback_settings) { - TRACE_EVENT0("cc", "TileTaskWorkerPool::PlaybackToMemory"); + TRACE_EVENT0("cc", "RasterBufferProvider::PlaybackToMemory"); DCHECK(IsSupportedPlaybackToMemoryFormat(format)) << format; @@ -109,22 +92,24 @@ void TileTaskWorkerPool::PlaybackToMemory( if (format == ETC1) { TRACE_EVENT0("cc", - "TileTaskWorkerPool::PlaybackToMemory::CompressETC1"); + "RasterBufferProvider::PlaybackToMemory::CompressETC1"); DCHECK_EQ(size.width() % 4, 0); DCHECK_EQ(size.height() % 4, 0); - scoped_ptr<TextureCompressor> texture_compressor = + std::unique_ptr<TextureCompressor> texture_compressor = TextureCompressor::Create(TextureCompressor::kFormatETC1); - texture_compressor->Compress(reinterpret_cast<const uint8_t*>( - surface->peekPixels(nullptr, nullptr)), - reinterpret_cast<uint8_t*>(memory), - size.width(), size.height(), - TextureCompressor::kQualityHigh); + SkPixmap pixmap; + surface->peekPixels(&pixmap); + texture_compressor->Compress( + reinterpret_cast<const uint8_t*>(pixmap.addr()), + reinterpret_cast<uint8_t*>(memory), size.width(), size.height(), + TextureCompressor::kQualityHigh); } else { TRACE_EVENT0("cc", - "TileTaskWorkerPool::PlaybackToMemory::ConvertRGBA4444"); - SkImageInfo dst_info = SkImageInfo::Make( - info.width(), info.height(), ResourceFormatToSkColorType(format), - info.alphaType(), info.profileType()); + "RasterBufferProvider::PlaybackToMemory::ConvertRGBA4444"); + SkImageInfo dst_info = + SkImageInfo::Make(info.width(), info.height(), + ResourceFormatToClosestSkColorType(format), + info.alphaType(), info.profileType()); bool rv = surface->readPixels(dst_info, memory, stride, 0, 0); DCHECK(rv); } @@ -142,4 +127,25 @@ void TileTaskWorkerPool::PlaybackToMemory( NOTREACHED(); } +bool RasterBufferProvider::ResourceFormatRequiresSwizzle( + ResourceFormat format) { + switch (format) { + case RGBA_8888: + case BGRA_8888: + // Initialize resource using the preferred PlatformColor component + // order and swizzle in the shader instead of in software. + return !PlatformColor::SameComponentOrder(format); + case RGBA_4444: + case ETC1: + case ALPHA_8: + case LUMINANCE_8: + case RGB_565: + case RED_8: + case LUMINANCE_F16: + return false; + } + NOTREACHED(); + return false; +} + } // namespace cc diff --git a/chromium/cc/raster/raster_buffer_provider.h b/chromium/cc/raster/raster_buffer_provider.h new file mode 100644 index 00000000000..061740a0e06 --- /dev/null +++ b/chromium/cc/raster/raster_buffer_provider.h @@ -0,0 +1,75 @@ +// 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. + +#ifndef CC_RASTER_RASTER_BUFFER_PROVIDER_H_ +#define CC_RASTER_RASTER_BUFFER_PROVIDER_H_ + +#include <stddef.h> + +#include "cc/playback/raster_source.h" +#include "cc/raster/raster_buffer.h" +#include "cc/raster/task_graph_runner.h" +#include "cc/raster/tile_task.h" +#include "cc/resources/resource_format.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" + +namespace base { +class SequencedTaskRunner; +} + +namespace cc { +class Resource; + +class CC_EXPORT RasterBufferProvider { + public: + RasterBufferProvider(); + virtual ~RasterBufferProvider(); + + // Utility function that will create a temporary bitmap and copy pixels to + // |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, + size_t stride, + const RasterSource* raster_source, + const gfx::Rect& canvas_bitmap_rect, + const gfx::Rect& canvas_playback_rect, + float scale, + const RasterSource::PlaybackSettings& playback_settings); + + // Acquire raster buffer. + virtual std::unique_ptr<RasterBuffer> AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) = 0; + + // Release raster buffer. + virtual void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) = 0; + + // Barrier to sync resources to the worker context. + virtual void OrderingBarrier() = 0; + + // Returns the format to use for the tiles. + virtual ResourceFormat GetResourceFormat(bool must_support_alpha) const = 0; + + // Determine if the resource requires swizzling. + virtual bool GetResourceRequiresSwizzle(bool must_support_alpha) const = 0; + + // Shutdown for doing cleanup. + virtual void Shutdown() = 0; + + protected: + // Check if resource format matches output format. + static bool ResourceFormatRequiresSwizzle(ResourceFormat format); +}; + +} // namespace cc + +#endif // CC_RASTER_RASTER_BUFFER_PROVIDER_H_ diff --git a/chromium/cc/raster/tile_task_worker_pool_perftest.cc b/chromium/cc/raster/raster_buffer_provider_perftest.cc index 086d7b192dc..662a24a5958 100644 --- a/chromium/cc/raster/tile_task_worker_pool_perftest.cc +++ b/chromium/cc/raster/raster_buffer_provider_perftest.cc @@ -2,24 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/raster/tile_task_worker_pool.h" - #include <stddef.h> #include <stdint.h> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/test/test_simple_task_runner.h" #include "base/time/time.h" #include "cc/debug/lap_timer.h" #include "cc/output/context_provider.h" -#include "cc/raster/bitmap_tile_task_worker_pool.h" +#include "cc/raster/bitmap_raster_buffer_provider.h" +#include "cc/raster/gpu_raster_buffer_provider.h" #include "cc/raster/gpu_rasterizer.h" -#include "cc/raster/gpu_tile_task_worker_pool.h" -#include "cc/raster/one_copy_tile_task_worker_pool.h" -#include "cc/raster/raster_buffer.h" +#include "cc/raster/one_copy_raster_buffer_provider.h" +#include "cc/raster/raster_buffer_provider.h" #include "cc/raster/synchronous_task_graph_runner.h" -#include "cc/raster/tile_task_runner.h" -#include "cc/raster/zero_copy_tile_task_worker_pool.h" +#include "cc/raster/zero_copy_raster_buffer_provider.h" #include "cc/resources/resource_pool.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_resource.h" @@ -30,6 +28,7 @@ #include "cc/test/test_gpu_memory_buffer_manager.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" +#include "cc/tiles/tile_task_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_test.h" #include "third_party/khronos/GLES2/gl2.h" @@ -76,10 +75,10 @@ class PerfContextProvider : public ContextProvider { PerfContextProvider() : context_gl_(new PerfGLES2Interface) {} bool BindToCurrentThread() override { return true; } - Capabilities ContextCapabilities() override { - Capabilities capabilities; - capabilities.gpu.image = true; - capabilities.gpu.sync_query = true; + gpu::Capabilities ContextCapabilities() override { + gpu::Capabilities capabilities; + capabilities.image = true; + capabilities.sync_query = true; return capabilities; } gpu::gles2::GLES2Interface* ContextGL() override { return context_gl_.get(); } @@ -88,9 +87,8 @@ class PerfContextProvider : public ContextProvider { if (gr_context_) return gr_context_.get(); - skia::RefPtr<const GrGLInterface> null_interface = - skia::AdoptRef(GrGLCreateNullInterface()); - gr_context_ = skia::AdoptRef(GrContext::Create( + sk_sp<const GrGLInterface> null_interface(GrGLCreateNullInterface()); + gr_context_ = sk_sp<class GrContext>(GrContext::Create( kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(null_interface.get()))); return gr_context_.get(); @@ -99,7 +97,6 @@ class PerfContextProvider : public ContextProvider { if (gr_context_) gr_context_.get()->resetContext(state); } - void SetupLock() override {} base::Lock* GetLock() override { return &context_lock_; } void DeleteCachedResources() override {} void SetLostContextCallback(const LostContextCallback& cb) override {} @@ -107,36 +104,38 @@ class PerfContextProvider : public ContextProvider { private: ~PerfContextProvider() override {} - scoped_ptr<PerfGLES2Interface> context_gl_; - skia::RefPtr<class GrContext> gr_context_; + std::unique_ptr<PerfGLES2Interface> context_gl_; + sk_sp<class GrContext> gr_context_; TestContextSupport support_; base::Lock context_lock_; }; -enum TileTaskWorkerPoolType { - TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY, - TILE_TASK_WORKER_POOL_TYPE_ONE_COPY, - TILE_TASK_WORKER_POOL_TYPE_GPU, - TILE_TASK_WORKER_POOL_TYPE_BITMAP +enum RasterBufferProviderType { + RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY, + RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY, + RASTER_BUFFER_PROVIDER_TYPE_GPU, + RASTER_BUFFER_PROVIDER_TYPE_BITMAP }; static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -class PerfImageDecodeTaskImpl : public ImageDecodeTask { +class PerfImageDecodeTaskImpl : public TileTask { public: - PerfImageDecodeTaskImpl() {} + PerfImageDecodeTaskImpl() : TileTask(true) {} // Overridden from Task: void RunOnWorkerThread() override {} // Overridden from TileTask: - void ScheduleOnOriginThread(TileTaskClient* client) override {} - void CompleteOnOriginThread(TileTaskClient* client) override { Reset(); } + void ScheduleOnOriginThread(RasterBufferProvider* provider) override {} + void CompleteOnOriginThread(RasterBufferProvider* provider) override { + Reset(); + } void Reset() { - did_run_ = false; + state().Reset(); did_complete_ = false; } @@ -147,27 +146,27 @@ class PerfImageDecodeTaskImpl : public ImageDecodeTask { DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl); }; -class PerfRasterTaskImpl : public RasterTask { +class PerfRasterTaskImpl : public TileTask { public: - PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource, - ImageDecodeTask::Vector* dependencies) - : RasterTask(dependencies), resource_(std::move(resource)) {} + PerfRasterTaskImpl(std::unique_ptr<ScopedResource> resource, + TileTask::Vector* dependencies) + : TileTask(true, dependencies), resource_(std::move(resource)) {} // Overridden from Task: void RunOnWorkerThread() override {} // Overridden from TileTask: - void ScheduleOnOriginThread(TileTaskClient* client) override { + void ScheduleOnOriginThread(RasterBufferProvider* provider) override { // No tile ids are given to support partial updates. - raster_buffer_ = client->AcquireBufferForRaster(resource_.get(), 0, 0); + raster_buffer_ = provider->AcquireBufferForRaster(resource_.get(), 0, 0); } - void CompleteOnOriginThread(TileTaskClient* client) override { - client->ReleaseBufferForRaster(std::move(raster_buffer_)); + void CompleteOnOriginThread(RasterBufferProvider* provider) override { + provider->ReleaseBufferForRaster(std::move(raster_buffer_)); Reset(); } void Reset() { - did_run_ = false; + state().Reset(); did_complete_ = false; } @@ -175,19 +174,19 @@ class PerfRasterTaskImpl : public RasterTask { ~PerfRasterTaskImpl() override {} private: - scoped_ptr<ScopedResource> resource_; - scoped_ptr<RasterBuffer> raster_buffer_; + std::unique_ptr<ScopedResource> resource_; + std::unique_ptr<RasterBuffer> raster_buffer_; DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl); }; -class TileTaskWorkerPoolPerfTestBase { +class RasterBufferProviderPerfTestBase { public: - typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector; + typedef std::vector<scoped_refptr<TileTask>> RasterTaskVector; enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL }; - TileTaskWorkerPoolPerfTestBase() + RasterBufferProviderPerfTestBase() : context_provider_(make_scoped_refptr(new PerfContextProvider)), task_runner_(new base::TestSimpleTaskRunner), task_graph_runner_(new SynchronousTaskGraphRunner), @@ -196,23 +195,23 @@ class TileTaskWorkerPoolPerfTestBase { kTimeCheckInterval) {} void CreateImageDecodeTasks(unsigned num_image_decode_tasks, - ImageDecodeTask::Vector* image_decode_tasks) { + TileTask::Vector* image_decode_tasks) { for (unsigned i = 0; i < num_image_decode_tasks; ++i) image_decode_tasks->push_back(new PerfImageDecodeTaskImpl); } void CreateRasterTasks(unsigned num_raster_tasks, - const ImageDecodeTask::Vector& image_decode_tasks, + const TileTask::Vector& image_decode_tasks, RasterTaskVector* raster_tasks) { const gfx::Size size(1, 1); for (unsigned i = 0; i < num_raster_tasks; ++i) { - scoped_ptr<ScopedResource> resource( + std::unique_ptr<ScopedResource> resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); - ImageDecodeTask::Vector dependencies = image_decode_tasks; + TileTask::Vector dependencies = image_decode_tasks; raster_tasks->push_back( new PerfRasterTaskImpl(std::move(resource), &dependencies)); } @@ -226,10 +225,20 @@ class TileTaskWorkerPoolPerfTestBase { priority++; for (auto& decode_task : raster_task->dependencies()) { - graph->nodes.push_back( - TaskGraph::Node(decode_task.get(), 0u /* group */, priority, 0u)); + // Add decode task if it doesn't already exist in graph. + TaskGraph::Node::Vector::iterator decode_it = + std::find_if(graph->nodes.begin(), graph->nodes.end(), + [decode_task](const TaskGraph::Node& node) { + return node.task == decode_task; + }); + + if (decode_it == graph->nodes.end()) { + graph->nodes.push_back( + TaskGraph::Node(decode_task.get(), 0u /* group */, priority, 0u)); + } + graph->edges.push_back( - TaskGraph::Edge(raster_task.get(), decode_task.get())); + TaskGraph::Edge(decode_task.get(), raster_task.get())); } graph->nodes.push_back(TaskGraph::Node( @@ -241,54 +250,54 @@ class TileTaskWorkerPoolPerfTestBase { protected: scoped_refptr<ContextProvider> context_provider_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> output_surface_; - scoped_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<FakeOutputSurface> output_surface_; + std::unique_ptr<ResourceProvider> resource_provider_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; - scoped_ptr<SynchronousTaskGraphRunner> task_graph_runner_; + std::unique_ptr<SynchronousTaskGraphRunner> task_graph_runner_; LapTimer timer_; }; -class TileTaskWorkerPoolPerfTest - : public TileTaskWorkerPoolPerfTestBase, - public testing::TestWithParam<TileTaskWorkerPoolType> { +class RasterBufferProviderPerfTest + : public RasterBufferProviderPerfTestBase, + public testing::TestWithParam<RasterBufferProviderType> { public: // Overridden from testing::Test: void SetUp() override { + std::unique_ptr<RasterBufferProvider> raster_buffer_provider; switch (GetParam()) { - case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY: + case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY: Create3dOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create( - task_runner_.get(), task_graph_runner_.get(), + raster_buffer_provider = ZeroCopyRasterBufferProvider::Create( resource_provider_.get(), PlatformColor::BestTextureFormat()); break; - case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY: + case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY: Create3dOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create( - task_runner_.get(), task_graph_runner_.get(), - context_provider_.get(), resource_provider_.get(), - std::numeric_limits<int>::max(), false, + raster_buffer_provider = OneCopyRasterBufferProvider::Create( + task_runner_.get(), context_provider_.get(), + resource_provider_.get(), std::numeric_limits<int>::max(), false, std::numeric_limits<int>::max(), PlatformColor::BestTextureFormat()); break; - case TILE_TASK_WORKER_POOL_TYPE_GPU: + case RASTER_BUFFER_PROVIDER_TYPE_GPU: Create3dOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create( - task_runner_.get(), task_graph_runner_.get(), + raster_buffer_provider = GpuRasterBufferProvider::Create( context_provider_.get(), resource_provider_.get(), false, 0); break; - case TILE_TASK_WORKER_POOL_TYPE_BITMAP: + case RASTER_BUFFER_PROVIDER_TYPE_BITMAP: CreateSoftwareOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create( - task_runner_.get(), task_graph_runner_.get(), - resource_provider_.get()); + raster_buffer_provider = + BitmapRasterBufferProvider::Create(resource_provider_.get()); break; } - DCHECK(tile_task_worker_pool_); + DCHECK(raster_buffer_provider); + + tile_task_manager_ = TileTaskManagerImpl::Create( + std::move(raster_buffer_provider), task_graph_runner_.get()); } void TearDown() override { - tile_task_worker_pool_->AsTileTaskRunner()->Shutdown(); - tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks(); + tile_task_manager_->Shutdown(); + tile_task_manager_->CheckForCompletedTasks(); } void RunMessageLoopUntilAllTasksHaveCompleted() { @@ -299,7 +308,7 @@ class TileTaskWorkerPoolPerfTest void RunScheduleTasksTest(const std::string& test_name, unsigned num_raster_tasks, unsigned num_image_decode_tasks) { - ImageDecodeTask::Vector image_decode_tasks; + TileTask::Vector image_decode_tasks; RasterTaskVector raster_tasks; CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks); CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks); @@ -311,13 +320,13 @@ class TileTaskWorkerPoolPerfTest do { graph.Reset(); BuildTileTaskGraph(&graph, raster_tasks); - tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&graph); - tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks(); + tile_task_manager_->ScheduleTasks(&graph); + tile_task_manager_->CheckForCompletedTasks(); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); TaskGraph empty; - tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty); + tile_task_manager_->ScheduleTasks(&empty); RunMessageLoopUntilAllTasksHaveCompleted(); perf_test::PrintResult("schedule_tasks", TestModifierString(), test_name, @@ -328,7 +337,7 @@ class TileTaskWorkerPoolPerfTest unsigned num_raster_tasks, unsigned num_image_decode_tasks) { const size_t kNumVersions = 2; - ImageDecodeTask::Vector image_decode_tasks[kNumVersions]; + TileTask::Vector image_decode_tasks[kNumVersions]; RasterTaskVector raster_tasks[kNumVersions]; for (size_t i = 0; i < kNumVersions; ++i) { CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]); @@ -344,14 +353,14 @@ class TileTaskWorkerPoolPerfTest do { graph.Reset(); BuildTileTaskGraph(&graph, raster_tasks[count % kNumVersions]); - tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&graph); - tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks(); + tile_task_manager_->ScheduleTasks(&graph); + tile_task_manager_->CheckForCompletedTasks(); ++count; timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); TaskGraph empty; - tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty); + tile_task_manager_->ScheduleTasks(&empty); RunMessageLoopUntilAllTasksHaveCompleted(); perf_test::PrintResult("schedule_alternate_tasks", TestModifierString(), @@ -361,7 +370,7 @@ class TileTaskWorkerPoolPerfTest void RunScheduleAndExecuteTasksTest(const std::string& test_name, unsigned num_raster_tasks, unsigned num_image_decode_tasks) { - ImageDecodeTask::Vector image_decode_tasks; + TileTask::Vector image_decode_tasks; RasterTaskVector raster_tasks; CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks); CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks); @@ -373,13 +382,13 @@ class TileTaskWorkerPoolPerfTest do { graph.Reset(); BuildTileTaskGraph(&graph, raster_tasks); - tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&graph); + tile_task_manager_->ScheduleTasks(&graph); RunMessageLoopUntilAllTasksHaveCompleted(); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); TaskGraph empty; - tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty); + tile_task_manager_->ScheduleTasks(&empty); RunMessageLoopUntilAllTasksHaveCompleted(); perf_test::PrintResult("schedule_and_execute_tasks", TestModifierString(), @@ -396,7 +405,7 @@ class TileTaskWorkerPoolPerfTest void CreateSoftwareOutputSurfaceAndResourceProvider() { output_surface_ = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = FakeResourceProvider::Create( output_surface_.get(), &shared_bitmap_manager_, nullptr); @@ -404,25 +413,25 @@ class TileTaskWorkerPoolPerfTest std::string TestModifierString() const { switch (GetParam()) { - case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY: - return std::string("_zero_copy_tile_task_worker_pool"); - case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY: - return std::string("_one_copy_tile_task_worker_pool"); - case TILE_TASK_WORKER_POOL_TYPE_GPU: - return std::string("_gpu_tile_task_worker_pool"); - case TILE_TASK_WORKER_POOL_TYPE_BITMAP: - return std::string("_bitmap_tile_task_worker_pool"); + case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY: + return std::string("_zero_copy_raster_buffer_provider"); + case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY: + return std::string("_one_copy_raster_buffer_provider"); + case RASTER_BUFFER_PROVIDER_TYPE_GPU: + return std::string("_gpu_raster_buffer_provider"); + case RASTER_BUFFER_PROVIDER_TYPE_BITMAP: + return std::string("_bitmap_raster_buffer_provider"); } NOTREACHED(); return std::string(); } - scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_; + std::unique_ptr<TileTaskManager> tile_task_manager_; TestGpuMemoryBufferManager gpu_memory_buffer_manager_; TestSharedBitmapManager shared_bitmap_manager_; }; -TEST_P(TileTaskWorkerPoolPerfTest, ScheduleTasks) { +TEST_P(RasterBufferProviderPerfTest, ScheduleTasks) { RunScheduleTasksTest("1_0", 1, 0); RunScheduleTasksTest("32_0", 32, 0); RunScheduleTasksTest("1_1", 1, 1); @@ -431,7 +440,7 @@ TEST_P(TileTaskWorkerPoolPerfTest, ScheduleTasks) { RunScheduleTasksTest("32_4", 32, 4); } -TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAlternateTasks) { +TEST_P(RasterBufferProviderPerfTest, ScheduleAlternateTasks) { RunScheduleAlternateTasksTest("1_0", 1, 0); RunScheduleAlternateTasksTest("32_0", 32, 0); RunScheduleAlternateTasksTest("1_1", 1, 1); @@ -440,7 +449,7 @@ TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAlternateTasks) { RunScheduleAlternateTasksTest("32_4", 32, 4); } -TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAndExecuteTasks) { +TEST_P(RasterBufferProviderPerfTest, ScheduleAndExecuteTasks) { RunScheduleAndExecuteTasksTest("1_0", 1, 0); RunScheduleAndExecuteTasksTest("32_0", 32, 0); RunScheduleAndExecuteTasksTest("1_1", 1, 1); @@ -449,15 +458,16 @@ TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAndExecuteTasks) { RunScheduleAndExecuteTasksTest("32_4", 32, 4); } -INSTANTIATE_TEST_CASE_P(TileTaskWorkerPoolPerfTests, - TileTaskWorkerPoolPerfTest, - ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY, - TILE_TASK_WORKER_POOL_TYPE_ONE_COPY, - TILE_TASK_WORKER_POOL_TYPE_GPU, - TILE_TASK_WORKER_POOL_TYPE_BITMAP)); +INSTANTIATE_TEST_CASE_P(RasterBufferProviderPerfTests, + RasterBufferProviderPerfTest, + ::testing::Values(RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY, + RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY, + RASTER_BUFFER_PROVIDER_TYPE_GPU, + RASTER_BUFFER_PROVIDER_TYPE_BITMAP)); -class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase, - public testing::Test { +class RasterBufferProviderCommonPerfTest + : public RasterBufferProviderPerfTestBase, + public testing::Test { public: // Overridden from testing::Test: void SetUp() override { @@ -470,7 +480,7 @@ class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase, void RunBuildTileTaskGraphTest(const std::string& test_name, unsigned num_raster_tasks, unsigned num_image_decode_tasks) { - ImageDecodeTask::Vector image_decode_tasks; + TileTask::Vector image_decode_tasks; RasterTaskVector raster_tasks; CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks); CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks); @@ -490,7 +500,7 @@ class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase, } }; -TEST_F(TileTaskWorkerPoolCommonPerfTest, BuildTileTaskGraph) { +TEST_F(RasterBufferProviderCommonPerfTest, BuildTileTaskGraph) { RunBuildTileTaskGraphTest("1_0", 1, 0); RunBuildTileTaskGraphTest("32_0", 32, 0); RunBuildTileTaskGraphTest("1_1", 1, 1); diff --git a/chromium/cc/raster/tile_task_worker_pool_unittest.cc b/chromium/cc/raster/raster_buffer_provider_unittest.cc index f7613856351..ffdb710b0e4 100644 --- a/chromium/cc/raster/tile_task_worker_pool_unittest.cc +++ b/chromium/cc/raster/raster_buffer_provider_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/raster/tile_task_worker_pool.h" +#include "cc/raster/raster_buffer_provider.h" #include <stddef.h> #include <stdint.h> @@ -14,17 +14,16 @@ #include "base/cancelable_callback.h" #include "base/location.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/base/unique_notifier.h" -#include "cc/raster/bitmap_tile_task_worker_pool.h" +#include "cc/raster/bitmap_raster_buffer_provider.h" +#include "cc/raster/gpu_raster_buffer_provider.h" #include "cc/raster/gpu_rasterizer.h" -#include "cc/raster/gpu_tile_task_worker_pool.h" -#include "cc/raster/one_copy_tile_task_worker_pool.h" -#include "cc/raster/raster_buffer.h" +#include "cc/raster/one_copy_raster_buffer_provider.h" #include "cc/raster/synchronous_task_graph_runner.h" -#include "cc/raster/tile_task_runner.h" -#include "cc/raster/zero_copy_tile_task_worker_pool.h" +#include "cc/raster/zero_copy_raster_buffer_provider.h" #include "cc/resources/resource_pool.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_resource.h" @@ -35,6 +34,7 @@ #include "cc/test/test_gpu_memory_buffer_manager.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" +#include "cc/tiles/tile_task_manager.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,21 +44,21 @@ namespace { const size_t kMaxBytesPerCopyOperation = 1000U; const size_t kMaxStagingBuffers = 32U; -enum TileTaskWorkerPoolType { - TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY, - TILE_TASK_WORKER_POOL_TYPE_ONE_COPY, - TILE_TASK_WORKER_POOL_TYPE_GPU, - TILE_TASK_WORKER_POOL_TYPE_BITMAP +enum RasterBufferProviderType { + RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY, + RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY, + RASTER_BUFFER_PROVIDER_TYPE_GPU, + RASTER_BUFFER_PROVIDER_TYPE_BITMAP }; -class TestRasterTaskImpl : public RasterTask { +class TestRasterTaskImpl : public TileTask { public: typedef base::Callback<void(bool was_canceled)> Reply; TestRasterTaskImpl(const Resource* resource, const Reply& reply, - ImageDecodeTask::Vector* dependencies) - : RasterTask(dependencies), + TileTask::Vector* dependencies) + : TileTask(true, dependencies), resource_(resource), reply_(reply), raster_source_(FakeRasterSource::CreateFilled(gfx::Size(1, 1))) {} @@ -72,14 +72,14 @@ class TestRasterTaskImpl : public RasterTask { } // Overridden from TileTask: - void ScheduleOnOriginThread(TileTaskClient* client) override { + void ScheduleOnOriginThread(RasterBufferProvider* provider) override { // 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); + raster_buffer_ = provider->AcquireBufferForRaster(resource_, 0, 0); } - void CompleteOnOriginThread(TileTaskClient* client) override { - client->ReleaseBufferForRaster(std::move(raster_buffer_)); - reply_.Run(!HasFinishedRunning()); + void CompleteOnOriginThread(RasterBufferProvider* provider) override { + provider->ReleaseBufferForRaster(std::move(raster_buffer_)); + reply_.Run(!state().IsFinished()); } protected: @@ -88,7 +88,7 @@ class TestRasterTaskImpl : public RasterTask { private: const Resource* resource_; const Reply reply_; - scoped_ptr<RasterBuffer> raster_buffer_; + std::unique_ptr<RasterBuffer> raster_buffer_; scoped_refptr<RasterSource> raster_source_; DISALLOW_COPY_AND_ASSIGN(TestRasterTaskImpl); @@ -99,7 +99,7 @@ class BlockingTestRasterTaskImpl : public TestRasterTaskImpl { BlockingTestRasterTaskImpl(const Resource* resource, const Reply& reply, base::Lock* lock, - ImageDecodeTask::Vector* dependencies) + TileTask::Vector* dependencies) : TestRasterTaskImpl(resource, reply, dependencies), lock_(lock) {} // Overridden from Task: @@ -117,76 +117,75 @@ class BlockingTestRasterTaskImpl : public TestRasterTaskImpl { DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterTaskImpl); }; -class TileTaskWorkerPoolTest - : public testing::TestWithParam<TileTaskWorkerPoolType> { +class RasterBufferProviderTest + : public testing::TestWithParam<RasterBufferProviderType> { public: struct RasterTaskResult { unsigned id; bool canceled; }; - typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector; + typedef std::vector<scoped_refptr<TileTask>> RasterTaskVector; enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL }; - TileTaskWorkerPoolTest() + RasterBufferProviderTest() : context_provider_(TestContextProvider::Create()), worker_context_provider_(TestContextProvider::CreateWorker()), all_tile_tasks_finished_( - base::ThreadTaskRunnerHandle::Get() - .get(), - base::Bind(&TileTaskWorkerPoolTest::AllTileTasksFinished, + base::ThreadTaskRunnerHandle::Get().get(), + base::Bind(&RasterBufferProviderTest::AllTileTasksFinished, base::Unretained(this))), timeout_seconds_(5), timed_out_(false) {} // Overridden from testing::Test: void SetUp() override { + std::unique_ptr<RasterBufferProvider> raster_buffer_provider; switch (GetParam()) { - case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY: + case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY: Create3dOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create( - base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_, + raster_buffer_provider = ZeroCopyRasterBufferProvider::Create( resource_provider_.get(), PlatformColor::BestTextureFormat()); break; - case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY: + case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY: Create3dOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create( - base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_, - context_provider_.get(), resource_provider_.get(), - kMaxBytesPerCopyOperation, false, kMaxStagingBuffers, - PlatformColor::BestTextureFormat()); + raster_buffer_provider = OneCopyRasterBufferProvider::Create( + base::ThreadTaskRunnerHandle::Get().get(), context_provider_.get(), + resource_provider_.get(), kMaxBytesPerCopyOperation, false, + kMaxStagingBuffers, PlatformColor::BestTextureFormat()); break; - case TILE_TASK_WORKER_POOL_TYPE_GPU: + case RASTER_BUFFER_PROVIDER_TYPE_GPU: Create3dOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create( - base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_, + raster_buffer_provider = GpuRasterBufferProvider::Create( context_provider_.get(), resource_provider_.get(), false, 0); break; - case TILE_TASK_WORKER_POOL_TYPE_BITMAP: + case RASTER_BUFFER_PROVIDER_TYPE_BITMAP: CreateSoftwareOutputSurfaceAndResourceProvider(); - tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create( - base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_, - resource_provider_.get()); + raster_buffer_provider = + BitmapRasterBufferProvider::Create(resource_provider_.get()); break; } - DCHECK(tile_task_worker_pool_); + DCHECK(raster_buffer_provider); + + tile_task_manager_ = TileTaskManagerImpl::Create( + std::move(raster_buffer_provider), &task_graph_runner_); } void TearDown() override { - tile_task_worker_pool_->AsTileTaskRunner()->Shutdown(); - tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks(); + tile_task_manager_->Shutdown(); + tile_task_manager_->CheckForCompletedTasks(); } void AllTileTasksFinished() { - tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks(); + tile_task_manager_->CheckForCompletedTasks(); base::MessageLoop::current()->QuitWhenIdle(); } void RunMessageLoopUntilAllTasksHaveCompleted() { task_graph_runner_.RunUntilIdle(); - tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks(); + tile_task_manager_->CheckForCompletedTasks(); } void ScheduleTasks() { @@ -200,20 +199,20 @@ class TileTaskWorkerPoolTest 0 /* dependencies */); } - tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&graph_); + tile_task_manager_->ScheduleTasks(&graph_); } void AppendTask(unsigned id, const gfx::Size& size) { - scoped_ptr<ScopedResource> resource( + std::unique_ptr<ScopedResource> resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); const Resource* const_resource = resource.get(); - ImageDecodeTask::Vector empty; + TileTask::Vector empty; tasks_.push_back(new TestRasterTaskImpl( const_resource, - base::Bind(&TileTaskWorkerPoolTest::OnTaskCompleted, + base::Bind(&RasterBufferProviderTest::OnTaskCompleted, base::Unretained(this), base::Passed(&resource), id), &empty)); } @@ -223,16 +222,16 @@ class TileTaskWorkerPoolTest void AppendBlockingTask(unsigned id, base::Lock* lock) { const gfx::Size size(1, 1); - scoped_ptr<ScopedResource> resource( + std::unique_ptr<ScopedResource> resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); const Resource* const_resource = resource.get(); - ImageDecodeTask::Vector empty; + TileTask::Vector empty; tasks_.push_back(new BlockingTestRasterTaskImpl( const_resource, - base::Bind(&TileTaskWorkerPoolTest::OnTaskCompleted, + base::Bind(&RasterBufferProviderTest::OnTaskCompleted, base::Unretained(this), base::Passed(&resource), id), lock, &empty)); } @@ -262,16 +261,15 @@ class TileTaskWorkerPoolTest void CreateSoftwareOutputSurfaceAndResourceProvider() { output_surface_ = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = FakeResourceProvider::Create( output_surface_.get(), &shared_bitmap_manager_, nullptr); } - void OnTaskCompleted( - scoped_ptr<ScopedResource> resource, - unsigned id, - bool was_canceled) { + void OnTaskCompleted(std::unique_ptr<ScopedResource> resource, + unsigned id, + bool was_canceled) { RasterTaskResult result; result.id = id; result.canceled = was_canceled; @@ -287,9 +285,9 @@ class TileTaskWorkerPoolTest scoped_refptr<TestContextProvider> context_provider_; scoped_refptr<TestContextProvider> worker_context_provider_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> output_surface_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_; + std::unique_ptr<FakeOutputSurface> output_surface_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<TileTaskManager> tile_task_manager_; TestGpuMemoryBufferManager gpu_memory_buffer_manager_; TestSharedBitmapManager shared_bitmap_manager_; SynchronousTaskGraphRunner task_graph_runner_; @@ -302,7 +300,7 @@ class TileTaskWorkerPoolTest TaskGraph graph_; }; -TEST_P(TileTaskWorkerPoolTest, Basic) { +TEST_P(RasterBufferProviderTest, Basic) { AppendTask(0u); AppendTask(1u); ScheduleTasks(); @@ -314,8 +312,8 @@ TEST_P(TileTaskWorkerPoolTest, Basic) { EXPECT_FALSE(completed_tasks()[1].canceled); } -TEST_P(TileTaskWorkerPoolTest, FailedMapResource) { - if (GetParam() == TILE_TASK_WORKER_POOL_TYPE_BITMAP) +TEST_P(RasterBufferProviderTest, FailedMapResource) { + if (GetParam() == RASTER_BUFFER_PROVIDER_TYPE_BITMAP) return; TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d(); @@ -331,7 +329,7 @@ TEST_P(TileTaskWorkerPoolTest, FailedMapResource) { // This test checks that replacing a pending raster task with another does // not prevent the DidFinishRunningTileTasks notification from being sent. -TEST_P(TileTaskWorkerPoolTest, FalseThrottling) { +TEST_P(RasterBufferProviderTest, FalseThrottling) { base::Lock lock; // Schedule a task that is prevented from completing with a lock. @@ -353,7 +351,7 @@ TEST_P(TileTaskWorkerPoolTest, FalseThrottling) { RunMessageLoopUntilAllTasksHaveCompleted(); } -TEST_P(TileTaskWorkerPoolTest, LostContext) { +TEST_P(RasterBufferProviderTest, LostContext) { LoseContext(output_surface_->context_provider()); LoseContext(output_surface_->worker_context_provider()); @@ -368,12 +366,12 @@ TEST_P(TileTaskWorkerPoolTest, LostContext) { EXPECT_FALSE(completed_tasks()[1].canceled); } -INSTANTIATE_TEST_CASE_P(TileTaskWorkerPoolTests, - TileTaskWorkerPoolTest, - ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY, - TILE_TASK_WORKER_POOL_TYPE_ONE_COPY, - TILE_TASK_WORKER_POOL_TYPE_GPU, - TILE_TASK_WORKER_POOL_TYPE_BITMAP)); +INSTANTIATE_TEST_CASE_P(RasterBufferProviderTests, + RasterBufferProviderTest, + ::testing::Values(RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY, + RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY, + RASTER_BUFFER_PROVIDER_TYPE_GPU, + RASTER_BUFFER_PROVIDER_TYPE_BITMAP)); } // namespace } // namespace cc diff --git a/chromium/cc/raster/scoped_gpu_raster.h b/chromium/cc/raster/scoped_gpu_raster.h index 274772c0dd6..3d9083bbf68 100644 --- a/chromium/cc/raster/scoped_gpu_raster.h +++ b/chromium/cc/raster/scoped_gpu_raster.h @@ -5,9 +5,10 @@ #ifndef CC_RASTER_SCOPED_GPU_RASTER_H_ #define CC_RASTER_SCOPED_GPU_RASTER_H_ +#include <memory> + #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/context_provider.h" diff --git a/chromium/cc/raster/scoped_gpu_raster_unittest.cc b/chromium/cc/raster/scoped_gpu_raster_unittest.cc index 7ffb464176d..0451d412fc2 100644 --- a/chromium/cc/raster/scoped_gpu_raster_unittest.cc +++ b/chromium/cc/raster/scoped_gpu_raster_unittest.cc @@ -24,7 +24,7 @@ TEST(ScopedGpuRasterTest, RestoresUnpackAlignment) { EXPECT_EQ(4, unpack_alignment); { - scoped_ptr<ScopedGpuRaster> scoped_gpu_raster( + std::unique_ptr<ScopedGpuRaster> scoped_gpu_raster( new ScopedGpuRaster(provider.get())); gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1); gl->GetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment); diff --git a/chromium/cc/raster/single_thread_task_graph_runner.cc b/chromium/cc/raster/single_thread_task_graph_runner.cc index ba879af6cb1..56ae382e720 100644 --- a/chromium/cc/raster/single_thread_task_graph_runner.cc +++ b/chromium/cc/raster/single_thread_task_graph_runner.cc @@ -148,17 +148,11 @@ bool SingleThreadTaskGraphRunner::RunTaskWithLockAcquired() { auto prioritized_task = work_queue_.GetNextTaskToRun(category); Task* task = prioritized_task.task; - // Call WillRun() before releasing |lock_| and running task. - task->WillRun(); - { base::AutoUnlock unlock(lock_); task->RunOnWorkerThread(); } - // This will mark task as finished running. - task->DidRun(); - work_queue_.CompleteTask(prioritized_task); // If namespace has finished running all tasks, wake up origin thread. diff --git a/chromium/cc/raster/single_thread_task_graph_runner.h b/chromium/cc/raster/single_thread_task_graph_runner.h index 3e8dec076e0..a8609cb25c0 100644 --- a/chromium/cc/raster/single_thread_task_graph_runner.h +++ b/chromium/cc/raster/single_thread_task_graph_runner.h @@ -5,7 +5,8 @@ #ifndef CC_RASTER_SINGLE_THREAD_TASK_GRAPH_RUNNER_H_ #define CC_RASTER_SINGLE_THREAD_TASK_GRAPH_RUNNER_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "base/synchronization/condition_variable.h" #include "base/threading/simple_thread.h" #include "cc/raster/task_graph_runner.h" @@ -43,7 +44,7 @@ class CC_EXPORT SingleThreadTaskGraphRunner // Returns true if there was a task to run. bool RunTaskWithLockAcquired(); - scoped_ptr<base::SimpleThread> thread_; + std::unique_ptr<base::SimpleThread> thread_; // Lock to exclusively access all the following members that are used to // implement the TaskRunner interfaces. diff --git a/chromium/cc/raster/staging_buffer_pool.cc b/chromium/cc/raster/staging_buffer_pool.cc index fd4c930eaf7..cb14f8224ba 100644 --- a/chromium/cc/raster/staging_buffer_pool.cc +++ b/chromium/cc/raster/staging_buffer_pool.cc @@ -4,8 +4,11 @@ #include "cc/raster/staging_buffer_pool.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "cc/base/container_util.h" #include "cc/debug/traced_value.h" @@ -118,12 +121,12 @@ void StagingBuffer::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, } // static -scoped_ptr<StagingBufferPool> StagingBufferPool::Create( +std::unique_ptr<StagingBufferPool> StagingBufferPool::Create( base::SequencedTaskRunner* task_runner, ResourceProvider* resource_provider, bool use_partial_raster, int max_staging_buffer_usage_in_bytes) { - return make_scoped_ptr<StagingBufferPool>( + return base::WrapUnique( new StagingBufferPool(task_runner, resource_provider, use_partial_raster, max_staging_buffer_usage_in_bytes)); } @@ -164,7 +167,7 @@ void StagingBufferPool::Shutdown() { } void StagingBufferPool::ReleaseStagingBuffer( - scoped_ptr<StagingBuffer> staging_buffer) { + std::unique_ptr<StagingBuffer> staging_buffer) { base::AutoLock lock(lock_); staging_buffer->last_usage = base::TimeTicks::Now(); @@ -181,7 +184,7 @@ bool StagingBufferPool::OnMemoryDump( for (const auto* buffer : buffers_) { auto in_free_buffers = std::find_if(free_buffers_.begin(), free_buffers_.end(), - [buffer](const scoped_ptr<StagingBuffer>& b) { + [buffer](const std::unique_ptr<StagingBuffer>& b) { return b.get() == buffer; }); buffer->OnMemoryDump(pmd, buffer->format, @@ -233,12 +236,12 @@ void StagingBufferPool::MarkStagingBufferAsBusy( free_staging_buffer_usage_in_bytes_ -= buffer_usage_in_bytes; } -scoped_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer( +std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer( const Resource* resource, uint64_t previous_content_id) { base::AutoLock lock(lock_); - scoped_ptr<StagingBuffer> staging_buffer; + std::unique_ptr<StagingBuffer> staging_buffer; ContextProvider* context_provider = resource_provider_->output_surface()->worker_context_provider(); @@ -287,7 +290,7 @@ scoped_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer( if (use_partial_raster_ && previous_content_id) { StagingBufferDeque::iterator it = std::find_if( free_buffers_.begin(), free_buffers_.end(), - [previous_content_id](const scoped_ptr<StagingBuffer>& buffer) { + [previous_content_id](const std::unique_ptr<StagingBuffer>& buffer) { return buffer->content_id == previous_content_id; }); if (it != free_buffers_.end()) { @@ -301,7 +304,7 @@ scoped_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer( if (!staging_buffer) { StagingBufferDeque::iterator it = std::find_if(free_buffers_.begin(), free_buffers_.end(), - [resource](const scoped_ptr<StagingBuffer>& buffer) { + [resource](const std::unique_ptr<StagingBuffer>& buffer) { return buffer->size == resource->size() && buffer->format == resource->format(); }); @@ -314,7 +317,7 @@ scoped_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer( // Create new staging buffer if necessary. if (!staging_buffer) { - staging_buffer = make_scoped_ptr( + staging_buffer = base::WrapUnique( new StagingBuffer(resource->size(), resource->format())); AddStagingBuffer(staging_buffer.get(), resource->format()); } diff --git a/chromium/cc/raster/staging_buffer_pool.h b/chromium/cc/raster/staging_buffer_pool.h index 1b3f04604e2..14818b4b426 100644 --- a/chromium/cc/raster/staging_buffer_pool.h +++ b/chromium/cc/raster/staging_buffer_pool.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <deque> +#include <memory> #include <set> #include "base/macros.h" @@ -40,7 +41,7 @@ struct StagingBuffer { const gfx::Size size; const ResourceFormat format; - scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; base::TimeTicks last_usage; unsigned texture_id; unsigned image_id; @@ -53,7 +54,7 @@ class CC_EXPORT StagingBufferPool public: ~StagingBufferPool() final; - static scoped_ptr<StagingBufferPool> Create( + static std::unique_ptr<StagingBufferPool> Create( base::SequencedTaskRunner* task_runner, ResourceProvider* resource_provider, bool use_partial_raster, @@ -64,9 +65,10 @@ class CC_EXPORT StagingBufferPool bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) override; - scoped_ptr<StagingBuffer> AcquireStagingBuffer(const Resource* resource, - uint64_t previous_content_id); - void ReleaseStagingBuffer(scoped_ptr<StagingBuffer> staging_buffer); + std::unique_ptr<StagingBuffer> AcquireStagingBuffer( + const Resource* resource, + uint64_t previous_content_id); + void ReleaseStagingBuffer(std::unique_ptr<StagingBuffer> staging_buffer); private: StagingBufferPool(base::SequencedTaskRunner* task_runner, @@ -85,7 +87,8 @@ class CC_EXPORT StagingBufferPool void ReduceMemoryUsage(); void ReleaseBuffersNotUsedSince(base::TimeTicks time); - scoped_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue() const; + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue() + const; void StagingStateAsValueInto( base::trace_event::TracedValue* staging_state) const; @@ -97,7 +100,7 @@ class CC_EXPORT StagingBufferPool // |lock_| must be acquired when accessing the following members. using StagingBufferSet = std::set<const StagingBuffer*>; StagingBufferSet buffers_; - using StagingBufferDeque = std::deque<scoped_ptr<StagingBuffer>>; + using StagingBufferDeque = std::deque<std::unique_ptr<StagingBuffer>>; StagingBufferDeque free_buffers_; StagingBufferDeque busy_buffers_; const int max_staging_buffer_usage_in_bytes_; diff --git a/chromium/cc/raster/synchronous_task_graph_runner.cc b/chromium/cc/raster/synchronous_task_graph_runner.cc index 2f5055d87b1..8987ca1e57f 100644 --- a/chromium/cc/raster/synchronous_task_graph_runner.cc +++ b/chromium/cc/raster/synchronous_task_graph_runner.cc @@ -85,9 +85,7 @@ bool SynchronousTaskGraphRunner::RunTask() { auto prioritized_task = work_queue_.GetNextTaskToRun(category); Task* task = prioritized_task.task; - task->WillRun(); task->RunOnWorkerThread(); - task->DidRun(); work_queue_.CompleteTask(prioritized_task); diff --git a/chromium/cc/raster/synchronous_task_graph_runner.h b/chromium/cc/raster/synchronous_task_graph_runner.h index 65a7716cb5c..720c435cdff 100644 --- a/chromium/cc/raster/synchronous_task_graph_runner.h +++ b/chromium/cc/raster/synchronous_task_graph_runner.h @@ -27,6 +27,9 @@ class CC_EXPORT SynchronousTaskGraphRunner : public TaskGraphRunner { // Runs all pending tasks from all namespaces. void RunUntilIdle(); + // For test use only. + bool RunSingleTaskForTesting() { return RunTask(); } + private: // Returns true if there was a task to run. bool RunTask(); diff --git a/chromium/cc/raster/task.cc b/chromium/cc/raster/task.cc new file mode 100644 index 00000000000..4f26d12ba44 --- /dev/null +++ b/chromium/cc/raster/task.cc @@ -0,0 +1,85 @@ +// Copyright 2016 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/raster/task.h" + +#include "base/logging.h" + +namespace cc { + +TaskState::TaskState() : value_(Value::NEW) {} + +TaskState::~TaskState() { + DCHECK(value_ != Value::RUNNING) + << "Running task should never get destroyed."; + DCHECK(value_ == Value::NEW || value_ == Value::FINISHED || + value_ == Value::CANCELED) + << "Task, if scheduled, should get concluded either in FINISHED or " + "CANCELED state."; +} + +bool TaskState::IsScheduled() const { + return value_ == Value::SCHEDULED; +} + +bool TaskState::IsRunning() const { + return value_ == Value::RUNNING; +} +bool TaskState::IsFinished() const { + return value_ == Value::FINISHED; +} +bool TaskState::IsCanceled() const { + return value_ == Value::CANCELED; +} + +void TaskState::Reset() { + value_ = Value::NEW; +} + +void TaskState::DidSchedule() { + DCHECK(value_ == Value::NEW) + << "Task should be in NEW state to get scheduled."; + value_ = Value::SCHEDULED; +} + +void TaskState::DidStart() { + DCHECK(value_ == Value::SCHEDULED) + << "Task should be only in SCHEDULED state to start, that is it should " + "not be started or finished."; + value_ = Value::RUNNING; +} + +void TaskState::DidFinish() { + DCHECK(value_ == Value::RUNNING) + << "Task should be running and not finished earlier."; + value_ = Value::FINISHED; +} + +void TaskState::DidCancel() { + DCHECK(value_ == Value::NEW || value_ == Value::SCHEDULED) + << "Task should be scheduled and not running to get canceled."; + value_ = Value::CANCELED; +} + +Task::Task() {} + +Task::~Task() {} + +TaskGraph::TaskGraph() {} + +TaskGraph::TaskGraph(const TaskGraph& other) = default; + +TaskGraph::~TaskGraph() {} + +void TaskGraph::Swap(TaskGraph* other) { + nodes.swap(other->nodes); + edges.swap(other->edges); +} + +void TaskGraph::Reset() { + nodes.clear(); + edges.clear(); +} + +} // namespace cc diff --git a/chromium/cc/raster/task.h b/chromium/cc/raster/task.h new file mode 100644 index 00000000000..54bcf8b6b1a --- /dev/null +++ b/chromium/cc/raster/task.h @@ -0,0 +1,126 @@ +// Copyright 2016 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_RASTER_TASK_H_ +#define CC_RASTER_TASK_H_ + +#include <stdint.h> + +#include <vector> + +#include "base/memory/ref_counted.h" +#include "cc/base/cc_export.h" + +namespace cc { +class Task; + +// States to manage life cycle of a task. Task gets created with NEW state and +// concludes either in FINISHED or CANCELLED state. So possible life cycle +// paths for task are - +// NEW -> SCHEDULED -> RUNNING -> FINISHED +// NEW -> SCHEDULED -> CANCELED +class CC_EXPORT TaskState { + public: + bool IsScheduled() const; + bool IsRunning() const; + bool IsFinished() const; + bool IsCanceled() const; + + // Functions to change the state of task. These functions should be called + // only from TaskGraphWorkQueue where the life cycle of a task is decided or + // from tests. These functions are not thread-safe. Caller is responsible for + // thread safety. + void Reset(); // Sets state to NEW. + void DidSchedule(); + void DidStart(); + void DidFinish(); + void DidCancel(); + + private: + friend class Task; + + // Let only Task class create the TaskState. + TaskState(); + ~TaskState(); + + enum class Value : uint16_t { NEW, SCHEDULED, RUNNING, FINISHED, CANCELED }; + + Value value_; +}; + +// A task which can be run by a TaskGraphRunner. To run a Task, it should be +// inserted into a TaskGraph, which can then be scheduled on the +// TaskGraphRunner. +class CC_EXPORT Task : public base::RefCountedThreadSafe<Task> { + public: + typedef std::vector<scoped_refptr<Task>> Vector; + + TaskState& state() { return state_; } + + // Subclasses should implement this method. RunOnWorkerThread may be called + // on any thread, and subclasses are responsible for locking and thread + // safety. + virtual void RunOnWorkerThread() = 0; + + protected: + friend class base::RefCountedThreadSafe<Task>; + + Task(); + virtual ~Task(); + + private: + TaskState state_; +}; + +// A task dependency graph describes the order in which to execute a set +// of tasks. Dependencies are represented as edges. Each node is assigned +// a category, a priority and a run count that matches the number of +// dependencies. Priority range from 0 (most favorable scheduling) to UINT16_MAX +// (least favorable). Categories range from 0 to UINT16_MAX. It is up to the +// implementation and its consumer to determine the meaning (if any) of a +// category. A TaskGraphRunner implementation may chose to prioritize certain +// categories over others, regardless of the individual priorities of tasks. +struct CC_EXPORT TaskGraph { + struct Node { + typedef std::vector<Node> Vector; + + Node(Task* task, + uint16_t category, + uint16_t priority, + uint32_t dependencies) + : task(task), + category(category), + priority(priority), + dependencies(dependencies) {} + + Task* task; + uint16_t category; + uint16_t priority; + uint32_t dependencies; + }; + + struct Edge { + typedef std::vector<Edge> Vector; + + Edge(const Task* task, Task* dependent) + : task(task), dependent(dependent) {} + + const Task* task; + Task* dependent; + }; + + TaskGraph(); + TaskGraph(const TaskGraph& other); + ~TaskGraph(); + + void Swap(TaskGraph* other); + void Reset(); + + Node::Vector nodes; + Edge::Vector edges; +}; + +} // namespace cc + +#endif // CC_RASTER_TASK_H_ diff --git a/chromium/cc/raster/task_graph_runner.cc b/chromium/cc/raster/task_graph_runner.cc deleted file mode 100644 index 4f1af43ad43..00000000000 --- a/chromium/cc/raster/task_graph_runner.cc +++ /dev/null @@ -1,54 +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/raster/task_graph_runner.h" - -#include <algorithm> -#include <utility> - -#include "base/atomic_sequence_num.h" -#include "base/threading/thread_restrictions.h" -#include "base/trace_event/trace_event.h" - -namespace cc { - -Task::Task() : will_run_(false), did_run_(false) {} - -Task::~Task() { - DCHECK(!will_run_); -} - -void Task::WillRun() { - DCHECK(!will_run_); - DCHECK(!did_run_); - will_run_ = true; -} - -void Task::DidRun() { - DCHECK(will_run_); - will_run_ = false; - did_run_ = true; -} - -bool Task::HasFinishedRunning() const { - return did_run_; -} - -TaskGraph::TaskGraph() {} - -TaskGraph::TaskGraph(const TaskGraph& other) = default; - -TaskGraph::~TaskGraph() {} - -void TaskGraph::Swap(TaskGraph* other) { - nodes.swap(other->nodes); - edges.swap(other->edges); -} - -void TaskGraph::Reset() { - nodes.clear(); - edges.clear(); -} - -} // namespace cc diff --git a/chromium/cc/raster/task_graph_runner.h b/chromium/cc/raster/task_graph_runner.h index 23094ef5a7e..112124797ca 100644 --- a/chromium/cc/raster/task_graph_runner.h +++ b/chromium/cc/raster/task_graph_runner.h @@ -10,91 +10,16 @@ #include <algorithm> #include <map> +#include <memory> #include <vector> #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" +#include "cc/raster/task.h" namespace cc { -class TaskGraphRunner; - -// A task which can be run by a TaskGraphRunner. To run a Task, it should be -// inserted into a TaskGraph, which can then be scheduled on the -// TaskGraphRunner. -class CC_EXPORT Task : public base::RefCountedThreadSafe<Task> { - public: - typedef std::vector<scoped_refptr<Task>> Vector; - - // Subclasses should implement this method. RunOnWorkerThread may be called - // on any thread, and subclasses are responsible for locking and thread - // safety. - virtual void RunOnWorkerThread() = 0; - - void WillRun(); - void DidRun(); - bool HasFinishedRunning() const; - - protected: - friend class base::RefCountedThreadSafe<Task>; - - Task(); - virtual ~Task(); - - bool will_run_; - bool did_run_; -}; - -// A task dependency graph describes the order in which to execute a set -// of tasks. Dependencies are represented as edges. Each node is assigned -// a category, a priority and a run count that matches the number of -// dependencies. Priority range from 0 (most favorable scheduling) to UINT16_MAX -// (least favorable). Categories range from 0 to UINT16_MAX. It is up to the -// implementation and its consumer to determine the meaning (if any) of a -// category. A TaskGraphRunner implementation may chose to prioritize certain -// categories over others, regardless of the individual priorities of tasks. -struct CC_EXPORT TaskGraph { - struct Node { - typedef std::vector<Node> Vector; - - Node(Task* task, - uint16_t category, - uint16_t priority, - uint32_t dependencies) - : task(task), - category(category), - priority(priority), - dependencies(dependencies) {} - - Task* task; - uint16_t category; - uint16_t priority; - uint32_t dependencies; - }; - - struct Edge { - typedef std::vector<Edge> Vector; - - Edge(const Task* task, Task* dependent) - : task(task), dependent(dependent) {} - - const Task* task; - Task* dependent; - }; - - TaskGraph(); - TaskGraph(const TaskGraph& other); - ~TaskGraph(); - - void Swap(TaskGraph* other); - void Reset(); - - Node::Vector nodes; - Edge::Vector edges; -}; - // Opaque identifier that defines a namespace of tasks. class CC_EXPORT NamespaceToken { public: @@ -144,6 +69,8 @@ class CC_EXPORT NamespaceToken { // - A TaskGraphRunner that has a method Run() that runs each task. class CC_EXPORT TaskGraphRunner { public: + virtual ~TaskGraphRunner() {} + // Returns a unique token that can be used to pass a task graph to // ScheduleTasks(). Valid tokens are always nonzero. virtual NamespaceToken GetNamespaceToken() = 0; @@ -161,64 +88,6 @@ class CC_EXPORT TaskGraphRunner { // Collect all completed tasks in |completed_tasks|. virtual void CollectCompletedTasks(NamespaceToken token, Task::Vector* completed_tasks) = 0; - - protected: - virtual ~TaskGraphRunner() {} -}; - -// Helper class for iterating over all dependents of a task. -class DependentIterator { - public: - DependentIterator(TaskGraph* graph, const Task* task) - : graph_(graph), - task_(task), - current_index_(static_cast<size_t>(-1)), - current_node_(NULL) { - ++(*this); - } - - TaskGraph::Node& operator->() const { - DCHECK_LT(current_index_, graph_->edges.size()); - DCHECK_EQ(graph_->edges[current_index_].task, task_); - DCHECK(current_node_); - return *current_node_; - } - - TaskGraph::Node& operator*() const { - DCHECK_LT(current_index_, graph_->edges.size()); - DCHECK_EQ(graph_->edges[current_index_].task, task_); - DCHECK(current_node_); - return *current_node_; - } - - // Note: Performance can be improved by keeping edges sorted. - DependentIterator& operator++() { - // Find next dependency edge for |task_|. - do { - ++current_index_; - if (current_index_ == graph_->edges.size()) - return *this; - } while (graph_->edges[current_index_].task != task_); - - // Now find the node for the dependent of this edge. - TaskGraph::Node::Vector::iterator it = std::find_if( - graph_->nodes.begin(), graph_->nodes.end(), - [this](const TaskGraph::Node& node) { - return node.task == graph_->edges[current_index_].dependent; - }); - DCHECK(it != graph_->nodes.end()); - current_node_ = &(*it); - - return *this; - } - - operator bool() const { return current_index_ < graph_->edges.size(); } - - private: - TaskGraph* graph_; - const Task* task_; - size_t current_index_; - TaskGraph::Node* current_node_; }; } // namespace cc diff --git a/chromium/cc/raster/task_graph_runner_perftest.cc b/chromium/cc/raster/task_graph_runner_perftest.cc index f86bae571bf..a825f1b373a 100644 --- a/chromium/cc/raster/task_graph_runner_perftest.cc +++ b/chromium/cc/raster/task_graph_runner_perftest.cc @@ -5,10 +5,11 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/time/time.h" #include "cc/base/completion_event.h" #include "cc/debug/lap_timer.h" @@ -32,7 +33,7 @@ class PerfTaskImpl : public Task { // Overridden from Task: void RunOnWorkerThread() override {} - void Reset() { did_run_ = false; } + void Reset() { state().Reset(); } private: ~PerfTaskImpl() override {} @@ -49,7 +50,7 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Overridden from testing::Test: void SetUp() override { - task_graph_runner_ = make_scoped_ptr(new SynchronousTaskGraphRunner); + task_graph_runner_ = base::WrapUnique(new SynchronousTaskGraphRunner); namespace_token_ = task_graph_runner_->GetNamespaceToken(); } void TearDown() override { task_graph_runner_ = nullptr; } @@ -144,11 +145,15 @@ class TaskGraphRunnerPerfTest : public testing::Test { size_t count = 0; timer_.Reset(); do { + size_t current_version = count % kNumVersions; graph.Reset(); - BuildTaskGraph(top_level_tasks[count % kNumVersions], - tasks[count % kNumVersions], - leaf_tasks[count % kNumVersions], - &graph); + // Reset tasks as we are not letting them execute, they get cancelled + // when next ScheduleTasks() happens. + ResetTasks(&top_level_tasks[current_version]); + ResetTasks(&tasks[current_version]); + ResetTasks(&leaf_tasks[current_version]); + BuildTaskGraph(top_level_tasks[current_version], tasks[current_version], + leaf_tasks[current_version], &graph); task_graph_runner_->ScheduleTasks(namespace_token_, &graph); CollectCompletedTasks(&completed_tasks); completed_tasks.clear(); @@ -272,7 +277,7 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Test uses SynchronousTaskGraphRunner, as this implementation introduces // minimal additional complexity over the TaskGraphWorkQueue helpers. - scoped_ptr<SynchronousTaskGraphRunner> task_graph_runner_; + std::unique_ptr<SynchronousTaskGraphRunner> task_graph_runner_; NamespaceToken namespace_token_; LapTimer timer_; }; diff --git a/chromium/cc/raster/task_graph_work_queue.cc b/chromium/cc/raster/task_graph_work_queue.cc index 98413eee1a6..807539db8e4 100644 --- a/chromium/cc/raster/task_graph_work_queue.cc +++ b/chromium/cc/raster/task_graph_work_queue.cc @@ -43,6 +43,62 @@ class CompareTaskNamespacePriority { private: uint16_t category_; }; + +// Helper class for iterating over all dependents of a task. +class DependentIterator { + public: + DependentIterator(TaskGraph* graph, const Task* task) + : graph_(graph), + task_(task), + current_index_(static_cast<size_t>(-1)), + current_node_(NULL) { + ++(*this); + } + + TaskGraph::Node& operator->() const { + DCHECK_LT(current_index_, graph_->edges.size()); + DCHECK_EQ(graph_->edges[current_index_].task, task_); + DCHECK(current_node_); + return *current_node_; + } + + TaskGraph::Node& operator*() const { + DCHECK_LT(current_index_, graph_->edges.size()); + DCHECK_EQ(graph_->edges[current_index_].task, task_); + DCHECK(current_node_); + return *current_node_; + } + + // Note: Performance can be improved by keeping edges sorted. + DependentIterator& operator++() { + // Find next dependency edge for |task_|. + do { + ++current_index_; + if (current_index_ == graph_->edges.size()) + return *this; + } while (graph_->edges[current_index_].task != task_); + + // Now find the node for the dependent of this edge. + TaskGraph::Node::Vector::iterator it = std::find_if( + graph_->nodes.begin(), graph_->nodes.end(), + [this](const TaskGraph::Node& node) { + return node.task == graph_->edges[current_index_].dependent; + }); + DCHECK(it != graph_->nodes.end()); + current_node_ = &(*it); + + return *this; + } + + operator bool() const { return current_index_ < graph_->edges.size(); } + + private: + TaskGraph* graph_; + const Task* task_; + size_t current_index_; + TaskGraph::Node* current_node_; +}; + } // namespace TaskGraphWorkQueue::TaskNamespace::TaskNamespace() {} @@ -88,6 +144,11 @@ void TaskGraphWorkQueue::ScheduleTasks(NamespaceToken token, TaskGraph* graph) { }); if (old_it != task_namespace.graph.nodes.end()) { std::swap(*old_it, task_namespace.graph.nodes.back()); + // If old task is scheduled to run again and not yet started running, + // reset its state to initial state as it has to be inserted in new + // |ready_to_run_tasks|, where it gets scheduled. + if (node.task->state().IsScheduled()) + node.task->state().Reset(); task_namespace.graph.nodes.pop_back(); } @@ -96,7 +157,7 @@ void TaskGraphWorkQueue::ScheduleTasks(NamespaceToken token, TaskGraph* graph) { continue; // Skip if already finished running task. - if (node.task->HasFinishedRunning()) + if (node.task->state().IsFinished()) continue; // Skip if already running. @@ -107,6 +168,7 @@ void TaskGraphWorkQueue::ScheduleTasks(NamespaceToken token, TaskGraph* graph) { })) continue; + node.task->state().DidSchedule(); task_namespace.ready_to_run_tasks[node.category].push_back(PrioritizedTask( node.task, &task_namespace, node.category, node.priority)); } @@ -128,7 +190,7 @@ void TaskGraphWorkQueue::ScheduleTasks(NamespaceToken token, TaskGraph* graph) { TaskGraph::Node& node = *it; // Skip if already finished running task. - if (node.task->HasFinishedRunning()) + if (node.task->state().IsFinished()) continue; // Skip if already running. @@ -142,6 +204,7 @@ void TaskGraphWorkQueue::ScheduleTasks(NamespaceToken token, TaskGraph* graph) { DCHECK(std::find(task_namespace.completed_tasks.begin(), task_namespace.completed_tasks.end(), node.task) == task_namespace.completed_tasks.end()); + node.task->state().DidCancel(); task_namespace.completed_tasks.push_back(node.task); } @@ -202,6 +265,7 @@ TaskGraphWorkQueue::PrioritizedTask TaskGraphWorkQueue::GetNextTaskToRun( } // Add task to |running_tasks|. + task.task->state().DidStart(); task_namespace->running_tasks.push_back( std::make_pair(task.category, task.task)); @@ -236,6 +300,7 @@ void TaskGraphWorkQueue::CompleteTask(const PrioritizedTask& completed_task) { task_namespace->ready_to_run_tasks[dependent_node.category]; bool was_empty = ready_to_run_tasks.empty(); + dependent_node.task->state().DidSchedule(); ready_to_run_tasks.push_back( PrioritizedTask(dependent_node.task, task_namespace, dependent_node.category, dependent_node.priority)); @@ -270,6 +335,7 @@ void TaskGraphWorkQueue::CompleteTask(const PrioritizedTask& completed_task) { } // Finally add task to |completed_tasks_|. + task->state().DidFinish(); task_namespace->completed_tasks.push_back(task); } diff --git a/chromium/cc/raster/texture_compressor.cc b/chromium/cc/raster/texture_compressor.cc index b8992bb9eef..6aabf6792df 100644 --- a/chromium/cc/raster/texture_compressor.cc +++ b/chromium/cc/raster/texture_compressor.cc @@ -5,6 +5,7 @@ #include "cc/raster/texture_compressor.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "cc/raster/texture_compressor_etc1.h" #if defined(ARCH_CPU_X86_FAMILY) @@ -14,16 +15,16 @@ namespace cc { -scoped_ptr<TextureCompressor> TextureCompressor::Create(Format format) { +std::unique_ptr<TextureCompressor> TextureCompressor::Create(Format format) { switch (format) { case kFormatETC1: { #if defined(ARCH_CPU_X86_FAMILY) base::CPU cpu; if (cpu.has_sse2()) { - return make_scoped_ptr(new TextureCompressorETC1SSE()); + return base::WrapUnique(new TextureCompressorETC1SSE()); } #endif - return make_scoped_ptr(new TextureCompressorETC1()); + return base::WrapUnique(new TextureCompressorETC1()); } } diff --git a/chromium/cc/raster/texture_compressor.h b/chromium/cc/raster/texture_compressor.h index 95536bcb40c..36a5a8d5abb 100644 --- a/chromium/cc/raster/texture_compressor.h +++ b/chromium/cc/raster/texture_compressor.h @@ -7,8 +7,9 @@ #include <stdint.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" namespace cc { @@ -25,7 +26,7 @@ class CC_EXPORT TextureCompressor { kQualityHigh, }; - static scoped_ptr<TextureCompressor> Create(Format format); + static std::unique_ptr<TextureCompressor> Create(Format format); virtual ~TextureCompressor() {} virtual void Compress(const uint8_t* src, diff --git a/chromium/cc/raster/texture_compressor_etc1_unittest.cc b/chromium/cc/raster/texture_compressor_etc1_unittest.cc index dc90ebb5d2b..4857b692612 100644 --- a/chromium/cc/raster/texture_compressor_etc1_unittest.cc +++ b/chromium/cc/raster/texture_compressor_etc1_unittest.cc @@ -17,7 +17,7 @@ const int kImageChannels = 4; const int kImageSizeInBytes = kImageWidth * kImageHeight * kImageChannels; TEST(TextureCompressorETC1Test, Compress256x256Ratio) { - scoped_ptr<TextureCompressor> compressor = + std::unique_ptr<TextureCompressor> compressor = TextureCompressor::Create(TextureCompressor::kFormatETC1); uint8_t src[kImageSizeInBytes]; uint8_t dst[kImageSizeInBytes]; diff --git a/chromium/cc/raster/texture_compressor_perftest.cc b/chromium/cc/raster/texture_compressor_perftest.cc index 96ab60db221..99ccb60302b 100644 --- a/chromium/cc/raster/texture_compressor_perftest.cc +++ b/chromium/cc/raster/texture_compressor_perftest.cc @@ -77,7 +77,7 @@ class TextureCompressorPerfTest protected: LapTimer timer_; - scoped_ptr<TextureCompressor> compressor_; + std::unique_ptr<TextureCompressor> compressor_; uint8_t src_[kImageSizeInBytes]; uint8_t dst_[kImageSizeInBytes]; }; diff --git a/chromium/cc/raster/tile_task.cc b/chromium/cc/raster/tile_task.cc new file mode 100644 index 00000000000..4010640a03c --- /dev/null +++ b/chromium/cc/raster/tile_task.cc @@ -0,0 +1,56 @@ +// 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/raster/tile_task.h" + +#include "base/logging.h" + +namespace cc { + +TileTask::TileTask(bool supports_concurrent_execution) + : supports_concurrent_execution_(supports_concurrent_execution), + did_schedule_(false), + did_complete_(false) {} + +TileTask::TileTask(bool supports_concurrent_execution, + TileTask::Vector* dependencies) + : supports_concurrent_execution_(supports_concurrent_execution), + dependencies_(std::move(*dependencies)), + did_schedule_(false), + did_complete_(false) {} + +TileTask::~TileTask() { + DCHECK(!did_schedule_); + DCHECK(!state().IsFinished() || did_complete_); +} + +void TileTask::WillSchedule() { + DCHECK(!did_schedule_); +} + +void TileTask::DidSchedule() { + did_schedule_ = true; + did_complete_ = false; +} + +bool TileTask::HasBeenScheduled() const { + return did_schedule_; +} + +void TileTask::WillComplete() { + DCHECK(!did_complete_); +} + +void TileTask::DidComplete() { + DCHECK(did_schedule_); + DCHECK(!did_complete_); + did_schedule_ = false; + did_complete_ = true; +} + +bool TileTask::HasCompleted() const { + return did_complete_; +} + +} // namespace cc diff --git a/chromium/cc/raster/tile_task.h b/chromium/cc/raster/tile_task.h new file mode 100644 index 00000000000..7b0f84e44dd --- /dev/null +++ b/chromium/cc/raster/tile_task.h @@ -0,0 +1,52 @@ +// 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_RASTER_TILE_TASK_H_ +#define CC_RASTER_TILE_TASK_H_ + +#include <vector> + +#include "cc/raster/task.h" + +namespace cc { +class RasterBufferProvider; + +class CC_EXPORT TileTask : public Task { + public: + typedef std::vector<scoped_refptr<TileTask>> Vector; + + const TileTask::Vector& dependencies() const { return dependencies_; } + + // Indicates whether this TileTask can be run at the same time as other tasks + // in the task graph. If false, this task will be scheduled with + // TASK_CATEGORY_NONCONCURRENT_FOREGROUND. + bool supports_concurrent_execution() const { + return supports_concurrent_execution_; + } + + virtual void ScheduleOnOriginThread(RasterBufferProvider* provider) = 0; + virtual void CompleteOnOriginThread(RasterBufferProvider* provider) = 0; + + void WillSchedule(); + void DidSchedule(); + bool HasBeenScheduled() const; + + void WillComplete(); + void DidComplete(); + bool HasCompleted() const; + + protected: + explicit TileTask(bool supports_concurrent_execution); + TileTask(bool supports_concurrent_execution, TileTask::Vector* dependencies); + ~TileTask() override; + + const bool supports_concurrent_execution_; + TileTask::Vector dependencies_; + bool did_schedule_; + bool did_complete_; +}; + +} // namespace cc + +#endif // CC_RASTER_TILE_TASK_H_ diff --git a/chromium/cc/raster/tile_task_runner.cc b/chromium/cc/raster/tile_task_runner.cc deleted file mode 100644 index 50e8805d938..00000000000 --- a/chromium/cc/raster/tile_task_runner.cc +++ /dev/null @@ -1,79 +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/raster/tile_task_runner.h" -#include "cc/resources/platform_color.h" - -namespace cc { - -TileTask::TileTask() : did_schedule_(false), did_complete_(false) { -} - -TileTask::~TileTask() { - DCHECK(!did_schedule_); - DCHECK(!did_run_ || did_complete_); -} - -void TileTask::WillSchedule() { - DCHECK(!did_schedule_); -} - -void TileTask::DidSchedule() { - did_schedule_ = true; - did_complete_ = false; -} - -bool TileTask::HasBeenScheduled() const { - return did_schedule_; -} - -void TileTask::WillComplete() { - DCHECK(!did_complete_); -} - -void TileTask::DidComplete() { - DCHECK(did_schedule_); - DCHECK(!did_complete_); - did_schedule_ = false; - did_complete_ = true; -} - -bool TileTask::HasCompleted() const { - return did_complete_; -} - -ImageDecodeTask::ImageDecodeTask() { -} - -ImageDecodeTask::~ImageDecodeTask() { -} - -RasterTask::RasterTask(ImageDecodeTask::Vector* dependencies) { - dependencies_.swap(*dependencies); -} - -RasterTask::~RasterTask() { -} - -bool TileTaskRunner::ResourceFormatRequiresSwizzle(ResourceFormat format) { - switch (format) { - case RGBA_8888: - case BGRA_8888: - // Initialize resource using the preferred PlatformColor component - // order and swizzle in the shader instead of in software. - return !PlatformColor::SameComponentOrder(format); - case RGBA_4444: - case ETC1: - case ALPHA_8: - case LUMINANCE_8: - case RGB_565: - case RED_8: - case LUMINANCE_F16: - return false; - } - NOTREACHED(); - return false; -} - -} // namespace cc diff --git a/chromium/cc/raster/tile_task_runner.h b/chromium/cc/raster/tile_task_runner.h deleted file mode 100644 index 5e2f7fd1c96..00000000000 --- a/chromium/cc/raster/tile_task_runner.h +++ /dev/null @@ -1,115 +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_RASTER_TILE_TASK_RUNNER_H_ -#define CC_RASTER_TILE_TASK_RUNNER_H_ - -#include <stdint.h> - -#include <vector> - -#include "base/callback.h" -#include "cc/raster/task_graph_runner.h" -#include "cc/resources/resource_format.h" - -namespace cc { -class ImageDecodeTask; -class RasterTask; -class Resource; -class RasterBuffer; - -class CC_EXPORT TileTaskClient { - public: - virtual scoped_ptr<RasterBuffer> AcquireBufferForRaster( - const Resource* resource, - uint64_t resource_content_id, - uint64_t previous_content_id) = 0; - virtual void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) = 0; - - protected: - virtual ~TileTaskClient() {} -}; - -class CC_EXPORT TileTask : public Task { - public: - typedef std::vector<scoped_refptr<TileTask>> Vector; - - virtual void ScheduleOnOriginThread(TileTaskClient* client) = 0; - virtual void CompleteOnOriginThread(TileTaskClient* client) = 0; - - void WillSchedule(); - void DidSchedule(); - bool HasBeenScheduled() const; - - void WillComplete(); - void DidComplete(); - bool HasCompleted() const; - - protected: - TileTask(); - ~TileTask() override; - - bool did_schedule_; - bool did_complete_; -}; - -class CC_EXPORT ImageDecodeTask : public TileTask { - public: - typedef std::vector<scoped_refptr<ImageDecodeTask>> Vector; - - protected: - ImageDecodeTask(); - ~ImageDecodeTask() override; -}; - -class CC_EXPORT RasterTask : public TileTask { - public: - typedef std::vector<scoped_refptr<RasterTask>> Vector; - - const ImageDecodeTask::Vector& dependencies() const { return dependencies_; } - - protected: - explicit RasterTask(ImageDecodeTask::Vector* dependencies); - ~RasterTask() override; - - private: - ImageDecodeTask::Vector dependencies_; -}; - -// This interface can be used to schedule and run tile tasks. -// The client can call CheckForCompletedTasks() at any time to dispatch -// pending completion callbacks for all tasks that have finished running. -class CC_EXPORT TileTaskRunner { - public: - // Tells the worker pool to shutdown after canceling all previously scheduled - // tasks. Reply callbacks are still guaranteed to run when - // CheckForCompletedTasks() is called. - virtual void Shutdown() = 0; - - // Schedule running of tile tasks in |graph| and all dependencies. - // Previously scheduled tasks that are not in |graph| will be canceled unless - // already running. Once scheduled, reply callbacks are guaranteed to run for - // all tasks even if they later get canceled by another call to - // ScheduleTasks(). - virtual void ScheduleTasks(TaskGraph* graph) = 0; - - // Check for completed tasks and dispatch reply callbacks. - virtual void CheckForCompletedTasks() = 0; - - // Returns the format to use for the tiles. - virtual ResourceFormat GetResourceFormat(bool must_support_alpha) const = 0; - - // Determine if the resource requires swizzling. - virtual bool GetResourceRequiresSwizzle(bool must_support_alpha) const = 0; - - protected: - // Check if resource format matches output format. - static bool ResourceFormatRequiresSwizzle(ResourceFormat format); - - virtual ~TileTaskRunner() {} -}; - -} // namespace cc - -#endif // CC_RASTER_TILE_TASK_RUNNER_H_ diff --git a/chromium/cc/raster/tile_task_worker_pool.h b/chromium/cc/raster/tile_task_worker_pool.h deleted file mode 100644 index e56807f16e8..00000000000 --- a/chromium/cc/raster/tile_task_worker_pool.h +++ /dev/null @@ -1,55 +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. - -#ifndef CC_RASTER_TILE_TASK_WORKER_POOL_H_ -#define CC_RASTER_TILE_TASK_WORKER_POOL_H_ - -#include <stddef.h> - -#include "cc/playback/raster_source.h" -#include "cc/raster/tile_task_runner.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size.h" - -namespace base { -class SequencedTaskRunner; -} - -namespace cc { -class RenderingStatsInstrumentation; - -class CC_EXPORT TileTaskWorkerPool { - public: - TileTaskWorkerPool(); - virtual ~TileTaskWorkerPool(); - - // Utility function that can be used to call ::ScheduleOnOriginThread() for - // each task in |graph|. - static void ScheduleTasksOnOriginThread(TileTaskClient* client, - TaskGraph* graph); - - // Utility function that will create a temporary bitmap and copy pixels to - // |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, - size_t stride, - const RasterSource* raster_source, - const gfx::Rect& canvas_bitmap_rect, - const gfx::Rect& canvas_playback_rect, - float scale, - const RasterSource::PlaybackSettings& playback_settings); - - // Type-checking downcast routine. - virtual TileTaskRunner* AsTileTaskRunner() = 0; -}; - -} // namespace cc - -#endif // CC_RASTER_TILE_TASK_WORKER_POOL_H_ diff --git a/chromium/cc/raster/zero_copy_tile_task_worker_pool.cc b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc index da962333e1a..93e8d7e13f0 100644 --- a/chromium/cc/raster/zero_copy_tile_task_worker_pool.cc +++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc @@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/raster/zero_copy_tile_task_worker_pool.h" +#include "cc/raster/zero_copy_raster_buffer_provider.h" #include <stdint.h> #include <algorithm> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #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/buffer_format_util.h" @@ -44,11 +44,11 @@ class RasterBufferImpl : public RasterBuffer { bool rv = buffer->Map(); DCHECK(rv); DCHECK(buffer->memory(0)); - // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides. + // RasterBufferProvider::PlaybackToMemory only supports unsigned strides. DCHECK_GE(buffer->stride(0), 0); // TODO(danakj): Implement partial raster with raster_dirty_rect. - TileTaskWorkerPool::PlaybackToMemory( + RasterBufferProvider::PlaybackToMemory( buffer->memory(0), resource_->format(), resource_->size(), buffer->stride(0), raster_source, raster_full_rect, raster_full_rect, scale, playback_settings); @@ -65,66 +65,41 @@ class RasterBufferImpl : public RasterBuffer { } // namespace // static -scoped_ptr<TileTaskWorkerPool> ZeroCopyTileTaskWorkerPool::Create( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, +std::unique_ptr<RasterBufferProvider> ZeroCopyRasterBufferProvider::Create( ResourceProvider* resource_provider, ResourceFormat preferred_tile_format) { - return make_scoped_ptr<TileTaskWorkerPool>( - new ZeroCopyTileTaskWorkerPool(task_runner, task_graph_runner, - resource_provider, preferred_tile_format)); + return base::WrapUnique<RasterBufferProvider>( + new ZeroCopyRasterBufferProvider(resource_provider, + preferred_tile_format)); } -ZeroCopyTileTaskWorkerPool::ZeroCopyTileTaskWorkerPool( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, +ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider( ResourceProvider* resource_provider, ResourceFormat preferred_tile_format) - : task_runner_(task_runner), - task_graph_runner_(task_graph_runner), - namespace_token_(task_graph_runner->GetNamespaceToken()), - resource_provider_(resource_provider), + : resource_provider_(resource_provider), preferred_tile_format_(preferred_tile_format) {} -ZeroCopyTileTaskWorkerPool::~ZeroCopyTileTaskWorkerPool() { -} +ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() {} -TileTaskRunner* ZeroCopyTileTaskWorkerPool::AsTileTaskRunner() { - return this; +std::unique_ptr<RasterBuffer> +ZeroCopyRasterBufferProvider::AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) { + return base::WrapUnique<RasterBuffer>( + new RasterBufferImpl(resource_provider_, resource)); } -void ZeroCopyTileTaskWorkerPool::Shutdown() { - TRACE_EVENT0("cc", "ZeroCopyTileTaskWorkerPool::Shutdown"); - - TaskGraph empty; - task_graph_runner_->ScheduleTasks(namespace_token_, &empty); - task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); +void ZeroCopyRasterBufferProvider::ReleaseBufferForRaster( + std::unique_ptr<RasterBuffer> buffer) { + // Nothing to do here. RasterBufferImpl destructor cleans up after itself. } -void ZeroCopyTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) { - TRACE_EVENT0("cc", "ZeroCopyTileTaskWorkerPool::ScheduleTasks"); - - ScheduleTasksOnOriginThread(this, graph); - task_graph_runner_->ScheduleTasks(namespace_token_, graph); +void ZeroCopyRasterBufferProvider::OrderingBarrier() { + // No need to sync resources as this provider does not use GL context. } -void ZeroCopyTileTaskWorkerPool::CheckForCompletedTasks() { - TRACE_EVENT0("cc", "ZeroCopyTileTaskWorkerPool::CheckForCompletedTasks"); - - task_graph_runner_->CollectCompletedTasks(namespace_token_, - &completed_tasks_); - for (Task::Vector::const_iterator it = completed_tasks_.begin(); - it != completed_tasks_.end(); ++it) { - TileTask* task = static_cast<TileTask*>(it->get()); - - task->WillComplete(); - task->CompleteOnOriginThread(this); - task->DidComplete(); - } - completed_tasks_.clear(); -} - -ResourceFormat ZeroCopyTileTaskWorkerPool::GetResourceFormat( +ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat( bool must_support_alpha) const { if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) && (DoesResourceFormatSupportAlpha(preferred_tile_format_) || @@ -135,22 +110,11 @@ ResourceFormat ZeroCopyTileTaskWorkerPool::GetResourceFormat( return resource_provider_->best_texture_format(); } -bool ZeroCopyTileTaskWorkerPool::GetResourceRequiresSwizzle( +bool ZeroCopyRasterBufferProvider::GetResourceRequiresSwizzle( bool must_support_alpha) const { return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); } -scoped_ptr<RasterBuffer> ZeroCopyTileTaskWorkerPool::AcquireBufferForRaster( - const Resource* resource, - uint64_t resource_content_id, - uint64_t previous_content_id) { - return make_scoped_ptr<RasterBuffer>( - new RasterBufferImpl(resource_provider_, resource)); -} - -void ZeroCopyTileTaskWorkerPool::ReleaseBufferForRaster( - scoped_ptr<RasterBuffer> buffer) { - // Nothing to do here. RasterBufferImpl destructor cleans up after itself. -} +void ZeroCopyRasterBufferProvider::Shutdown() {} } // namespace cc diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.h b/chromium/cc/raster/zero_copy_raster_buffer_provider.h new file mode 100644 index 00000000000..f813a59b894 --- /dev/null +++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.h @@ -0,0 +1,59 @@ +// 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. + +#ifndef CC_RASTER_ZERO_COPY_RASTER_BUFFER_PROVIDER_H_ +#define CC_RASTER_ZERO_COPY_RASTER_BUFFER_PROVIDER_H_ + +#include <stdint.h> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "cc/raster/raster_buffer_provider.h" + +namespace base { +namespace trace_event { +class ConvertableToTraceFormat; +} +} + +namespace cc { +class ResourceProvider; + +class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider { + public: + ~ZeroCopyRasterBufferProvider() override; + + static std::unique_ptr<RasterBufferProvider> Create( + ResourceProvider* resource_provider, + ResourceFormat preferred_tile_format); + + // Overridden from RasterBufferProvider: + std::unique_ptr<RasterBuffer> AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) override; + void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override; + void OrderingBarrier() override; + ResourceFormat GetResourceFormat(bool must_support_alpha) const override; + bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; + void Shutdown() override; + + protected: + ZeroCopyRasterBufferProvider(ResourceProvider* resource_provider, + ResourceFormat preferred_tile_format); + + private: + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue() + const; + + ResourceProvider* resource_provider_; + ResourceFormat preferred_tile_format_; + + DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferProvider); +}; + +} // namespace cc + +#endif // CC_RASTER_ZERO_COPY_RASTER_BUFFER_PROVIDER_H_ diff --git a/chromium/cc/raster/zero_copy_tile_task_worker_pool.h b/chromium/cc/raster/zero_copy_tile_task_worker_pool.h deleted file mode 100644 index bc558d762ce..00000000000 --- a/chromium/cc/raster/zero_copy_tile_task_worker_pool.h +++ /dev/null @@ -1,77 +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. - -#ifndef CC_RASTER_ZERO_COPY_TILE_TASK_WORKER_POOL_H_ -#define CC_RASTER_ZERO_COPY_TILE_TASK_WORKER_POOL_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/values.h" -#include "cc/raster/tile_task_runner.h" -#include "cc/raster/tile_task_worker_pool.h" - -namespace base { -namespace trace_event { -class ConvertableToTraceFormat; -} -} - -namespace cc { -class ResourceProvider; - -class CC_EXPORT ZeroCopyTileTaskWorkerPool : public TileTaskWorkerPool, - public TileTaskRunner, - public TileTaskClient { - public: - ~ZeroCopyTileTaskWorkerPool() override; - - static scoped_ptr<TileTaskWorkerPool> Create( - base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider, - ResourceFormat preferred_tile_format); - - // Overridden from TileTaskWorkerPool: - TileTaskRunner* AsTileTaskRunner() override; - - // Overridden from TileTaskRunner: - void Shutdown() override; - void ScheduleTasks(TaskGraph* graph) override; - void CheckForCompletedTasks() override; - ResourceFormat GetResourceFormat(bool must_support_alpha) const override; - bool GetResourceRequiresSwizzle(bool must_support_alpha) const override; - - // Overridden from TileTaskClient: - scoped_ptr<RasterBuffer> AcquireBufferForRaster( - const Resource* resource, - uint64_t resource_content_id, - uint64_t previous_content_id) override; - void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override; - - protected: - ZeroCopyTileTaskWorkerPool(base::SequencedTaskRunner* task_runner, - TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider, - ResourceFormat preferred_tile_format); - - private: - scoped_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue() const; - - scoped_refptr<base::SequencedTaskRunner> task_runner_; - TaskGraphRunner* task_graph_runner_; - const NamespaceToken namespace_token_; - ResourceProvider* resource_provider_; - - ResourceFormat preferred_tile_format_; - - Task::Vector completed_tasks_; - - DISALLOW_COPY_AND_ASSIGN(ZeroCopyTileTaskWorkerPool); -}; - -} // namespace cc - -#endif // CC_RASTER_ZERO_COPY_TILE_TASK_WORKER_POOL_H_ diff --git a/chromium/cc/resources/memory_history.cc b/chromium/cc/resources/memory_history.cc index 29bad2a30b3..caf849807e9 100644 --- a/chromium/cc/resources/memory_history.cc +++ b/chromium/cc/resources/memory_history.cc @@ -6,11 +6,13 @@ #include <limits> +#include "base/memory/ptr_util.h" + namespace cc { // static -scoped_ptr<MemoryHistory> MemoryHistory::Create() { - return make_scoped_ptr(new MemoryHistory()); +std::unique_ptr<MemoryHistory> MemoryHistory::Create() { + return base::WrapUnique(new MemoryHistory()); } MemoryHistory::MemoryHistory() {} diff --git a/chromium/cc/resources/memory_history.h b/chromium/cc/resources/memory_history.h index cdcc46aafae..2a396485b36 100644 --- a/chromium/cc/resources/memory_history.h +++ b/chromium/cc/resources/memory_history.h @@ -8,8 +8,9 @@ #include <stddef.h> #include <stdint.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/debug/ring_buffer.h" @@ -18,7 +19,7 @@ namespace cc { // Maintains a history of memory for each frame. class MemoryHistory { public: - static scoped_ptr<MemoryHistory> Create(); + static std::unique_ptr<MemoryHistory> Create(); size_t HistorySize() const { return ring_buffer_.BufferSize(); } diff --git a/chromium/cc/resources/resource_format.cc b/chromium/cc/resources/resource_format.cc index ec553d8acbc..101aef484a6 100644 --- a/chromium/cc/resources/resource_format.cc +++ b/chromium/cc/resources/resource_format.cc @@ -9,21 +9,24 @@ namespace cc { -SkColorType ResourceFormatToSkColorType(ResourceFormat format) { +SkColorType ResourceFormatToClosestSkColorType(ResourceFormat format) { + // Use kN32_SkColorType if there is no corresponding SkColorType. switch (format) { case RGBA_4444: return kARGB_4444_SkColorType; case RGBA_8888: case BGRA_8888: return kN32_SkColorType; - case ETC1: case ALPHA_8: - case LUMINANCE_8: + return kAlpha_8_SkColorType; case RGB_565: + return kRGB_565_SkColorType; + case LUMINANCE_8: + return kGray_8_SkColorType; + case ETC1: case RED_8: case LUMINANCE_F16: - NOTREACHED(); - break; + return kN32_SkColorType; } NOTREACHED(); return kN32_SkColorType; diff --git a/chromium/cc/resources/resource_format.h b/chromium/cc/resources/resource_format.h index 5266f31fe72..901632c04cc 100644 --- a/chromium/cc/resources/resource_format.h +++ b/chromium/cc/resources/resource_format.h @@ -7,7 +7,7 @@ #include "base/logging.h" #include "cc/base/cc_export.h" -#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkImageInfo.h" #include "ui/gfx/gpu_memory_buffer.h" // TODO(prashant.n): Including third_party/khronos/GLES2/gl2.h causes @@ -31,7 +31,7 @@ enum ResourceFormat { RESOURCE_FORMAT_MAX = LUMINANCE_F16, }; -SkColorType ResourceFormatToSkColorType(ResourceFormat format); +SkColorType ResourceFormatToClosestSkColorType(ResourceFormat format); CC_EXPORT int BitsPerPixel(ResourceFormat format); CC_EXPORT GLenum GLDataType(ResourceFormat format); diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc index 374b7178bc4..38ec99d227e 100644 --- a/chromium/cc/resources/resource_pool.cc +++ b/chromium/cc/resources/resource_pool.cc @@ -12,7 +12,7 @@ #include "base/format_macros.h" #include "base/strings/stringprintf.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "cc/base/container_util.h" #include "cc/resources/resource_provider.h" @@ -121,7 +121,7 @@ Resource* ResourcePool::AcquireResource(const gfx::Size& size, return resource; } - scoped_ptr<PoolResource> pool_resource = + std::unique_ptr<PoolResource> pool_resource = PoolResource::Create(resource_provider_); if (use_gpu_memory_buffers_) { @@ -147,11 +147,11 @@ Resource* ResourcePool::AcquireResource(const gfx::Size& size, Resource* ResourcePool::TryAcquireResourceWithContentId(uint64_t content_id) { DCHECK(content_id); - auto it = - std::find_if(unused_resources_.begin(), unused_resources_.end(), - [content_id](const scoped_ptr<PoolResource>& pool_resource) { - return pool_resource->content_id() == content_id; - }); + auto it = std::find_if( + unused_resources_.begin(), unused_resources_.end(), + [content_id](const std::unique_ptr<PoolResource>& pool_resource) { + return pool_resource->content_id() == content_id; + }); if (it == unused_resources_.end()) return nullptr; @@ -185,19 +185,19 @@ void ResourcePool::ReleaseResource(Resource* resource, uint64_t content_id) { // Maybe this is a double free - see if the resource exists in our busy // list. - auto found_busy = - std::find_if(busy_resources_.begin(), busy_resources_.end(), - [resource](const scoped_ptr<PoolResource>& busy_resource) { - return busy_resource->id() == resource->id(); - }); + auto found_busy = std::find_if( + busy_resources_.begin(), busy_resources_.end(), + [resource](const std::unique_ptr<PoolResource>& busy_resource) { + return busy_resource->id() == resource->id(); + }); CHECK(found_busy == busy_resources_.end()); // Also check if the resource exists in our unused resources list. - auto found_unused = - std::find_if(unused_resources_.begin(), unused_resources_.end(), - [resource](const scoped_ptr<PoolResource>& pool_resource) { - return pool_resource->id() == resource->id(); - }); + auto found_unused = std::find_if( + unused_resources_.begin(), unused_resources_.end(), + [resource](const std::unique_ptr<PoolResource>& pool_resource) { + return pool_resource->id() == resource->id(); + }); CHECK(found_unused == unused_resources_.end()); // Resource doesn't exist in any of our lists. CHECK. @@ -256,7 +256,7 @@ bool ResourcePool::ResourceUsageTooHigh() { return false; } -void ResourcePool::DeleteResource(scoped_ptr<PoolResource> resource) { +void ResourcePool::DeleteResource(std::unique_ptr<PoolResource> resource) { size_t resource_bytes = ResourceUtil::UncheckedSizeInBytes<size_t>( resource->size(), resource->format()); total_memory_usage_bytes_ -= resource_bytes; @@ -281,7 +281,8 @@ void ResourcePool::CheckBusyResources() { } } -void ResourcePool::DidFinishUsingResource(scoped_ptr<PoolResource> resource) { +void ResourcePool::DidFinishUsingResource( + std::unique_ptr<PoolResource> resource) { unused_resources_.push_front(std::move(resource)); } diff --git a/chromium/cc/resources/resource_pool.h b/chromium/cc/resources/resource_pool.h index df958469440..74262dedcf9 100644 --- a/chromium/cc/resources/resource_pool.h +++ b/chromium/cc/resources/resource_pool.h @@ -10,9 +10,10 @@ #include <deque> #include <map> +#include <memory> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/trace_event/memory_dump_provider.h" #include "cc/base/cc_export.h" #include "cc/output/renderer.h" @@ -24,17 +25,17 @@ namespace cc { class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider { public: - static scoped_ptr<ResourcePool> CreateForGpuMemoryBufferResources( + static std::unique_ptr<ResourcePool> CreateForGpuMemoryBufferResources( ResourceProvider* resource_provider, base::SingleThreadTaskRunner* task_runner) { - return make_scoped_ptr( + return base::WrapUnique( new ResourcePool(resource_provider, task_runner, true)); } - static scoped_ptr<ResourcePool> Create( + static std::unique_ptr<ResourcePool> Create( ResourceProvider* resource_provider, base::SingleThreadTaskRunner* task_runner) { - return make_scoped_ptr( + return base::WrapUnique( new ResourcePool(resource_provider, task_runner, false)); } @@ -80,9 +81,9 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider { private: class PoolResource : public ScopedResource { public: - static scoped_ptr<PoolResource> Create( + static std::unique_ptr<PoolResource> Create( ResourceProvider* resource_provider) { - return make_scoped_ptr(new PoolResource(resource_provider)); + return base::WrapUnique(new PoolResource(resource_provider)); } void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, const ResourceProvider* resource_provider, @@ -101,8 +102,8 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider { base::TimeTicks last_usage_; }; - void DidFinishUsingResource(scoped_ptr<PoolResource> resource); - void DeleteResource(scoped_ptr<PoolResource> resource); + void DidFinishUsingResource(std::unique_ptr<PoolResource> resource); + void DeleteResource(std::unique_ptr<PoolResource> resource); // Functions which manage periodic eviction of expired resources. void ScheduleEvictExpiredResourcesIn(base::TimeDelta time_from_now); @@ -120,11 +121,11 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider { size_t total_resource_count_; // Holds most recently used resources at the front of the queue. - using ResourceDeque = std::deque<scoped_ptr<PoolResource>>; + using ResourceDeque = std::deque<std::unique_ptr<PoolResource>>; ResourceDeque unused_resources_; ResourceDeque busy_resources_; - std::map<ResourceId, scoped_ptr<PoolResource>> in_use_resources_; + std::map<ResourceId, std::unique_ptr<PoolResource>> in_use_resources_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; bool evict_expired_resources_pending_; diff --git a/chromium/cc/resources/resource_pool_unittest.cc b/chromium/cc/resources/resource_pool_unittest.cc index af865036136..d9025c621b1 100644 --- a/chromium/cc/resources/resource_pool_unittest.cc +++ b/chromium/cc/resources/resource_pool_unittest.cc @@ -7,7 +7,7 @@ #include <stddef.h> #include "base/run_loop.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/resources/resource_util.h" #include "cc/resources/scoped_resource.h" #include "cc/test/fake_output_surface.h" @@ -34,11 +34,11 @@ class ResourcePoolTest : public testing::Test { protected: FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> output_surface_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<FakeOutputSurface> output_surface_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - scoped_ptr<ResourcePool> resource_pool_; + std::unique_ptr<ResourcePool> resource_pool_; }; TEST_F(ResourcePoolTest, AcquireRelease) { diff --git a/chromium/cc/resources/resource_provider.cc b/chromium/cc/resources/resource_provider.cc index 128ab280fa7..ae6edc35efb 100644 --- a/chromium/cc/resources/resource_provider.cc +++ b/chromium/cc/resources/resource_provider.cc @@ -19,7 +19,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" #include "cc/resources/platform_color.h" @@ -34,6 +34,7 @@ #include "skia/ext/texture_handle.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" +#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/GrTextureProvider.h" @@ -65,7 +66,7 @@ class IdAllocator { GLES2Interface* gl_; const size_t id_allocation_chunk_size_; - scoped_ptr<GLuint[]> ids_; + std::unique_ptr<GLuint[]> ids_; size_t next_id_index_; }; @@ -221,7 +222,7 @@ ResourceProvider::Resource::Resource(GLuint texture_id, gl_pixel_buffer_id(0), gl_upload_query_id(0), gl_read_lock_query_id(0), - pixels(NULL), + pixels(nullptr), lock_for_read_count(0), imported_count(0), exported_count(0), @@ -233,7 +234,7 @@ ResourceProvider::Resource::Resource(GLuint texture_id, read_lock_fences_enabled(false), has_shared_bitmap_id(false), is_overlay_candidate(false), - read_lock_fence(NULL), + read_lock_fence(nullptr), size(size), origin(origin), target(target), @@ -244,8 +245,7 @@ ResourceProvider::Resource::Resource(GLuint texture_id, hint(hint), type(type), format(format), - shared_bitmap(NULL), - gpu_memory_buffer(NULL) {} + shared_bitmap(nullptr) {} ResourceProvider::Resource::Resource(uint8_t* pixels, SharedBitmap* bitmap, @@ -269,7 +269,7 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, read_lock_fences_enabled(false), has_shared_bitmap_id(!!bitmap), is_overlay_candidate(false), - read_lock_fence(NULL), + read_lock_fence(nullptr), size(size), origin(origin), target(0), @@ -280,8 +280,7 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, hint(TEXTURE_HINT_IMMUTABLE), type(RESOURCE_TYPE_BITMAP), format(RGBA_8888), - shared_bitmap(bitmap), - gpu_memory_buffer(NULL) { + shared_bitmap(bitmap) { DCHECK(origin == DELEGATED || pixels); if (bitmap) shared_bitmap_id = bitmap->id(); @@ -296,7 +295,7 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id, gl_pixel_buffer_id(0), gl_upload_query_id(0), gl_read_lock_query_id(0), - pixels(NULL), + pixels(nullptr), lock_for_read_count(0), imported_count(0), exported_count(0), @@ -308,7 +307,7 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id, read_lock_fences_enabled(false), has_shared_bitmap_id(true), is_overlay_candidate(false), - read_lock_fence(NULL), + read_lock_fence(nullptr), size(size), origin(origin), target(0), @@ -320,10 +319,9 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id, type(RESOURCE_TYPE_BITMAP), format(RGBA_8888), shared_bitmap_id(bitmap_id), - shared_bitmap(NULL), - gpu_memory_buffer(NULL) {} + shared_bitmap(nullptr) {} -ResourceProvider::Resource::Resource(const Resource& other) = default; +ResourceProvider::Resource::Resource(Resource&& other) = default; void ResourceProvider::Resource::set_mailbox(const TextureMailbox& mailbox) { mailbox_ = mailbox; @@ -383,7 +381,7 @@ ResourceProvider::Child::Child(const Child& other) = default; ResourceProvider::Child::~Child() {} -scoped_ptr<ResourceProvider> ResourceProvider::Create( +std::unique_ptr<ResourceProvider> ResourceProvider::Create( OutputSurface* output_surface, SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, @@ -392,7 +390,7 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create( size_t id_allocation_chunk_size, bool use_gpu_memory_buffer_resources, const std::vector<unsigned>& use_image_texture_targets) { - scoped_ptr<ResourceProvider> resource_provider(new ResourceProvider( + std::unique_ptr<ResourceProvider> resource_provider(new ResourceProvider( output_surface, shared_bitmap_manager, gpu_memory_buffer_manager, blocking_main_thread_task_runner, highp_threshold_min, id_allocation_chunk_size, use_gpu_memory_buffer_resources, @@ -432,7 +430,7 @@ ResourceProvider::~ResourceProvider() { } bool ResourceProvider::IsResourceFormatSupported(ResourceFormat format) const { - ContextProvider::Capabilities caps; + gpu::Capabilities caps; if (output_surface_->context_provider()) caps = output_surface_->context_provider()->ContextCapabilities(); @@ -444,13 +442,13 @@ bool ResourceProvider::IsResourceFormatSupported(ResourceFormat format) const { case LUMINANCE_8: return true; case BGRA_8888: - return caps.gpu.texture_format_bgra8888; + return caps.texture_format_bgra8888; case ETC1: - return caps.gpu.texture_format_etc1; + return caps.texture_format_etc1; case RED_8: - return caps.gpu.texture_rg; + return caps.texture_rg; case LUMINANCE_F16: - return caps.gpu.texture_half_float_linear; + return caps.texture_half_float_linear; } NOTREACHED(); @@ -551,7 +549,7 @@ ResourceId ResourceProvider::CreateGLTexture(const gfx::Size& size, ResourceId ResourceProvider::CreateBitmap(const gfx::Size& size) { DCHECK(thread_checker_.CalledOnValidThread()); - scoped_ptr<SharedBitmap> bitmap = + std::unique_ptr<SharedBitmap> bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size); uint8_t* pixels = bitmap->pixels(); DCHECK(pixels); @@ -586,7 +584,7 @@ ResourceId ResourceProvider::CreateResourceFromIOSurface( ResourceId ResourceProvider::CreateResourceFromTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl, + std::unique_ptr<SingleReleaseCallbackImpl> release_callback_impl, bool read_lock_fences_enabled) { DCHECK(thread_checker_.CalledOnValidThread()); // Just store the information. Mailbox will be consumed in LockForRead(). @@ -616,13 +614,14 @@ ResourceId ResourceProvider::CreateResourceFromTextureMailbox( base::Owned(release_callback_impl.release())); resource->read_lock_fences_enabled = read_lock_fences_enabled; resource->is_overlay_candidate = mailbox.is_overlay_candidate(); + resource->gpu_memory_buffer_id = mailbox.gpu_memory_buffer_id(); return id; } ResourceId ResourceProvider::CreateResourceFromTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl) { + std::unique_ptr<SingleReleaseCallbackImpl> release_callback_impl) { return CreateResourceFromTextureMailbox( mailbox, std::move(release_callback_impl), false); } @@ -714,17 +713,16 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, DCHECK(resource->origin != Resource::EXTERNAL); DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type); delete resource->shared_bitmap; - resource->pixels = NULL; + resource->pixels = nullptr; } if (resource->pixels) { DCHECK(resource->origin == Resource::INTERNAL); delete[] resource->pixels; - resource->pixels = NULL; + resource->pixels = nullptr; } if (resource->gpu_memory_buffer) { DCHECK(resource->origin == Resource::INTERNAL); - delete resource->gpu_memory_buffer; - resource->gpu_memory_buffer = NULL; + resource->gpu_memory_buffer.reset(); } resources_.erase(it); } @@ -826,9 +824,9 @@ void ResourceProvider::GenerateSyncTokenForResources( ResourceProvider::Resource* ResourceProvider::InsertResource( ResourceId id, - const Resource& resource) { + Resource resource) { std::pair<ResourceMap::iterator, bool> result = - resources_.insert(ResourceMap::value_type(id, resource)); + resources_.insert(ResourceMap::value_type(id, std::move(resource))); DCHECK(result.second); return &result.first->second; } @@ -868,7 +866,7 @@ const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) { if (!resource->pixels && resource->has_shared_bitmap_id && shared_bitmap_manager_) { - scoped_ptr<SharedBitmap> bitmap = + std::unique_ptr<SharedBitmap> bitmap = shared_bitmap_manager_->GetSharedBitmapFromId( resource->size, resource->shared_bitmap_id); if (bitmap) { @@ -1000,7 +998,7 @@ ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL( resource_provider_->LazyAllocate(resource_); texture_id_ = resource_->gl_id; DCHECK(texture_id_); - if (resource_->dirty_image) + if (resource_->image_id && resource_->dirty_image) resource_provider_->BindImageForSampling(resource_); } @@ -1050,7 +1048,7 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: : resource_provider_(resource_provider), resource_(resource_provider->LockForWrite(resource_id)) { DCHECK(IsGpuResourceType(resource_->type)); - gpu_memory_buffer_.reset(resource_->gpu_memory_buffer); + gpu_memory_buffer_ = std::move(resource_->gpu_memory_buffer); resource_->gpu_memory_buffer = nullptr; } @@ -1063,7 +1061,9 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: DCHECK(!resource_->gpu_memory_buffer); resource_provider_->LazyCreate(resource_); - resource_->gpu_memory_buffer = gpu_memory_buffer_.release(); + resource_->gpu_memory_buffer = std::move(gpu_memory_buffer_); + if (resource_->gpu_memory_buffer) + resource_->gpu_memory_buffer_id = resource_->gpu_memory_buffer->GetId(); resource_->allocated = true; resource_provider_->LazyCreateImage(resource_); resource_->dirty_image = true; @@ -1082,7 +1082,7 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() { gpu_memory_buffer_ = resource_provider_->gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( resource_->size, BufferFormat(resource_->format), - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, 0 /* surface_id */); + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gpu::kNullSurfaceHandle); } return gpu_memory_buffer_.get(); } @@ -1095,9 +1095,8 @@ ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr( set_sync_token_(false) { DCHECK(thread_checker_.CalledOnValidThread()); resource_provider_->LazyAllocate(resource_); - if (resource_->dirty_image) { + if (resource_->image_id && resource_->dirty_image) resource_provider_->BindImageForSampling(resource_); - } } ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() { @@ -1237,19 +1236,19 @@ void ResourceProvider::Initialize() { DCHECK(!texture_id_allocator_); DCHECK(!buffer_id_allocator_); - const ContextProvider::Capabilities& caps = + const gpu::Capabilities& caps = output_surface_->context_provider()->ContextCapabilities(); DCHECK(IsGpuResourceType(default_resource_type_)); - 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; - use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1; - yuv_resource_format_ = caps.gpu.texture_rg ? RED_8 : LUMINANCE_8; + use_texture_storage_ext_ = caps.texture_storage; + use_texture_format_bgra_ = caps.texture_format_bgra8888; + use_texture_usage_hint_ = caps.texture_usage; + use_compressed_texture_etc1_ = caps.texture_format_etc1; + yuv_resource_format_ = caps.texture_rg ? RED_8 : LUMINANCE_8; yuv_highbit_resource_format_ = yuv_resource_format_; - if (caps.gpu.texture_half_float_linear) + if (caps.texture_half_float_linear) yuv_highbit_resource_format_ = LUMINANCE_F16; - use_sync_query_ = caps.gpu.sync_query; + use_sync_query_ = caps.sync_query; max_texture_size_ = 0; // Context expects cleared value. gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_); @@ -1257,7 +1256,7 @@ void ResourceProvider::Initialize() { PlatformColor::BestSupportedTextureFormat(use_texture_format_bgra_); best_render_buffer_format_ = PlatformColor::BestSupportedTextureFormat( - caps.gpu.render_buffer_format_bgra8888); + caps.render_buffer_format_bgra8888); texture_id_allocator_.reset( new TextureIdAllocator(gl, id_allocation_chunk_size_)); @@ -1443,6 +1442,7 @@ void ResourceProvider::ReceiveFromChild( it->mailbox_holder.texture_target)); resource->read_lock_fences_enabled = it->read_lock_fences_enabled; resource->is_overlay_candidate = it->is_overlay_candidate; + resource->gpu_memory_buffer_id = it->gpu_memory_buffer_id; } resource->child_id = child; // Don't allocate a texture for a child. @@ -1568,6 +1568,7 @@ void ResourceProvider::TransferResource(Resource* source, resource->filter = source->filter; resource->size = source->size; resource->read_lock_fences_enabled = source->read_lock_fences_enabled; + resource->gpu_memory_buffer_id = source->gpu_memory_buffer_id; resource->is_overlay_candidate = source->is_overlay_candidate; if (source->type == RESOURCE_TYPE_BITMAP) { @@ -1782,11 +1783,11 @@ void ResourceProvider::LazyAllocate(Resource* resource) { gl->BindTexture(resource->target, resource->gl_id); if (resource->type == RESOURCE_TYPE_GPU_MEMORY_BUFFER) { resource->gpu_memory_buffer = - gpu_memory_buffer_manager_ - ->AllocateGpuMemoryBuffer(size, BufferFormat(format), - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - 0 /* surface_id */) - .release(); + gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( + size, BufferFormat(format), + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gpu::kNullSurfaceHandle); + if (resource->gpu_memory_buffer) + resource->gpu_memory_buffer_id = resource->gpu_memory_buffer->GetId(); LazyCreateImage(resource); resource->dirty_image = true; resource->is_overlay_candidate = true; @@ -1801,7 +1802,7 @@ void ResourceProvider::LazyAllocate(Resource* resource) { if (format != ETC1) { gl->TexImage2D(resource->target, 0, GLInternalFormat(format), size.width(), size.height(), 0, GLDataFormat(format), - GLDataType(format), NULL); + GLDataType(format), nullptr); } } } @@ -1828,6 +1829,8 @@ void ResourceProvider::LazyCreateImage(Resource* resource) { resource->image_id = gl->CreateImageCHROMIUM( resource->gpu_memory_buffer->AsClientBuffer(), resource->size.width(), resource->size.height(), GLInternalFormat(resource->format)); + DCHECK(resource->image_id || IsGLContextLost()); + resource->SetLocallyUsed(); } } @@ -1881,14 +1884,18 @@ void ResourceProvider::ValidateResource(ResourceId id) const { GLES2Interface* ResourceProvider::ContextGL() const { ContextProvider* context_provider = output_surface_->context_provider(); - return context_provider ? context_provider->ContextGL() : NULL; + return context_provider ? context_provider->ContextGL() : nullptr; } class GrContext* ResourceProvider::GrContext(bool worker_context) const { ContextProvider* context_provider = worker_context ? output_surface_->worker_context_provider() : output_surface_->context_provider(); - return context_provider ? context_provider->GrContext() : NULL; + return context_provider ? context_provider->GrContext() : nullptr; +} + +bool ResourceProvider::IsGLContextLost() const { + return ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR; } bool ResourceProvider::OnMemoryDump( diff --git a/chromium/cc/resources/resource_provider.h b/chromium/cc/resources/resource_provider.h index 0c6d3b79f9a..56c3a625a09 100644 --- a/chromium/cc/resources/resource_provider.h +++ b/chromium/cc/resources/resource_provider.h @@ -9,6 +9,7 @@ #include <stdint.h> #include <deque> +#include <memory> #include <set> #include <string> #include <unordered_map> @@ -19,7 +20,6 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" -#include "base/memory/scoped_ptr.h" #include "base/threading/thread_checker.h" #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/memory_dump_provider.h" @@ -37,7 +37,6 @@ #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -86,7 +85,7 @@ class CC_EXPORT ResourceProvider RESOURCE_TYPE_BITMAP, }; - static scoped_ptr<ResourceProvider> Create( + static std::unique_ptr<ResourceProvider> Create( OutputSurface* output_surface, SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, @@ -146,11 +145,11 @@ class CC_EXPORT ResourceProvider // Wraps an external texture mailbox into a GL resource. ResourceId CreateResourceFromTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl); + std::unique_ptr<SingleReleaseCallbackImpl> release_callback_impl); ResourceId CreateResourceFromTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl, + std::unique_ptr<SingleReleaseCallbackImpl> release_callback_impl, bool read_lock_fences_enabled); void DeleteResource(ResourceId id); @@ -327,7 +326,7 @@ class CC_EXPORT ResourceProvider private: ResourceProvider* resource_provider_; ResourceProvider::Resource* resource_; - scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; base::ThreadChecker thread_checker_; DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGpuMemoryBuffer); @@ -518,7 +517,7 @@ class CC_EXPORT ResourceProvider const gfx::Size& size, Origin origin, GLenum filter); - Resource(const Resource& other); + Resource(Resource&& other); bool needs_sync_token() const { return needs_sync_token_; } @@ -570,12 +569,15 @@ class CC_EXPORT ResourceProvider ResourceFormat format; SharedBitmapId shared_bitmap_id; SharedBitmap* shared_bitmap; - gfx::GpuMemoryBuffer* gpu_memory_buffer; + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; + gfx::GpuMemoryBufferId gpu_memory_buffer_id; private: SynchronizationState synchronization_state_ = SYNCHRONIZED; bool needs_sync_token_ = false; TextureMailbox mailbox_; + + DISALLOW_COPY_AND_ASSIGN(Resource); }; using ResourceMap = std::unordered_map<ResourceId, Resource>; @@ -602,7 +604,7 @@ class CC_EXPORT ResourceProvider ResourceType type, ResourceFormat format); ResourceId CreateBitmap(const gfx::Size& size); - Resource* InsertResource(ResourceId id, const Resource& resource); + Resource* InsertResource(ResourceId id, Resource resource); Resource* GetResource(ResourceId id); const Resource* LockForRead(ResourceId id); void UnlockForRead(ResourceId id); @@ -640,6 +642,7 @@ class CC_EXPORT ResourceProvider // Returns NULL if the output_surface_ does not have a ContextProvider. gpu::gles2::GLES2Interface* ContextGL() const; class GrContext* GrContext(bool worker_context) const; + bool IsGLContextLost() const; OutputSurface* output_surface_; SharedBitmapManager* shared_bitmap_manager_; @@ -669,8 +672,8 @@ class CC_EXPORT ResourceProvider scoped_refptr<Fence> current_read_lock_fence_; const size_t id_allocation_chunk_size_; - scoped_ptr<IdAllocator> texture_id_allocator_; - scoped_ptr<IdAllocator> buffer_id_allocator_; + std::unique_ptr<IdAllocator> texture_id_allocator_; + std::unique_ptr<IdAllocator> buffer_id_allocator_; bool use_sync_query_; std::vector<unsigned> use_image_texture_targets_; diff --git a/chromium/cc/resources/resource_provider_unittest.cc b/chromium/cc/resources/resource_provider_unittest.cc index d3eb2649699..578eeb06681 100644 --- a/chromium/cc/resources/resource_provider_unittest.cc +++ b/chromium/cc/resources/resource_provider_unittest.cc @@ -16,6 +16,7 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "cc/output/output_surface.h" #include "cc/resources/returned_resource.h" @@ -68,13 +69,13 @@ static void ReleaseCallback( } static void SharedBitmapReleaseCallback( - scoped_ptr<SharedBitmap> bitmap, + std::unique_ptr<SharedBitmap> bitmap, const gpu::SyncToken& sync_token, bool lost_resource, BlockingTaskRunner* main_thread_task_runner) {} static void ReleaseSharedBitmapCallback( - scoped_ptr<SharedBitmap> shared_bitmap, + std::unique_ptr<SharedBitmap> shared_bitmap, bool* release_called, gpu::SyncToken* release_sync_token, bool* lost_resource_result, @@ -86,11 +87,12 @@ static void ReleaseSharedBitmapCallback( *lost_resource_result = lost_resource; } -static scoped_ptr<SharedBitmap> CreateAndFillSharedBitmap( +static std::unique_ptr<SharedBitmap> CreateAndFillSharedBitmap( SharedBitmapManager* manager, const gfx::Size& size, uint32_t value) { - scoped_ptr<SharedBitmap> shared_bitmap = manager->AllocateSharedBitmap(size); + std::unique_ptr<SharedBitmap> shared_bitmap = + manager->AllocateSharedBitmap(size); CHECK(shared_bitmap); uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_bitmap->pixels()); CHECK(pixels); @@ -136,8 +138,8 @@ class TextureStateTrackingContext : public TestWebGraphicsContext3D { // contents as well as information about sync points. class ContextSharedData { public: - static scoped_ptr<ContextSharedData> Create() { - return make_scoped_ptr(new ContextSharedData()); + static std::unique_ptr<ContextSharedData> Create() { + return base::WrapUnique(new ContextSharedData()); } uint32_t InsertFenceSync() { return next_fence_sync_++; } @@ -189,9 +191,9 @@ class ContextSharedData { class ResourceProviderContext : public TestWebGraphicsContext3D { public: - static scoped_ptr<ResourceProviderContext> Create( + static std::unique_ptr<ResourceProviderContext> Create( ContextSharedData* shared_data) { - return make_scoped_ptr(new ResourceProviderContext(shared_data)); + return base::WrapUnique(new ResourceProviderContext(shared_data)); } GLuint64 insertFenceSync() override { @@ -205,7 +207,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D { sync_token_data.SetVerifyFlush(); // Commit the produceTextureCHROMIUM calls at this point, so that // they're associated with the sync point. - for (const scoped_ptr<PendingProduceTexture>& pending_texture : + for (const std::unique_ptr<PendingProduceTexture>& pending_texture : pending_produce_textures_) { shared_data_->ProduceTexture(pending_texture->mailbox, sync_token_data, pending_texture->texture); @@ -301,7 +303,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D { // Delay moving the texture into the mailbox until the next // sync token, so that it is not visible to other contexts that // haven't waited on that sync point. - scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture); + std::unique_ptr<PendingProduceTexture> pending(new PendingProduceTexture); memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox)); base::AutoLock lock_for_texture_access(namespace_->lock); pending->texture = UnboundTexture(texture); @@ -380,7 +382,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D { }; ContextSharedData* shared_data_; gpu::SyncToken last_waited_sync_token_; - std::deque<scoped_ptr<PendingProduceTexture>> pending_produce_textures_; + std::deque<std::unique_ptr<PendingProduceTexture>> pending_produce_textures_; }; void GetResourcePixels(ResourceProvider* resource_provider, @@ -421,7 +423,7 @@ class ResourceProviderTest switch (GetParam()) { case ResourceProvider::RESOURCE_TYPE_GPU_MEMORY_BUFFER: case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: { - scoped_ptr<ResourceProviderContext> context3d( + std::unique_ptr<ResourceProviderContext> context3d( ResourceProviderContext::Create(shared_data_.get())); context3d_ = context3d.get(); @@ -430,7 +432,7 @@ class ResourceProviderTest output_surface_ = FakeOutputSurface::Create3d(context_provider); - scoped_ptr<ResourceProviderContext> child_context_owned = + std::unique_ptr<ResourceProviderContext> child_context_owned = ResourceProviderContext::Create(shared_data_.get()); child_context_ = child_context_owned.get(); if (child_needs_sync_token) { @@ -444,9 +446,9 @@ class ResourceProviderTest } case ResourceProvider::RESOURCE_TYPE_BITMAP: output_surface_ = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); child_output_surface_ = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); break; } CHECK(output_surface_->BindToClient(&output_surface_client_)); @@ -500,8 +502,8 @@ class ResourceProviderTest sync_token->GetData()); EXPECT_TRUE(sync_token->HasData()); - scoped_ptr<SharedBitmap> shared_bitmap; - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SharedBitmap> shared_bitmap; + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create(base::Bind( ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap), release_called, release_sync_token, lost_resource)); @@ -510,11 +512,11 @@ class ResourceProviderTest std::move(callback)); } else { gfx::Size size(64, 64); - scoped_ptr<SharedBitmap> shared_bitmap( + std::unique_ptr<SharedBitmap> shared_bitmap( CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, 0)); SharedBitmap* shared_bitmap_ptr = shared_bitmap.get(); - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create(base::Bind( ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap), release_called, release_sync_token, lost_resource)); @@ -534,18 +536,18 @@ class ResourceProviderTest protected: static bool use_gpu_memory_buffer_resources_; static std::vector<unsigned> use_image_texture_targets_; - scoped_ptr<ContextSharedData> shared_data_; + std::unique_ptr<ContextSharedData> shared_data_; ResourceProviderContext* context3d_; ResourceProviderContext* child_context_; FakeOutputSurfaceClient output_surface_client_; FakeOutputSurfaceClient child_output_surface_client_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<OutputSurface> child_output_surface_; - scoped_ptr<BlockingTaskRunner> main_thread_task_runner_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<ResourceProvider> child_resource_provider_; - scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_; + std::unique_ptr<OutputSurface> output_surface_; + std::unique_ptr<OutputSurface> child_output_surface_; + std::unique_ptr<BlockingTaskRunner> main_thread_task_runner_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<ResourceProvider> child_resource_provider_; + std::unique_ptr<TestSharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_; }; bool ResourceProviderTest::use_gpu_memory_buffer_resources_ = false; @@ -1263,7 +1265,7 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) { uint8_t data2[4] = { 5, 5, 5, 5 }; child_resource_provider_->CopyToResource(id2, data2, size); - scoped_ptr<SharedBitmap> shared_bitmap(CreateAndFillSharedBitmap( + std::unique_ptr<SharedBitmap> shared_bitmap(CreateAndFillSharedBitmap( shared_bitmap_manager_.get(), gfx::Size(1, 1), 0)); SharedBitmap* shared_bitmap_ptr = shared_bitmap.get(); ResourceId id3 = child_resource_provider_->CreateResourceFromTextureMailbox( @@ -1451,18 +1453,19 @@ TEST_P(ResourceProviderTest, TransferGLToSoftware) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP) return; - scoped_ptr<ResourceProviderContext> child_context_owned( + std::unique_ptr<ResourceProviderContext> child_context_owned( ResourceProviderContext::Create(shared_data_.get())); FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface( + std::unique_ptr<OutputSurface> child_output_surface( FakeOutputSurface::Create3d(std::move(child_context_owned))); 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, 1, - use_gpu_memory_buffer_resources_, use_image_texture_targets_)); + std::unique_ptr<ResourceProvider> child_resource_provider( + ResourceProvider::Create( + child_output_surface.get(), shared_bitmap_manager_.get(), + gpu_memory_buffer_manager_.get(), NULL, 0, 1, + use_gpu_memory_buffer_resources_, use_image_texture_targets_)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -1962,33 +1965,33 @@ TEST_P(ResourceProviderTest, UnuseTransferredResources) { class ResourceProviderTestTextureFilters : public ResourceProviderTest { public: static void RunTest(GLenum child_filter, GLenum parent_filter) { - scoped_ptr<TextureStateTrackingContext> child_context_owned( + std::unique_ptr<TextureStateTrackingContext> child_context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* child_context = child_context_owned.get(); FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface( + std::unique_ptr<OutputSurface> child_output_surface( FakeOutputSurface::Create3d(std::move(child_context_owned))); CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> child_resource_provider( + std::unique_ptr<ResourceProvider> child_resource_provider( ResourceProvider::Create(child_output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); - scoped_ptr<TextureStateTrackingContext> parent_context_owned( + std::unique_ptr<TextureStateTrackingContext> parent_context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* parent_context = parent_context_owned.get(); FakeOutputSurfaceClient parent_output_surface_client; - scoped_ptr<OutputSurface> parent_output_surface( + std::unique_ptr<OutputSurface> parent_output_surface( FakeOutputSurface::Create3d(std::move(parent_context_owned))); CHECK(parent_output_surface->BindToClient(&parent_output_surface_client)); - scoped_ptr<ResourceProvider> parent_resource_provider( + std::unique_ptr<ResourceProvider> parent_resource_provider( ResourceProvider::Create(parent_output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, 1, use_gpu_memory_buffer_resources_, @@ -2591,7 +2594,7 @@ TEST_P(ResourceProviderTest, LostContext) { gpu::SyncToken release_sync_token; bool lost_resource = false; BlockingTaskRunner* main_thread_task_runner = NULL; - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create( base::Bind(ReleaseCallback, &release_sync_token, &lost_resource, &main_thread_task_runner)); @@ -2615,16 +2618,16 @@ TEST_P(ResourceProviderTest, ScopedSampler) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -2694,16 +2697,16 @@ TEST_P(ResourceProviderTest, ManagedResource) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -2737,16 +2740,16 @@ TEST_P(ResourceProviderTest, TextureWrapMode) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -2779,18 +2782,18 @@ TEST_P(ResourceProviderTest, TextureHint) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); context->set_support_texture_storage(true); context->set_support_texture_usage(true); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -2840,16 +2843,16 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) { gfx::Size size(64, 64); const uint32_t kBadBeef = 0xbadbeef; - scoped_ptr<SharedBitmap> shared_bitmap( + std::unique_ptr<SharedBitmap> shared_bitmap( CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, kBadBeef)); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( - FakeOutputSurface::CreateSoftware(make_scoped_ptr( - new SoftwareOutputDevice))); + std::unique_ptr<OutputSurface> output_surface( + FakeOutputSurface::CreateSoftware( + base::WrapUnique(new SoftwareOutputDevice))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), main_thread_task_runner_.get(), 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -2857,7 +2860,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) { gpu::SyncToken release_sync_token; bool lost_resource = false; BlockingTaskRunner* main_thread_task_runner = NULL; - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create( base::Bind(&ReleaseCallback, &release_sync_token, &lost_resource, &main_thread_task_runner)); @@ -2889,19 +2892,20 @@ class ResourceProviderTestTextureMailboxGLFilters BlockingTaskRunner* main_thread_task_runner, bool mailbox_nearest_neighbor, GLenum sampler_filter) { - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); 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, 1, use_gpu_memory_buffer_resources_, - use_image_texture_targets_)); + std::unique_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create( + output_surface.get(), shared_bitmap_manager, + gpu_memory_buffer_manager, main_thread_task_runner, 0, 1, + use_gpu_memory_buffer_resources_, use_image_texture_targets_)); unsigned texture_id = 1; gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO, 0, @@ -2920,7 +2924,7 @@ class ResourceProviderTestTextureMailboxGLFilters gpu::SyncToken release_sync_token; bool lost_resource = false; BlockingTaskRunner* mailbox_task_runner = NULL; - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create( base::Bind(&ReleaseCallback, &release_sync_token, &lost_resource, &mailbox_task_runner)); @@ -3034,16 +3038,16 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3060,7 +3064,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) { gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); TextureMailbox mailbox(gpu_mailbox, sync_token, target); @@ -3104,16 +3108,16 @@ TEST_P(ResourceProviderTest, if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3130,7 +3134,7 @@ TEST_P(ResourceProviderTest, gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); TextureMailbox mailbox(gpu_mailbox, sync_token, target); @@ -3160,16 +3164,16 @@ TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncTokenIfNeeded_NoSyncToken) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<TextureStateTrackingContext> context_owned( + std::unique_ptr<TextureStateTrackingContext> context_owned( new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3185,7 +3189,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncTokenIfNeeded_NoSyncToken) { gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallbackImpl> callback = + std::unique_ptr<SingleReleaseCallbackImpl> callback = SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); TextureMailbox mailbox(gpu_mailbox, sync_token, target); @@ -3282,16 +3286,16 @@ TEST_P(ResourceProviderTest, TextureAllocation) { // Only for GL textures. if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<AllocationTrackingContext3D> context_owned( + std::unique_ptr<AllocationTrackingContext3D> context_owned( new StrictMock<AllocationTrackingContext3D>); AllocationTrackingContext3D* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3336,18 +3340,18 @@ TEST_P(ResourceProviderTest, TextureAllocationHint) { // Only for GL textures. if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<AllocationTrackingContext3D> context_owned( + std::unique_ptr<AllocationTrackingContext3D> context_owned( new StrictMock<AllocationTrackingContext3D>); AllocationTrackingContext3D* context = context_owned.get(); context->set_support_texture_storage(true); context->set_support_texture_usage(true); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3391,7 +3395,7 @@ TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) { // Only for GL textures. if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<AllocationTrackingContext3D> context_owned( + std::unique_ptr<AllocationTrackingContext3D> context_owned( new StrictMock<AllocationTrackingContext3D>); AllocationTrackingContext3D* context = context_owned.get(); context->set_support_texture_format_bgra8888(true); @@ -3399,11 +3403,11 @@ TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) { context->set_support_texture_usage(true); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3445,12 +3449,12 @@ TEST_P(ResourceProviderTest, Image_GLTexture) { // Only for GL textures. if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<AllocationTrackingContext3D> context_owned( + std::unique_ptr<AllocationTrackingContext3D> context_owned( new StrictMock<AllocationTrackingContext3D>); AllocationTrackingContext3D* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); @@ -3462,7 +3466,7 @@ TEST_P(ResourceProviderTest, Image_GLTexture) { const unsigned kTextureId = 123u; const unsigned kImageId = 234u; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3529,18 +3533,18 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<AllocationTrackingContext3D> context_owned( + std::unique_ptr<AllocationTrackingContext3D> context_owned( new AllocationTrackingContext3D); AllocationTrackingContext3D* context = context_owned.get(); context_owned->set_support_compressed_texture_etc1(true); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); gfx::Size size(4, 4); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3561,18 +3565,18 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1Upload) { if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) return; - scoped_ptr<AllocationTrackingContext3D> context_owned( + std::unique_ptr<AllocationTrackingContext3D> context_owned( new AllocationTrackingContext3D); AllocationTrackingContext3D* context = context_owned.get(); context_owned->set_support_compressed_texture_etc1(true); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); gfx::Size size(4, 4); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + std::unique_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( output_surface.get(), shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(), NULL, 0, 1, use_gpu_memory_buffer_resources_, use_image_texture_targets_)); @@ -3613,15 +3617,15 @@ class TextureIdAllocationTrackingContext : public TestWebGraphicsContext3D { }; TEST(ResourceProviderTest, TextureAllocationChunkSize) { - scoped_ptr<TextureIdAllocationTrackingContext> context_owned( + std::unique_ptr<TextureIdAllocationTrackingContext> context_owned( new TextureIdAllocationTrackingContext); TextureIdAllocationTrackingContext* context = context_owned.get(); FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context_owned))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); gfx::Size size(1, 1); @@ -3629,11 +3633,12 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) { { size_t kTextureAllocationChunkSize = 1; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, - kTextureAllocationChunkSize, - ResourceProviderTest::use_gpu_memory_buffer_resources(), - ResourceProviderTest::use_image_texture_targets())); + std::unique_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create( + output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, + kTextureAllocationChunkSize, + ResourceProviderTest::use_gpu_memory_buffer_resources(), + ResourceProviderTest::use_image_texture_targets())); ResourceId id = resource_provider->CreateResource( size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); @@ -3646,11 +3651,12 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) { { size_t kTextureAllocationChunkSize = 8; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, - kTextureAllocationChunkSize, - ResourceProviderTest::use_gpu_memory_buffer_resources(), - ResourceProviderTest::use_image_texture_targets())); + std::unique_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create( + output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, + kTextureAllocationChunkSize, + ResourceProviderTest::use_gpu_memory_buffer_resources(), + ResourceProviderTest::use_image_texture_targets())); ResourceId id = resource_provider->CreateResource( size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); diff --git a/chromium/cc/resources/resource_util.h b/chromium/cc/resources/resource_util.h index 68a4aa59fa9..51cda02d499 100644 --- a/chromium/cc/resources/resource_util.h +++ b/chromium/cc/resources/resource_util.h @@ -55,18 +55,6 @@ class CC_EXPORT ResourceUtil { ResourceFormat format); private: - // TODO(prashant.n): Replace IsSameType with std::is_same once C++11 is used - // on all platforms. - template <typename T, typename U> - struct IsSameType { - static const bool value = false; - }; - - template <typename T> - struct IsSameType<T, T> { - static const bool value = true; - }; - template <typename T> static inline void VerifyType(); @@ -161,7 +149,7 @@ T ResourceUtil::UncheckedSizeInBytesAligned(const gfx::Size& size, template <typename T> void ResourceUtil::VerifyType() { static_assert( - std::numeric_limits<T>::is_integer && !IsSameType<T, bool>::value, + std::numeric_limits<T>::is_integer && !std::is_same<T, bool>::value, "T must be non-bool integer type. Preferred type is size_t."); } diff --git a/chromium/cc/resources/scoped_resource.h b/chromium/cc/resources/scoped_resource.h index 0e50d0ab68e..1190b47c955 100644 --- a/chromium/cc/resources/scoped_resource.h +++ b/chromium/cc/resources/scoped_resource.h @@ -5,9 +5,11 @@ #ifndef CC_RESOURCES_SCOPED_RESOURCE_H_ #define CC_RESOURCES_SCOPED_RESOURCE_H_ +#include <memory> + #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/resources/resource.h" @@ -19,9 +21,9 @@ namespace cc { class CC_EXPORT ScopedResource : public Resource { public: - static scoped_ptr<ScopedResource> Create( + static std::unique_ptr<ScopedResource> Create( ResourceProvider* resource_provider) { - return make_scoped_ptr(new ScopedResource(resource_provider)); + return base::WrapUnique(new ScopedResource(resource_provider)); } virtual ~ScopedResource(); diff --git a/chromium/cc/resources/scoped_resource_unittest.cc b/chromium/cc/resources/scoped_resource_unittest.cc index 1133f2108e1..a7811d0859e 100644 --- a/chromium/cc/resources/scoped_resource_unittest.cc +++ b/chromium/cc/resources/scoped_resource_unittest.cc @@ -18,14 +18,15 @@ namespace { TEST(ScopedResourceTest, NewScopedResource) { FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + std::unique_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); - scoped_ptr<ScopedResource> texture = + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); + std::unique_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); // New scoped textures do not hold a texture yet. @@ -39,14 +40,15 @@ TEST(ScopedResourceTest, NewScopedResource) { TEST(ScopedResourceTest, CreateScopedResource) { FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + std::unique_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); - scoped_ptr<ScopedResource> texture = + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); + std::unique_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); texture->Allocate(gfx::Size(30, 30), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); @@ -63,15 +65,16 @@ TEST(ScopedResourceTest, CreateScopedResource) { TEST(ScopedResourceTest, ScopedResourceIsDeleted) { FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + std::unique_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get()); + std::unique_ptr<ResourceProvider> resource_provider = + FakeResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get()); { - scoped_ptr<ScopedResource> texture = + std::unique_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); EXPECT_EQ(0u, resource_provider->num_resources()); @@ -83,7 +86,7 @@ TEST(ScopedResourceTest, ScopedResourceIsDeleted) { EXPECT_EQ(0u, resource_provider->num_resources()); { - scoped_ptr<ScopedResource> texture = + std::unique_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); EXPECT_EQ(0u, resource_provider->num_resources()); texture->Allocate(gfx::Size(30, 30), diff --git a/chromium/cc/resources/scoped_ui_resource.cc b/chromium/cc/resources/scoped_ui_resource.cc index 2db3edd12f5..4ac336d2fe7 100644 --- a/chromium/cc/resources/scoped_ui_resource.cc +++ b/chromium/cc/resources/scoped_ui_resource.cc @@ -5,14 +5,15 @@ #include "cc/resources/scoped_ui_resource.h" #include "base/bind.h" +#include "base/memory/ptr_util.h" #include "cc/trees/layer_tree_host.h" namespace cc { -scoped_ptr<ScopedUIResource> ScopedUIResource::Create( +std::unique_ptr<ScopedUIResource> ScopedUIResource::Create( LayerTreeHost* host, const UIResourceBitmap& bitmap) { - return make_scoped_ptr(new ScopedUIResource(host, bitmap)); + return base::WrapUnique(new ScopedUIResource(host, bitmap)); } ScopedUIResource::ScopedUIResource(LayerTreeHost* host, diff --git a/chromium/cc/resources/scoped_ui_resource.h b/chromium/cc/resources/scoped_ui_resource.h index 0e1676f05d2..4176c4b5af2 100644 --- a/chromium/cc/resources/scoped_ui_resource.h +++ b/chromium/cc/resources/scoped_ui_resource.h @@ -23,8 +23,9 @@ class LayerTreeHost; // resource or not. class CC_EXPORT ScopedUIResource : public UIResourceClient { public: - static scoped_ptr<ScopedUIResource> Create(LayerTreeHost* host, - const UIResourceBitmap& bitmap); + static std::unique_ptr<ScopedUIResource> Create( + LayerTreeHost* host, + const UIResourceBitmap& bitmap); ~ScopedUIResource() override; // UIResourceClient implementation. diff --git a/chromium/cc/resources/shared_bitmap_manager.h b/chromium/cc/resources/shared_bitmap_manager.h index 881f6fa9d2a..7ee8c9ce2fb 100644 --- a/chromium/cc/resources/shared_bitmap_manager.h +++ b/chromium/cc/resources/shared_bitmap_manager.h @@ -5,8 +5,9 @@ #ifndef CC_RESOURCES_SHARED_BITMAP_MANAGER_H_ #define CC_RESOURCES_SHARED_BITMAP_MANAGER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/resources/shared_bitmap.h" #include "ui/gfx/geometry/size.h" @@ -18,8 +19,9 @@ class CC_EXPORT SharedBitmapManager { SharedBitmapManager() {} virtual ~SharedBitmapManager() {} - virtual scoped_ptr<SharedBitmap> AllocateSharedBitmap(const gfx::Size&) = 0; - virtual scoped_ptr<SharedBitmap> GetSharedBitmapFromId( + virtual std::unique_ptr<SharedBitmap> AllocateSharedBitmap( + const gfx::Size&) = 0; + virtual std::unique_ptr<SharedBitmap> GetSharedBitmapFromId( const gfx::Size&, const SharedBitmapId&) = 0; diff --git a/chromium/cc/resources/single_release_callback.h b/chromium/cc/resources/single_release_callback.h index 2118ad70430..cfb2330a4c2 100644 --- a/chromium/cc/resources/single_release_callback.h +++ b/chromium/cc/resources/single_release_callback.h @@ -5,7 +5,9 @@ #ifndef CC_RESOURCES_SINGLE_RELEASE_CALLBACK_H_ #define CC_RESOURCES_SINGLE_RELEASE_CALLBACK_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/resources/release_callback.h" @@ -13,8 +15,9 @@ namespace cc { class CC_EXPORT SingleReleaseCallback { public: - static scoped_ptr<SingleReleaseCallback> Create(const ReleaseCallback& cb) { - return make_scoped_ptr(new SingleReleaseCallback(cb)); + static std::unique_ptr<SingleReleaseCallback> Create( + const ReleaseCallback& cb) { + return base::WrapUnique(new SingleReleaseCallback(cb)); } ~SingleReleaseCallback(); diff --git a/chromium/cc/resources/single_release_callback_impl.h b/chromium/cc/resources/single_release_callback_impl.h index 50c0210bddd..eafcb1f85e0 100644 --- a/chromium/cc/resources/single_release_callback_impl.h +++ b/chromium/cc/resources/single_release_callback_impl.h @@ -5,7 +5,9 @@ #ifndef CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_ #define CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/base/cc_export.h" #include "cc/resources/release_callback_impl.h" @@ -13,9 +15,9 @@ namespace cc { class CC_EXPORT SingleReleaseCallbackImpl { public: - static scoped_ptr<SingleReleaseCallbackImpl> Create( + static std::unique_ptr<SingleReleaseCallbackImpl> Create( const ReleaseCallbackImpl& cb) { - return make_scoped_ptr(new SingleReleaseCallbackImpl(cb)); + return base::WrapUnique(new SingleReleaseCallbackImpl(cb)); } ~SingleReleaseCallbackImpl(); diff --git a/chromium/cc/resources/texture_mailbox.cc b/chromium/cc/resources/texture_mailbox.cc index db117f52c54..b9439489305 100644 --- a/chromium/cc/resources/texture_mailbox.cc +++ b/chromium/cc/resources/texture_mailbox.cc @@ -31,15 +31,18 @@ TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox, secure_output_only_(false), nearest_neighbor_(false) {} -TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox, - const gpu::SyncToken& sync_token, - uint32_t target, - const gfx::Size& size_in_pixels, - bool is_overlay_candidate, - bool secure_output_only) +TextureMailbox::TextureMailbox( + const gpu::Mailbox& mailbox, + const gpu::SyncToken& sync_token, + uint32_t target, + const gfx::Size& size_in_pixels, + const gfx::GpuMemoryBufferId& gpu_memory_buffer_id, + bool is_overlay_candidate, + bool secure_output_only) : mailbox_holder_(mailbox, sync_token, target), shared_bitmap_(nullptr), size_in_pixels_(size_in_pixels), + gpu_memory_buffer_id_(gpu_memory_buffer_id), is_overlay_candidate_(is_overlay_candidate), secure_output_only_(secure_output_only), nearest_neighbor_(false) { diff --git a/chromium/cc/resources/texture_mailbox.h b/chromium/cc/resources/texture_mailbox.h index 8dcf98ed380..e93a63cc2f5 100644 --- a/chromium/cc/resources/texture_mailbox.h +++ b/chromium/cc/resources/texture_mailbox.h @@ -14,6 +14,7 @@ #include "cc/base/cc_export.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace cc { class SharedBitmap; @@ -31,6 +32,7 @@ class CC_EXPORT TextureMailbox { const gpu::SyncToken& sync_token, uint32_t target, const gfx::Size& size_in_pixels, + const gfx::GpuMemoryBufferId& gpu_memory_buffer_id, bool is_overlay_candidate, bool secure_output_only); TextureMailbox(SharedBitmap* shared_bitmap, const gfx::Size& size_in_pixels); @@ -56,6 +58,9 @@ class CC_EXPORT TextureMailbox { mailbox_holder_.sync_token = sync_token; } + gfx::GpuMemoryBufferId gpu_memory_buffer_id() const { + return gpu_memory_buffer_id_; + } bool is_overlay_candidate() const { return is_overlay_candidate_; } bool secure_output_only() const { return secure_output_only_; } bool nearest_neighbor() const { return nearest_neighbor_; } @@ -73,6 +78,7 @@ class CC_EXPORT TextureMailbox { gpu::MailboxHolder mailbox_holder_; SharedBitmap* shared_bitmap_; gfx::Size size_in_pixels_; + gfx::GpuMemoryBufferId gpu_memory_buffer_id_; bool is_overlay_candidate_; bool secure_output_only_; bool nearest_neighbor_; diff --git a/chromium/cc/resources/transferable_resource.h b/chromium/cc/resources/transferable_resource.h index ea6344120ea..65a16cb01ba 100644 --- a/chromium/cc/resources/transferable_resource.h +++ b/chromium/cc/resources/transferable_resource.h @@ -14,6 +14,7 @@ #include "cc/resources/resource_format.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace cc { @@ -38,6 +39,7 @@ struct CC_EXPORT TransferableResource { gpu::MailboxHolder mailbox_holder; bool read_lock_fences_enabled; bool is_software; + gfx::GpuMemoryBufferId gpu_memory_buffer_id; bool is_overlay_candidate; }; diff --git a/chromium/cc/resources/ui_resource_bitmap.cc b/chromium/cc/resources/ui_resource_bitmap.cc index 3acc6dc49e6..9c42bd811fd 100644 --- a/chromium/cc/resources/ui_resource_bitmap.cc +++ b/chromium/cc/resources/ui_resource_bitmap.cc @@ -6,8 +6,9 @@ #include <stdint.h> +#include <memory> + #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkMallocPixelRef.h" #include "third_party/skia/include/core/SkPixelRef.h" @@ -34,7 +35,7 @@ UIResourceBitmap::UIResourceFormat SkColorTypeToUIResourceFormat( } // namespace -void UIResourceBitmap::Create(const skia::RefPtr<SkPixelRef>& pixel_ref, +void UIResourceBitmap::Create(sk_sp<SkPixelRef> pixel_ref, const gfx::Size& size, UIResourceFormat format) { DCHECK(size.width()); @@ -43,7 +44,7 @@ void UIResourceBitmap::Create(const skia::RefPtr<SkPixelRef>& pixel_ref, DCHECK(pixel_ref->isImmutable()); format_ = format; size_ = size; - pixel_ref_ = pixel_ref; + pixel_ref_ = std::move(pixel_ref); // Default values for secondary parameters. opaque_ = (format == ETC1); @@ -53,9 +54,9 @@ UIResourceBitmap::UIResourceBitmap(const SkBitmap& skbitmap) { DCHECK_EQ(skbitmap.width(), skbitmap.rowBytesAsPixels()); DCHECK(skbitmap.isImmutable()); - skia::RefPtr<SkPixelRef> pixel_ref = skia::SharePtr(skbitmap.pixelRef()); + sk_sp<SkPixelRef> pixel_ref = sk_ref_sp(skbitmap.pixelRef()); const SkImageInfo& info = pixel_ref->info(); - Create(pixel_ref, gfx::Size(info.width(), info.height()), + Create(std::move(pixel_ref), gfx::Size(info.width(), info.height()), SkColorTypeToUIResourceFormat(skbitmap.colorType())); SetOpaque(skbitmap.isOpaque()); @@ -65,16 +66,16 @@ UIResourceBitmap::UIResourceBitmap(const gfx::Size& size, bool is_opaque) { SkAlphaType alphaType = is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaType); - skia::RefPtr<SkPixelRef> pixel_ref = skia::AdoptRef( + sk_sp<SkPixelRef> pixel_ref( SkMallocPixelRef::NewAllocate(info, info.minRowBytes(), NULL)); pixel_ref->setImmutable(); - Create(pixel_ref, size, UIResourceBitmap::RGBA8); + Create(std::move(pixel_ref), size, UIResourceBitmap::RGBA8); SetOpaque(is_opaque); } -UIResourceBitmap::UIResourceBitmap(const skia::RefPtr<SkPixelRef>& pixel_ref, +UIResourceBitmap::UIResourceBitmap(sk_sp<SkPixelRef> pixel_ref, const gfx::Size& size) { - Create(pixel_ref, size, UIResourceBitmap::ETC1); + Create(std::move(pixel_ref), size, UIResourceBitmap::ETC1); } UIResourceBitmap::UIResourceBitmap(const UIResourceBitmap& other) = default; diff --git a/chromium/cc/resources/ui_resource_bitmap.h b/chromium/cc/resources/ui_resource_bitmap.h index a90159f5db2..c56cc86115e 100644 --- a/chromium/cc/resources/ui_resource_bitmap.h +++ b/chromium/cc/resources/ui_resource_bitmap.h @@ -7,10 +7,10 @@ #include <stdint.h> +#include <memory> + #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" -#include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkPixelRef.h" #include "ui/gfx/geometry/size.h" @@ -41,19 +41,18 @@ class CC_EXPORT UIResourceBitmap { // be 32-bit RGBA or 8-bit ALPHA. explicit UIResourceBitmap(const SkBitmap& skbitmap); UIResourceBitmap(const gfx::Size& size, bool is_opaque); - UIResourceBitmap(const skia::RefPtr<SkPixelRef>& pixel_ref, - const gfx::Size& size); + UIResourceBitmap(sk_sp<SkPixelRef> pixel_ref, const gfx::Size& size); UIResourceBitmap(const UIResourceBitmap& other); ~UIResourceBitmap(); private: friend class AutoLockUIResourceBitmap; - void Create(const skia::RefPtr<SkPixelRef>& pixel_ref, + void Create(sk_sp<SkPixelRef> pixel_ref, const gfx::Size& size, UIResourceFormat format); - skia::RefPtr<SkPixelRef> pixel_ref_; + sk_sp<SkPixelRef> pixel_ref_; UIResourceFormat format_; gfx::Size size_; bool opaque_; diff --git a/chromium/cc/resources/ui_resource_request.cc b/chromium/cc/resources/ui_resource_request.cc index b8dd50af117..28fd7f3602f 100644 --- a/chromium/cc/resources/ui_resource_request.cc +++ b/chromium/cc/resources/ui_resource_request.cc @@ -4,6 +4,8 @@ #include "cc/resources/ui_resource_request.h" +#include "base/memory/ptr_util.h" + namespace cc { UIResourceRequest::UIResourceRequest(UIResourceRequestType type, @@ -24,7 +26,7 @@ UIResourceRequest& UIResourceRequest::operator=( type_ = request.type_; id_ = request.id_; if (request.bitmap_) { - bitmap_ = make_scoped_ptr(new UIResourceBitmap(*request.bitmap_.get())); + bitmap_ = base::WrapUnique(new UIResourceBitmap(*request.bitmap_.get())); } else { bitmap_ = nullptr; } diff --git a/chromium/cc/resources/ui_resource_request.h b/chromium/cc/resources/ui_resource_request.h index b89e567ce45..8294724e548 100644 --- a/chromium/cc/resources/ui_resource_request.h +++ b/chromium/cc/resources/ui_resource_request.h @@ -5,8 +5,9 @@ #ifndef CC_RESOURCES_UI_RESOURCE_REQUEST_H_ #define CC_RESOURCES_UI_RESOURCE_REQUEST_H_ +#include <memory> + #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/resources/ui_resource_bitmap.h" #include "cc/resources/ui_resource_client.h" @@ -41,7 +42,7 @@ class CC_EXPORT UIResourceRequest { private: UIResourceRequestType type_; UIResourceId id_; - scoped_ptr<UIResourceBitmap> bitmap_; + std::unique_ptr<UIResourceBitmap> bitmap_; }; } // namespace cc diff --git a/chromium/cc/resources/video_resource_updater.cc b/chromium/cc/resources/video_resource_updater.cc index e77cd7505af..50416eff7b5 100644 --- a/chromium/cc/resources/video_resource_updater.cc +++ b/chromium/cc/resources/video_resource_updater.cc @@ -21,13 +21,9 @@ #include "media/renderers/skcanvas_video_renderer.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" +#include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/geometry/size_conversions.h" -#if DCHECK_IS_ON() -#include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" -#endif - namespace cc { namespace { @@ -51,7 +47,7 @@ VideoFrameExternalResources::ResourceType ResourceTypeForVideoFrame( ? VideoFrameExternalResources::RGBA_RESOURCE : VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; case GL_TEXTURE_RECTANGLE_ARB: - return VideoFrameExternalResources::IO_SURFACE; + return VideoFrameExternalResources::RGB_RESOURCE; default: NOTREACHED(); break; @@ -61,9 +57,15 @@ VideoFrameExternalResources::ResourceType ResourceTypeForVideoFrame( return VideoFrameExternalResources::YUV_RESOURCE; break; case media::PIXEL_FORMAT_NV12: - DCHECK_EQ(static_cast<uint32_t>(GL_TEXTURE_RECTANGLE_ARB), - video_frame->mailbox_holder(0).texture_target); - return VideoFrameExternalResources::IO_SURFACE; + switch (video_frame->mailbox_holder(0).texture_target) { + case GL_TEXTURE_EXTERNAL_OES: + return VideoFrameExternalResources::YUV_RESOURCE; + case GL_TEXTURE_RECTANGLE_ARB: + return VideoFrameExternalResources::RGB_RESOURCE; + default: + NOTREACHED(); + break; + } break; case media::PIXEL_FORMAT_YV12: case media::PIXEL_FORMAT_YV16: @@ -117,14 +119,6 @@ class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient { gpu::SyncToken sync_token_; }; -#if DCHECK_IS_ON() -void OnVideoFrameDestruct( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const base::Closure& task) { - task_runner->PostTask(FROM_HERE, task); -} -#endif - } // namespace VideoResourceUpdater::PlaneResource::PlaneResource( @@ -132,48 +126,26 @@ VideoResourceUpdater::PlaneResource::PlaneResource( const gfx::Size& resource_size, ResourceFormat resource_format, gpu::Mailbox mailbox) - : resource_id(resource_id), - resource_size(resource_size), - resource_format(resource_format), - mailbox(mailbox), - ref_count(0), - frame_ptr(nullptr), -#if DCHECK_IS_ON() - destructed(false), -#endif - plane_index(0u) { -} + : resource_id_(resource_id), + resource_size_(resource_size), + resource_format_(resource_format), + mailbox_(mailbox) {} VideoResourceUpdater::PlaneResource::PlaneResource(const PlaneResource& other) = default; -bool VideoResourceUpdater::PlaneResourceMatchesUniqueID( - const PlaneResource& plane_resource, - const media::VideoFrame* video_frame, - size_t plane_index) { - bool matched = plane_resource.frame_ptr == video_frame && - plane_resource.plane_index == plane_index && - plane_resource.timestamp == video_frame->timestamp(); -#if DCHECK_IS_ON() - if ((plane_index == 0) && matched) { - DCHECK(!plane_resource.destructed) - << "ERROR: reused the destructed resource." - << " timestamp = " << plane_resource.timestamp; - } -#endif - return matched; +bool VideoResourceUpdater::PlaneResource::Matches(int unique_frame_id, + size_t plane_index) { + return has_unique_frame_id_and_plane_index_ && + unique_frame_id_ == unique_frame_id && plane_index_ == plane_index; } -void VideoResourceUpdater::SetPlaneResourceUniqueId( - const media::VideoFrame* video_frame, - 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(); -#if DCHECK_IS_ON() - plane_resource->destructed = false; -#endif +void VideoResourceUpdater::PlaneResource::SetUniqueId(int unique_frame_id, + size_t plane_index) { + DCHECK_EQ(ref_count_, 1); + plane_index_ = plane_index; + unique_frame_id_ = unique_frame_id; + has_unique_frame_id_and_plane_index_ = true; } VideoFrameExternalResources::VideoFrameExternalResources() @@ -195,7 +167,7 @@ VideoResourceUpdater::VideoResourceUpdater(ContextProvider* context_provider, VideoResourceUpdater::~VideoResourceUpdater() { for (const PlaneResource& plane_resource : all_resources_) - resource_provider_->DeleteResource(plane_resource.resource_id); + resource_provider_->DeleteResource(plane_resource.resource_id()); } VideoResourceUpdater::ResourceList::iterator @@ -231,8 +203,8 @@ VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size, } void VideoResourceUpdater::DeleteResource(ResourceList::iterator resource_it) { - DCHECK_EQ(resource_it->ref_count, 0); - resource_provider_->DeleteResource(resource_it->resource_id); + DCHECK(!resource_it->has_refs()); + resource_provider_->DeleteResource(resource_it->resource_id()); all_resources_.erase(resource_it); } @@ -335,7 +307,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( // Drop recycled resources that are the wrong format. for (auto it = all_resources_.begin(); it != all_resources_.end();) { - if (it->ref_count == 0 && it->resource_format != output_resource_format) + if (!it->has_refs() && it->resource_format() != output_resource_format) DeleteResource(it++); else ++it; @@ -355,9 +327,9 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( // Try recycle a previously-allocated resource. ResourceList::iterator resource_it = all_resources_.end(); for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { - if (it->resource_size == output_plane_resource_size && - it->resource_format == output_resource_format) { - if (PlaneResourceMatchesUniqueID(*it, video_frame.get(), i)) { + if (it->resource_size() == output_plane_resource_size && + it->resource_format() == output_resource_format) { + if (it->Matches(video_frame->unique_id(), i)) { // Bingo, we found a resource that already contains the data we are // planning to put in it. It's safe to reuse it even if // resource_provider_ holds some references to it, because those @@ -371,8 +343,8 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( // codereview.chromium.org/145273021. const bool in_use = software_compositor && - resource_provider_->InUseByConsumer(it->resource_id); - if (it->ref_count == 0 && !in_use) { + resource_provider_->InUseByConsumer(it->resource_id()); + if (!it->has_refs() && !in_use) { // We found a resource with the correct size that we can overwrite. resource_it = it; } @@ -389,14 +361,14 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( if (resource_it == all_resources_.end()) break; - ++resource_it->ref_count; + resource_it->add_ref(); plane_resources.push_back(resource_it); } if (plane_resources.size() != output_plane_count) { // Allocation failed, nothing will be returned so restore reference counts. for (ResourceList::iterator resource_it : plane_resources) - --resource_it->ref_count; + resource_it->remove_ref(); return VideoFrameExternalResources(); } @@ -405,34 +377,27 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( if (software_compositor) { DCHECK_EQ(plane_resources.size(), 1u); PlaneResource& plane_resource = *plane_resources[0]; - DCHECK_EQ(plane_resource.resource_format, kRGBResourceFormat); - DCHECK(plane_resource.mailbox.IsZero()); + DCHECK_EQ(plane_resource.resource_format(), kRGBResourceFormat); + DCHECK(plane_resource.mailbox().IsZero()); - if (!PlaneResourceMatchesUniqueID(plane_resource, video_frame.get(), 0)) { + if (!plane_resource.Matches(video_frame->unique_id(), 0)) { // We need to transfer data from |video_frame| to the plane resource. if (!video_renderer_) video_renderer_.reset(new media::SkCanvasVideoRenderer); ResourceProvider::ScopedWriteLockSoftware lock( - resource_provider_, plane_resource.resource_id); + resource_provider_, plane_resource.resource_id()); SkCanvas canvas(lock.sk_bitmap()); // This is software path, so canvas and video_frame are always backed // by software. video_renderer_->Copy(video_frame, &canvas, media::Context3D()); - SetPlaneResourceUniqueId(video_frame.get(), 0, &plane_resource); -#if DCHECK_IS_ON() - // Add VideoFrame destructor callback. - video_frame->AddDestructionObserver(base::Bind( - &OnVideoFrameDestruct, base::ThreadTaskRunnerHandle::Get(), - base::Bind(&VideoResourceUpdater::MarkOldResource, AsWeakPtr(), - base::Unretained(video_frame.get()), - video_frame->timestamp()))); -#endif + plane_resource.SetUniqueId(video_frame->unique_id(), 0); } - external_resources.software_resources.push_back(plane_resource.resource_id); + external_resources.software_resources.push_back( + plane_resource.resource_id()); external_resources.software_release_callback = - base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id); + base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id()); external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; return external_resources; } @@ -440,22 +405,22 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( for (size_t i = 0; i < plane_resources.size(); ++i) { PlaneResource& plane_resource = *plane_resources[i]; // Update each plane's resource id with its content. - DCHECK_EQ(plane_resource.resource_format, + DCHECK_EQ(plane_resource.resource_format(), resource_provider_->YuvResourceFormat(bits_per_channel)); - if (!PlaneResourceMatchesUniqueID(plane_resource, video_frame.get(), i)) { + if (!plane_resource.Matches(video_frame->unique_id(), i)) { // We need to transfer data from |video_frame| to the plane resource. // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. // The |resource_size_pixels| is the size of the resource we want to // upload to. - gfx::Size resource_size_pixels = plane_resource.resource_size; + gfx::Size resource_size_pixels = plane_resource.resource_size(); // The |video_stride_bytes| is the width of the video frame we are // uploading (including non-frame data to fill in the stride). int video_stride_bytes = video_frame->stride(i); size_t bytes_per_row = ResourceUtil::UncheckedWidthInBytes<size_t>( - resource_size_pixels.width(), plane_resource.resource_format); + resource_size_pixels.width(), plane_resource.resource_format()); // 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 = @@ -465,7 +430,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( int shift = 0; // LUMINANCE_F16 uses half-floats, so we always need a conversion step. - if (plane_resource.resource_format == LUMINANCE_F16) { + if (plane_resource.resource_format() == LUMINANCE_F16) { needs_conversion = true; // Note that the current method of converting integers to half-floats // stops working if you have more than 10 bits of data. @@ -488,7 +453,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( upload_pixels_.resize(needed_size); for (int row = 0; row < resource_size_pixels.height(); ++row) { - if (plane_resource.resource_format == LUMINANCE_F16) { + if (plane_resource.resource_format() == LUMINANCE_F16) { uint16_t* dst = reinterpret_cast<uint16_t*>( &upload_pixels_[upload_image_stride * row]); const uint16_t* src = reinterpret_cast<uint16_t*>( @@ -520,22 +485,12 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( pixels = &upload_pixels_[0]; } - resource_provider_->CopyToResource(plane_resource.resource_id, pixels, + resource_provider_->CopyToResource(plane_resource.resource_id(), pixels, resource_size_pixels); - SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resource); -#if DCHECK_IS_ON() - // Add VideoFrame destructor callback. - if (i == 0) { - video_frame->AddDestructionObserver(base::Bind( - &OnVideoFrameDestruct, base::ThreadTaskRunnerHandle::Get(), - base::Bind(&VideoResourceUpdater::MarkOldResource, AsWeakPtr(), - base::Unretained(video_frame.get()), - video_frame->timestamp()))); - } -#endif + plane_resource.SetUniqueId(video_frame->unique_id(), i); } - if (plane_resource.resource_format == LUMINANCE_F16) { + if (plane_resource.resource_format() == LUMINANCE_F16) { // By OR-ing with 0x3800, 10-bit numbers become half-floats in the // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). // @@ -559,11 +514,11 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( } external_resources.mailboxes.push_back( - TextureMailbox(plane_resource.mailbox, gpu::SyncToken(), + TextureMailbox(plane_resource.mailbox(), gpu::SyncToken(), resource_provider_->GetResourceTextureTarget( - plane_resource.resource_id))); - external_resources.release_callbacks.push_back( - base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id)); + plane_resource.resource_id()))); + external_resources.release_callbacks.push_back(base::Bind( + &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); } external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; @@ -609,10 +564,10 @@ void VideoResourceUpdater::CopyPlaneTexture( for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { // Reuse resource if attributes match and the resource is a currently // unreferenced texture. - if (it->resource_size == output_plane_resource_size && - it->resource_format == copy_target_format && !it->mailbox.IsZero() && - it->ref_count == 0 && - resource_provider_->GetTextureHint(it->resource_id) != + if (it->resource_size() == output_plane_resource_size && + it->resource_format() == copy_target_format && + !it->mailbox().IsZero() && !it->has_refs() && + resource_provider_->GetTextureHint(it->resource_id()) != ResourceProvider::TEXTURE_HINT_IMMUTABLE) { resource = it; break; @@ -626,14 +581,15 @@ void VideoResourceUpdater::CopyPlaneTexture( true, is_immutable); } - ++resource->ref_count; + resource->add_ref(); ResourceProvider::ScopedWriteLockGL lock(resource_provider_, - resource->resource_id); + resource->resource_id()); uint32_t texture_id = lock.texture_id(); - DCHECK_EQ(resource_provider_->GetResourceTextureTarget(resource->resource_id), - (GLenum)GL_TEXTURE_2D); + DCHECK_EQ( + resource_provider_->GetResourceTextureTarget(resource->resource_id()), + (GLenum)GL_TEXTURE_2D); gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); uint32_t src_texture_id = gl->CreateAndConsumeTextureCHROMIUM( @@ -653,12 +609,12 @@ void VideoResourceUpdater::CopyPlaneTexture( // Done with the source video frame texture at this point. video_frame->UpdateReleaseSyncToken(&client); - external_resources->mailboxes.push_back( - TextureMailbox(resource->mailbox, sync_token, GL_TEXTURE_2D, - video_frame->coded_size(), false, false)); + external_resources->mailboxes.push_back(TextureMailbox( + resource->mailbox(), sync_token, GL_TEXTURE_2D, video_frame->coded_size(), + gfx::GpuMemoryBufferId(), false, false)); external_resources->release_callbacks.push_back( - base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id)); + base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id())); } VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( @@ -691,12 +647,13 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( media::VideoFrameMetadata::COPY_REQUIRED)) { CopyPlaneTexture(video_frame.get(), mailbox_holder, &external_resources); } else { - external_resources.mailboxes.push_back(TextureMailbox( - mailbox_holder.mailbox, mailbox_holder.sync_token, - mailbox_holder.texture_target, video_frame->coded_size(), - video_frame->metadata()->IsTrue( - media::VideoFrameMetadata::ALLOW_OVERLAY), - false)); + external_resources.mailboxes.push_back( + TextureMailbox(mailbox_holder.mailbox, mailbox_holder.sync_token, + mailbox_holder.texture_target, + video_frame->coded_size(), gfx::GpuMemoryBufferId(), + video_frame->metadata()->IsTrue( + media::VideoFrameMetadata::ALLOW_OVERLAY), + false)); external_resources.release_callbacks.push_back( base::Bind(&ReturnTexture, AsWeakPtr(), video_frame)); @@ -720,7 +677,7 @@ void VideoResourceUpdater::RecycleResource( const ResourceList::iterator resource_it = std::find_if( updater->all_resources_.begin(), updater->all_resources_.end(), [resource_id](const PlaneResource& plane_resource) { - return plane_resource.resource_id == resource_id; + return plane_resource.resource_id() == resource_id; }); if (resource_it == updater->all_resources_.end()) return; @@ -732,35 +689,12 @@ void VideoResourceUpdater::RecycleResource( } if (lost_resource) { - resource_it->ref_count = 0; + resource_it->clear_refs(); updater->DeleteResource(resource_it); return; } - --resource_it->ref_count; - DCHECK_GE(resource_it->ref_count, 0); -} - -#if DCHECK_IS_ON() -// static -void VideoResourceUpdater::MarkOldResource( - base::WeakPtr<VideoResourceUpdater> updater, - const media::VideoFrame* video_frame_ptr, - base::TimeDelta timestamp) { - if (!updater) - return; - const ResourceList::iterator resource_it = std::find_if( - updater->all_resources_.begin(), updater->all_resources_.end(), - [video_frame_ptr, timestamp](const PlaneResource& plane_resource) { - return plane_resource.frame_ptr == video_frame_ptr && - plane_resource.timestamp == timestamp && - plane_resource.plane_index == 0; - }); - if (resource_it == updater->all_resources_.end()) - return; - - resource_it->destructed = true; + resource_it->remove_ref(); } -#endif } // namespace cc diff --git a/chromium/cc/resources/video_resource_updater.h b/chromium/cc/resources/video_resource_updater.h index 9af50b2c875..96ba4823768 100644 --- a/chromium/cc/resources/video_resource_updater.h +++ b/chromium/cc/resources/video_resource_updater.h @@ -9,11 +9,11 @@ #include <stdint.h> #include <list> +#include <memory> #include <vector> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "cc/base/cc_export.h" @@ -42,7 +42,6 @@ class CC_EXPORT VideoFrameExternalResources { RGBA_PREMULTIPLIED_RESOURCE, RGBA_RESOURCE, STREAM_TEXTURE_RESOURCE, - IO_SURFACE, #if defined(VIDEO_HOLE) // TODO(danakj): Implement this with a solid color layer instead of a video @@ -87,44 +86,51 @@ class CC_EXPORT VideoResourceUpdater scoped_refptr<media::VideoFrame> video_frame); private: - struct PlaneResource { - unsigned resource_id; - gfx::Size resource_size; - ResourceFormat resource_format; - gpu::Mailbox mailbox; - // The balance between the number of times this resource has been returned - // from CreateForSoftwarePlanes vs released in RecycleResource. - int ref_count; - // These last three members will be used for identifying the data stored in - // this resource, and uniquely identifies a media::VideoFrame plane. The - // frame pointer will only be used for pointer comparison, i.e. the - // underlying data will not be accessed. - const void* frame_ptr; -#if DCHECK_IS_ON() - // This is marked true when the orginal VideoFrame is destructed. It is - // used to detect clients that are not setting the VideoFrame's timestamp - // field correctly, as required. The memory allocator can and will re-use - // the same pointer for new VideoFrame instances, so a destruction observer - // is used to detect that. - bool destructed; -#endif - size_t plane_index; - base::TimeDelta timestamp; - + class PlaneResource { + public: PlaneResource(unsigned resource_id, const gfx::Size& resource_size, ResourceFormat resource_format, gpu::Mailbox mailbox); PlaneResource(const PlaneResource& other); - }; - static bool PlaneResourceMatchesUniqueID(const PlaneResource& plane_resource, - const media::VideoFrame* video_frame, - size_t plane_index); + // Returns true if this resource matches the unique identifiers of another + // VideoFrame resource. + bool Matches(int unique_frame_id, size_t plane_index); + + // Sets the unique identifiers for this resource, may only be called when + // there is a single reference to the resource (i.e. |ref_count_| == 1). + void SetUniqueId(int unique_frame_id, size_t plane_index); - static void SetPlaneResourceUniqueId(const media::VideoFrame* video_frame, - size_t plane_index, - PlaneResource* plane_resource); + // Accessors for resource identifiers provided at construction time. + unsigned resource_id() const { return resource_id_; } + const gfx::Size& resource_size() const { return resource_size_; } + ResourceFormat resource_format() const { return resource_format_; } + const gpu::Mailbox& mailbox() const { return mailbox_; } + + // Various methods for managing references. See |ref_count_| for details. + void add_ref() { ++ref_count_; } + void remove_ref() { --ref_count_; } + void clear_refs() { ref_count_ = 0; } + bool has_refs() const { return ref_count_ != 0; } + + private: + // The balance between the number of times this resource has been returned + // from CreateForSoftwarePlanes vs released in RecycleResource. + int ref_count_ = 0; + + // These two members are used for identifying the data stored in this + // resource; they uniquely identify a media::VideoFrame plane. + int unique_frame_id_ = 0; + size_t plane_index_ = 0u; + // Indicates if the above two members have been set or not. + bool has_unique_frame_id_and_plane_index_ = false; + + const unsigned resource_id_; + const gfx::Size resource_size_; + const ResourceFormat resource_format_; + const gpu::Mailbox mailbox_; + }; // This needs to be a container where iterators can be erased without // invalidating other iterators. @@ -152,16 +158,10 @@ class CC_EXPORT VideoResourceUpdater const gpu::SyncToken& sync_token, bool lost_resource, BlockingTaskRunner* main_thread_task_runner); -#if DCHECK_IS_ON() - // Mark the |destructed| as true when the orginal VideoFrame is destructed. - static void MarkOldResource(base::WeakPtr<VideoResourceUpdater> updater, - const media::VideoFrame* video_frame_ptr, - base::TimeDelta timestamp); -#endif ContextProvider* context_provider_; ResourceProvider* resource_provider_; - scoped_ptr<media::SkCanvasVideoRenderer> video_renderer_; + std::unique_ptr<media::SkCanvasVideoRenderer> video_renderer_; std::vector<uint8_t> upload_pixels_; // Recycle resources so that we can reduce the number of allocations and diff --git a/chromium/cc/resources/video_resource_updater_unittest.cc b/chromium/cc/resources/video_resource_updater_unittest.cc index 4adf83720fd..bf8302af0cb 100644 --- a/chromium/cc/resources/video_resource_updater_unittest.cc +++ b/chromium/cc/resources/video_resource_updater_unittest.cc @@ -7,6 +7,7 @@ #include <stddef.h> #include <stdint.h> +#include "base/memory/ptr_util.h" #include "cc/resources/resource_provider.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" @@ -70,7 +71,7 @@ class WebGraphicsContext3DUploadCounter : public TestWebGraphicsContext3D { class SharedBitmapManagerAllocationCounter : public TestSharedBitmapManager { public: - scoped_ptr<SharedBitmap> AllocateSharedBitmap( + std::unique_ptr<SharedBitmap> AllocateSharedBitmap( const gfx::Size& size) override { ++allocation_count_; return TestSharedBitmapManager::AllocateSharedBitmap(size); @@ -86,7 +87,7 @@ class SharedBitmapManagerAllocationCounter : public TestSharedBitmapManager { class VideoResourceUpdaterTest : public testing::Test { protected: VideoResourceUpdaterTest() { - scoped_ptr<WebGraphicsContext3DUploadCounter> context3d( + std::unique_ptr<WebGraphicsContext3DUploadCounter> context3d( new WebGraphicsContext3DUploadCounter()); context3d_ = context3d.get(); @@ -100,7 +101,7 @@ class VideoResourceUpdaterTest : public testing::Test { testing::Test::SetUp(); output_surface_software_ = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); CHECK(output_surface_software_->BindToClient(&client_)); shared_bitmap_manager_.reset(new SharedBitmapManagerAllocationCounter()); @@ -185,15 +186,16 @@ class VideoResourceUpdaterTest : public testing::Test { const gpu::SyncToken sync_token( gpu::CommandBufferNamespace::GPU_IO, 0, gpu::CommandBufferId::FromUnsafeValue(0x123), 7); + gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes] = { + gpu::MailboxHolder(mailbox, sync_token, target)}; scoped_refptr<media::VideoFrame> video_frame = - media::VideoFrame::WrapNativeTexture( - media::PIXEL_FORMAT_ARGB, - gpu::MailboxHolder(mailbox, sync_token, target), - base::Bind(&ReleaseMailboxCB), - size, // coded_size - gfx::Rect(size), // visible_rect - size, // natural_size - base::TimeDelta()); // timestamp + media::VideoFrame::WrapNativeTextures(media::PIXEL_FORMAT_ARGB, + mailbox_holders, + base::Bind(&ReleaseMailboxCB), + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + base::TimeDelta()); // timestamp EXPECT_TRUE(video_frame); return video_frame; } @@ -215,39 +217,36 @@ class VideoResourceUpdaterTest : public testing::Test { const int kDimension = 10; gfx::Size size(kDimension, kDimension); - const int kPlanesNum = 3; - gpu::Mailbox mailbox[kPlanesNum]; - for (int i = 0; i < kPlanesNum; ++i) { - mailbox[i].name[0] = 50 + 1; - } const gpu::SyncToken sync_token( gpu::CommandBufferNamespace::GPU_IO, 0, gpu::CommandBufferId::FromUnsafeValue(0x123), 7); const unsigned target = GL_TEXTURE_RECTANGLE_ARB; + const int kPlanesNum = 3; + gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes]; + for (int i = 0; i < kPlanesNum; ++i) { + gpu::Mailbox mailbox; + mailbox.name[0] = 50 + 1; + mailbox_holders[i] = gpu::MailboxHolder(mailbox, sync_token, target); + } scoped_refptr<media::VideoFrame> video_frame = - media::VideoFrame::WrapYUV420NativeTextures( - gpu::MailboxHolder(mailbox[media::VideoFrame::kYPlane], sync_token, - target), - gpu::MailboxHolder(mailbox[media::VideoFrame::kUPlane], sync_token, - target), - gpu::MailboxHolder(mailbox[media::VideoFrame::kVPlane], sync_token, - target), - base::Bind(&ReleaseMailboxCB), - size, // coded_size - gfx::Rect(size), // visible_rect - size, // natural_size - base::TimeDelta()); // timestamp + media::VideoFrame::WrapNativeTextures(media::PIXEL_FORMAT_I420, + mailbox_holders, + base::Bind(&ReleaseMailboxCB), + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + base::TimeDelta()); // timestamp EXPECT_TRUE(video_frame); return video_frame; } WebGraphicsContext3DUploadCounter* context3d_; FakeOutputSurfaceClient client_; - scoped_ptr<FakeOutputSurface> output_surface3d_; - scoped_ptr<FakeOutputSurface> output_surface_software_; - scoped_ptr<SharedBitmapManagerAllocationCounter> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider3d_; - scoped_ptr<ResourceProvider> resource_provider_software_; + std::unique_ptr<FakeOutputSurface> output_surface3d_; + std::unique_ptr<FakeOutputSurface> output_surface_software_; + std::unique_ptr<SharedBitmapManagerAllocationCounter> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider3d_; + std::unique_ptr<ResourceProvider> resource_provider_software_; }; TEST_F(VideoResourceUpdaterTest, SoftwareFrame) { diff --git a/chromium/cc/scheduler/begin_frame_source.cc b/chromium/cc/scheduler/begin_frame_source.cc index a0cf3627ea7..bf717470c7e 100644 --- a/chromium/cc/scheduler/begin_frame_source.cc +++ b/chromium/cc/scheduler/begin_frame_source.cc @@ -48,14 +48,6 @@ void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) { } } -void BeginFrameObserverBase::AsValueInto( - base::trace_event::TracedValue* dict) const { - dict->BeginDictionary("last_begin_frame_args_"); - last_begin_frame_args_.AsValueInto(dict); - dict->EndDictionary(); - dict->SetInteger("dropped_begin_frame_args_", dropped_begin_frame_args_); -} - // BeginFrameSourceBase ------------------------------------------------------ BeginFrameSourceBase::BeginFrameSourceBase() : paused_(false), inside_as_value_into_(false) {} @@ -90,8 +82,8 @@ void BeginFrameSourceBase::CallOnBeginFrame(const BeginFrameArgs& args) { DEBUG_FRAMES("BeginFrameSourceBase::CallOnBeginFrame", "num observers", observers_.size(), "args", args.AsValue()); std::set<BeginFrameObserver*> observers(observers_); - for (auto& it : observers) - it->OnBeginFrame(args); + for (BeginFrameObserver* obs : observers) + obs->OnBeginFrame(args); } void BeginFrameSourceBase::SetBeginFrameSourcePaused(bool paused) { @@ -99,31 +91,8 @@ void BeginFrameSourceBase::SetBeginFrameSourcePaused(bool paused) { return; paused_ = paused; std::set<BeginFrameObserver*> observers(observers_); - for (auto& it : observers) - it->OnBeginFrameSourcePausedChanged(paused_); -} - -// Tracing support -void BeginFrameSourceBase::AsValueInto( - base::trace_event::TracedValue* dict) const { - // As the observer might try to trace the source, prevent an infinte loop - // from occuring. - if (inside_as_value_into_) { - dict->SetString("observer", "<loop detected>"); - return; - } - - { - base::AutoReset<bool> prevent_loops( - const_cast<bool*>(&inside_as_value_into_), true); - dict->BeginArray("observers"); - for (const auto& it : observers_) { - dict->BeginDictionary(); - it->AsValueInto(dict); - dict->EndDictionary(); - } - dict->EndArray(); - } + for (BeginFrameObserver* obs : observers) + obs->OnBeginFrameSourcePausedChanged(paused_); } // BackToBackBeginFrameSource -------------------------------------------- @@ -142,49 +111,52 @@ base::TimeTicks BackToBackBeginFrameSource::Now() { // BeginFrameSourceBase support void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) { - DCHECK(observers_.empty()) - << "BackToBackBeginFrameSource only supports a single observer"; BeginFrameSourceBase::AddObserver(obs); + pending_begin_frame_observers_.insert(obs); + PostPendingBeginFramesTask(); } -void BackToBackBeginFrameSource::OnNeedsBeginFramesChanged( - bool needs_begin_frames) { - if (needs_begin_frames) { - PostBeginFrame(); - } else { +void BackToBackBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { + BeginFrameSourceBase::RemoveObserver(obs); + pending_begin_frame_observers_.erase(obs); + if (pending_begin_frame_observers_.empty()) begin_frame_task_.Cancel(); +} + +void BackToBackBeginFrameSource::DidFinishFrame(BeginFrameObserver* obs, + size_t remaining_frames) { + BeginFrameSourceBase::DidFinishFrame(obs, remaining_frames); + if (remaining_frames == 0 && observers_.find(obs) != observers_.end()) { + pending_begin_frame_observers_.insert(obs); + PostPendingBeginFramesTask(); } } -void BackToBackBeginFrameSource::PostBeginFrame() { +void BackToBackBeginFrameSource::PostPendingBeginFramesTask() { DCHECK(needs_begin_frames()); - begin_frame_task_.Reset(base::Bind(&BackToBackBeginFrameSource::BeginFrame, - weak_factory_.GetWeakPtr())); - task_runner_->PostTask(FROM_HERE, begin_frame_task_.callback()); + DCHECK(!pending_begin_frame_observers_.empty()); + if (begin_frame_task_.IsCancelled()) { + begin_frame_task_.Reset( + base::Bind(&BackToBackBeginFrameSource::SendPendingBeginFrames, + weak_factory_.GetWeakPtr())); + task_runner_->PostTask(FROM_HERE, begin_frame_task_.callback()); + } } -void BackToBackBeginFrameSource::BeginFrame() { +void BackToBackBeginFrameSource::SendPendingBeginFrames() { DCHECK(needs_begin_frames()); DCHECK(!begin_frame_task_.IsCancelled()); begin_frame_task_.Cancel(); + base::TimeTicks now = Now(); BeginFrameArgs args = BeginFrameArgs::Create( BEGINFRAME_FROM_HERE, now, now + BeginFrameArgs::DefaultInterval(), BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL); - CallOnBeginFrame(args); -} -void BackToBackBeginFrameSource::DidFinishFrame(size_t remaining_frames) { - BeginFrameSourceBase::DidFinishFrame(remaining_frames); - if (needs_begin_frames() && remaining_frames == 0) - PostBeginFrame(); -} - -// Tracing support -void BackToBackBeginFrameSource::AsValueInto( - base::trace_event::TracedValue* dict) const { - dict->SetString("type", "BackToBackBeginFrameSource"); - BeginFrameSourceBase::AsValueInto(dict); + std::set<BeginFrameObserver*> pending_observers; + pending_observers.swap(pending_begin_frame_observers_); + for (BeginFrameObserver* obs : pending_observers) + obs->OnBeginFrame(args); } // SyntheticBeginFrameSource --------------------------------------------- @@ -197,7 +169,7 @@ SyntheticBeginFrameSource::SyntheticBeginFrameSource( } SyntheticBeginFrameSource::SyntheticBeginFrameSource( - scoped_ptr<DelayBasedTimeSource> time_source) + std::unique_ptr<DelayBasedTimeSource> time_source) : time_source_(std::move(time_source)) { time_source_->SetClient(this); } @@ -205,9 +177,19 @@ SyntheticBeginFrameSource::SyntheticBeginFrameSource( SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {} void SyntheticBeginFrameSource::OnUpdateVSyncParameters( - base::TimeTicks new_vsync_timebase, - base::TimeDelta new_vsync_interval) { - time_source_->SetTimebaseAndInterval(new_vsync_timebase, new_vsync_interval); + base::TimeTicks timebase, + base::TimeDelta interval) { + if (!authoritative_interval_.is_zero()) + interval = authoritative_interval_; + + last_timebase_ = timebase; + time_source_->SetTimebaseAndInterval(timebase, interval); +} + +void SyntheticBeginFrameSource::SetAuthoritativeVSyncInterval( + base::TimeDelta interval) { + authoritative_interval_ = interval; + OnUpdateVSyncParameters(last_timebase_, interval); } BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs( @@ -252,15 +234,4 @@ void SyntheticBeginFrameSource::OnTimerTick() { } } -// Tracing support -void SyntheticBeginFrameSource::AsValueInto( - base::trace_event::TracedValue* dict) const { - dict->SetString("type", "SyntheticBeginFrameSource"); - BeginFrameSourceBase::AsValueInto(dict); - - dict->BeginDictionary("time_source"); - time_source_->AsValueInto(dict); - dict->EndDictionary(); -} - } // namespace cc diff --git a/chromium/cc/scheduler/begin_frame_source.h b/chromium/cc/scheduler/begin_frame_source.h index fb0c8c3f40c..cb23667a274 100644 --- a/chromium/cc/scheduler/begin_frame_source.h +++ b/chromium/cc/scheduler/begin_frame_source.h @@ -61,9 +61,6 @@ class CC_EXPORT BeginFrameObserver { virtual const BeginFrameArgs& LastUsedBeginFrameArgs() const = 0; virtual void OnBeginFrameSourcePausedChanged(bool paused) = 0; - - // Tracing support - virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0; }; // Simple base class which implements a BeginFrameObserver which checks the @@ -87,9 +84,6 @@ class CC_EXPORT BeginFrameObserverBase : public BeginFrameObserver { void OnBeginFrame(const BeginFrameArgs& args) override; const BeginFrameArgs& LastUsedBeginFrameArgs() const override; - // Outputs last_begin_frame_args_ - void AsValueInto(base::trace_event::TracedValue* dict) const override; - protected: // Subclasses should override this method! // Return true if the given argument is (or will be) used. @@ -119,16 +113,13 @@ class CC_EXPORT BeginFrameSource { // processing (rather than toggling SetNeedsBeginFrames every frame). It is // used by systems like the BackToBackFrameSource to make sure only one frame // is pending at a time. - virtual void DidFinishFrame(size_t remaining_frames) = 0; + virtual void DidFinishFrame(BeginFrameObserver* obs, + size_t remaining_frames) = 0; // Add/Remove an observer from the source. When no observers are added the BFS // should shut down its timers, disable vsync, etc. virtual void AddObserver(BeginFrameObserver* obs) = 0; virtual void RemoveObserver(BeginFrameObserver* obs) = 0; - - // Tracing support - Recommend (but not required) to call this implementation - // in any override. - virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0; }; // Simple base class which implements a BeginFrameSource. @@ -136,21 +127,16 @@ class CC_EXPORT BeginFrameSource { // - 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 BeginFrameSourceBase::AsValueInto -// in their own AsValueInto implementation. class CC_EXPORT BeginFrameSourceBase : public BeginFrameSource { public: ~BeginFrameSourceBase() override; // BeginFrameSource - void DidFinishFrame(size_t remaining_frames) override {} + void DidFinishFrame(BeginFrameObserver* obs, + size_t remaining_frames) override {} void AddObserver(BeginFrameObserver* obs) override; void RemoveObserver(BeginFrameObserver* obs) override; - // Tracing support - Recommend (but not required) to call this implementation - // in any override. - void AsValueInto(base::trace_event::TracedValue* dict) const override; - protected: BeginFrameSourceBase(); @@ -183,23 +169,20 @@ class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSourceBase { ~BackToBackBeginFrameSource() override; // BeginFrameSource - void DidFinishFrame(size_t remaining_frames) override; - - // BeginFrameSourceBase void AddObserver(BeginFrameObserver* obs) override; - void OnNeedsBeginFramesChanged(bool needs_begin_frames) override; - - // Tracing - void AsValueInto(base::trace_event::TracedValue* dict) const override; + void RemoveObserver(BeginFrameObserver* obs) override; + void DidFinishFrame(BeginFrameObserver* obs, + size_t remaining_frames) override; protected: virtual base::TimeTicks Now(); // Now overridable for testing base::SingleThreadTaskRunner* task_runner_; base::CancelableClosure begin_frame_task_; + std::set<BeginFrameObserver*> pending_begin_frame_observers_; - void PostBeginFrame(); - void BeginFrame(); + void PostPendingBeginFramesTask(); + void SendPendingBeginFrames(); private: base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_; @@ -215,19 +198,18 @@ class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSourceBase, explicit SyntheticBeginFrameSource(base::SingleThreadTaskRunner* task_runner, base::TimeDelta initial_vsync_interval); explicit SyntheticBeginFrameSource( - scoped_ptr<DelayBasedTimeSource> time_source); + std::unique_ptr<DelayBasedTimeSource> time_source); ~SyntheticBeginFrameSource() override; - void OnUpdateVSyncParameters(base::TimeTicks new_vsync_timebase, - base::TimeDelta new_vsync_interval); + void OnUpdateVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval); + // This overrides any past or future interval from updating vsync parameters. + void SetAuthoritativeVSyncInterval(base::TimeDelta interval); // BeginFrameSourceBase void AddObserver(BeginFrameObserver* obs) override; void OnNeedsBeginFramesChanged(bool needs_begin_frames) override; - // Tracing - void AsValueInto(base::trace_event::TracedValue* dict) const override; - // DelayBasedTimeSourceClient void OnTimerTick() override; @@ -235,7 +217,9 @@ class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSourceBase, BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time, BeginFrameArgs::BeginFrameArgsType type); - scoped_ptr<DelayBasedTimeSource> time_source_; + std::unique_ptr<DelayBasedTimeSource> time_source_; + base::TimeTicks last_timebase_; + base::TimeDelta authoritative_interval_; private: DISALLOW_COPY_AND_ASSIGN(SyntheticBeginFrameSource); diff --git a/chromium/cc/scheduler/begin_frame_source_unittest.cc b/chromium/cc/scheduler/begin_frame_source_unittest.cc index 37b0a639b15..fbeba81732a 100644 --- a/chromium/cc/scheduler/begin_frame_source_unittest.cc +++ b/chromium/cc/scheduler/begin_frame_source_unittest.cc @@ -6,6 +6,7 @@ #include <stdint.h> +#include "base/memory/ptr_util.h" #include "base/test/test_simple_task_runner.h" #include "cc/test/begin_frame_args_test.h" #include "cc/test/begin_frame_source_test.h" @@ -172,38 +173,6 @@ TEST(BeginFrameSourceBaseTest, MultipleObservers) { source.RemoveObserver(&obs2); } -class LoopingBeginFrameObserver : public BeginFrameObserverBase { - public: - BeginFrameSource* source_; - - void AsValueInto(base::trace_event::TracedValue* dict) const override { - dict->SetString("type", "LoopingBeginFrameObserver"); - dict->BeginDictionary("source"); - source_->AsValueInto(dict); - dict->EndDictionary(); - } - - protected: - // BeginFrameObserverBase - bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override { - return true; - } - - void OnBeginFrameSourcePausedChanged(bool paused) override {} -}; - -TEST(BeginFrameSourceBaseTest, DetectAsValueIntoLoop) { - LoopingBeginFrameObserver obs; - FakeBeginFrameSource source; - - obs.source_ = &source; - source.AddObserver(&obs); - - scoped_ptr<base::trace_event::TracedValue> state( - new base::trace_event::TracedValue()); - source.AsValueInto(state.get()); -} - // BackToBackBeginFrameSource testing ----------------------------------------- class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource { public: @@ -223,10 +192,10 @@ class BackToBackBeginFrameSourceTest : public ::testing::Test { static const int64_t kDeadline; static const int64_t kInterval; - scoped_ptr<base::SimpleTestTickClock> now_src_; + std::unique_ptr<base::SimpleTestTickClock> now_src_; scoped_refptr<OrderedSimpleTaskRunner> task_runner_; - scoped_ptr<TestBackToBackBeginFrameSource> source_; - scoped_ptr<MockBeginFrameObserver> obs_; + std::unique_ptr<TestBackToBackBeginFrameSource> source_; + std::unique_ptr<MockBeginFrameObserver> obs_; void SetUp() override { now_src_.reset(new base::SimpleTestTickClock()); @@ -235,7 +204,8 @@ class BackToBackBeginFrameSourceTest : public ::testing::Test { make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_.get(), false)); source_.reset( new TestBackToBackBeginFrameSource(now_src_.get(), task_runner_.get())); - obs_ = make_scoped_ptr(new ::testing::StrictMock<MockBeginFrameObserver>()); + obs_ = + base::WrapUnique(new ::testing::StrictMock<MockBeginFrameObserver>()); } void TearDown() override { obs_.reset(); } @@ -256,7 +226,7 @@ TEST_F(BackToBackBeginFrameSourceTest, AddObserverSendsBeginFrame) { EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval); now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); task_runner_->RunPendingTasks(); } @@ -268,7 +238,7 @@ TEST_F(BackToBackBeginFrameSourceTest, task_runner_->RunPendingTasks(); source_->RemoveObserver(obs_.get()); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); EXPECT_FALSE(task_runner_->HasPendingTasks()); } @@ -281,7 +251,7 @@ TEST_F(BackToBackBeginFrameSourceTest, task_runner_->RunPendingTasks(); now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); source_->RemoveObserver(obs_.get()); EXPECT_TRUE(task_runner_->HasPendingTasks()); @@ -303,7 +273,7 @@ TEST_F(BackToBackBeginFrameSourceTest, source_->AddObserver(obs_.get()); now_src_->Advance(base::TimeDelta::FromMicroseconds(10)); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); now_src_->Advance(base::TimeDelta::FromMicroseconds(10)); EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval); @@ -319,7 +289,7 @@ TEST_F(BackToBackBeginFrameSourceTest, task_runner_->RunPendingTasks(); now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); now_src_->Advance(base::TimeDelta::FromMicroseconds(10)); source_->RemoveObserver(obs_.get()); @@ -338,7 +308,7 @@ TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNoObserver) { EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false); source_->AddObserver(obs_.get()); source_->RemoveObserver(obs_.get()); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); EXPECT_FALSE(task_runner_->RunPendingTasks()); } @@ -350,15 +320,15 @@ TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) { now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); - source_->DidFinishFrame(3); + source_->DidFinishFrame(obs_.get(), 3); EXPECT_FALSE(task_runner_->HasPendingTasks()); - source_->DidFinishFrame(2); + source_->DidFinishFrame(obs_.get(), 2); EXPECT_FALSE(task_runner_->HasPendingTasks()); - source_->DidFinishFrame(1); + source_->DidFinishFrame(obs_.get(), 1); EXPECT_FALSE(task_runner_->HasPendingTasks()); EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); EXPECT_EQ(base::TimeDelta(), task_runner_->DelayToNextTaskTime()); task_runner_->RunPendingTasks(); } @@ -370,16 +340,16 @@ TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) { task_runner_->RunPendingTasks(); now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); - source_->DidFinishFrame(0); - source_->DidFinishFrame(0); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); + source_->DidFinishFrame(obs_.get(), 0); + source_->DidFinishFrame(obs_.get(), 0); EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval); task_runner_->RunPendingTasks(); now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); - source_->DidFinishFrame(0); - source_->DidFinishFrame(0); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); + source_->DidFinishFrame(obs_.get(), 0); + source_->DidFinishFrame(obs_.get(), 0); EXPECT_BEGIN_FRAME_USED(*obs_, 1200, 1200 + kDeadline, kInterval); task_runner_->RunPendingTasks(); } @@ -391,7 +361,7 @@ TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) { task_runner_->RunPendingTasks(); now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); - source_->DidFinishFrame(0); + source_->DidFinishFrame(obs_.get(), 0); now_src_->Advance(base::TimeDelta::FromMicroseconds(50)); EXPECT_BEGIN_FRAME_USED(*obs_, 1150, 1150 + kDeadline, kInterval); @@ -399,13 +369,72 @@ TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) { task_runner_->RunPendingTasks(); } +TEST_F(BackToBackBeginFrameSourceTest, MultipleObserversSynchronized) { + StrictMock<MockBeginFrameObserver> obs1, obs2; + + EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false); + source_->AddObserver(&obs1); + EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false); + source_->AddObserver(&obs2); + + EXPECT_BEGIN_FRAME_USED(obs1, 1000, 1000 + kDeadline, kInterval); + EXPECT_BEGIN_FRAME_USED(obs2, 1000, 1000 + kDeadline, kInterval); + task_runner_->RunPendingTasks(); + + now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); + source_->DidFinishFrame(&obs1, 0); + source_->DidFinishFrame(&obs2, 0); + EXPECT_BEGIN_FRAME_USED(obs1, 1100, 1100 + kDeadline, kInterval); + EXPECT_BEGIN_FRAME_USED(obs2, 1100, 1100 + kDeadline, kInterval); + task_runner_->RunPendingTasks(); + + now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); + source_->DidFinishFrame(&obs1, 0); + source_->DidFinishFrame(&obs2, 0); + EXPECT_TRUE(task_runner_->HasPendingTasks()); + source_->RemoveObserver(&obs1); + source_->RemoveObserver(&obs2); + task_runner_->RunPendingTasks(); +} + +TEST_F(BackToBackBeginFrameSourceTest, MultipleObserversInterleaved) { + StrictMock<MockBeginFrameObserver> obs1, obs2; + + EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false); + source_->AddObserver(&obs1); + EXPECT_BEGIN_FRAME_USED(obs1, 1000, 1000 + kDeadline, kInterval); + task_runner_->RunPendingTasks(); + + now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); + EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false); + source_->AddObserver(&obs2); + EXPECT_BEGIN_FRAME_USED(obs2, 1100, 1100 + kDeadline, kInterval); + task_runner_->RunPendingTasks(); + + now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); + source_->DidFinishFrame(&obs1, 0); + EXPECT_BEGIN_FRAME_USED(obs1, 1200, 1200 + kDeadline, kInterval); + task_runner_->RunPendingTasks(); + + source_->DidFinishFrame(&obs1, 0); + source_->RemoveObserver(&obs1); + + now_src_->Advance(base::TimeDelta::FromMicroseconds(100)); + source_->DidFinishFrame(&obs2, 0); + EXPECT_BEGIN_FRAME_USED(obs2, 1300, 1300 + kDeadline, kInterval); + task_runner_->RunPendingTasks(); + + source_->DidFinishFrame(&obs2, 0); + source_->RemoveObserver(&obs2); +} + // SyntheticBeginFrameSource testing ------------------------------------------ class SyntheticBeginFrameSourceTest : public ::testing::Test { public: - scoped_ptr<base::SimpleTestTickClock> now_src_; + std::unique_ptr<base::SimpleTestTickClock> now_src_; scoped_refptr<OrderedSimpleTaskRunner> task_runner_; - scoped_ptr<TestSyntheticBeginFrameSource> source_; - scoped_ptr<MockBeginFrameObserver> obs_; + std::unique_ptr<TestSyntheticBeginFrameSource> source_; + std::unique_ptr<MockBeginFrameObserver> obs_; void SetUp() override { now_src_.reset(new base::SimpleTestTickClock()); @@ -415,7 +444,7 @@ class SyntheticBeginFrameSourceTest : public ::testing::Test { source_.reset(new TestSyntheticBeginFrameSource( now_src_.get(), task_runner_.get(), base::TimeDelta::FromMicroseconds(10000))); - obs_ = make_scoped_ptr(new MockBeginFrameObserver()); + obs_ = base::WrapUnique(new MockBeginFrameObserver()); } void TearDown() override { obs_.reset(); } @@ -478,6 +507,33 @@ TEST_F(SyntheticBeginFrameSourceTest, VSyncChanges) { task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000)); } +TEST_F(SyntheticBeginFrameSourceTest, AuthoritativeVSyncChanges) { + task_runner_->SetAutoAdvanceNowToPendingTasks(true); + source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(500), + base::TimeDelta::FromMicroseconds(10000)); + EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false); + EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, 500, 10500, 10000); + source_->AddObserver(obs_.get()); + + EXPECT_BEGIN_FRAME_USED(*obs_, 10500, 20500, 10000); + EXPECT_BEGIN_FRAME_USED(*obs_, 20500, 30500, 10000); + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(20501)); + + // This will keep the same timebase, so 500, 9999 + source_->SetAuthoritativeVSyncInterval( + base::TimeDelta::FromMicroseconds(9999)); + EXPECT_BEGIN_FRAME_USED(*obs_, 30500, 40496, 9999); + EXPECT_BEGIN_FRAME_USED(*obs_, 40496, 50495, 9999); + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(40497)); + + // Change the vsync params, but the new interval will be ignored. + source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(400), + base::TimeDelta::FromMicroseconds(1)); + EXPECT_BEGIN_FRAME_USED(*obs_, 50495, 60394, 9999); + EXPECT_BEGIN_FRAME_USED(*obs_, 60394, 70393, 9999); + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60395)); +} + TEST_F(SyntheticBeginFrameSourceTest, MultipleObservers) { StrictMock<MockBeginFrameObserver> obs1, obs2; diff --git a/chromium/cc/scheduler/begin_frame_tracker.cc b/chromium/cc/scheduler/begin_frame_tracker.cc index 20e2c39376d..dc18beaa4d3 100644 --- a/chromium/cc/scheduler/begin_frame_tracker.cc +++ b/chromium/cc/scheduler/begin_frame_tracker.cc @@ -23,7 +23,7 @@ void BeginFrameTracker::Start(BeginFrameArgs new_args) { new_args.frame_time.ToInternalValue(), location_string_); // Trace this specific begin frame tracker Start/Finish times. - TRACE_EVENT_ASYNC_BEGIN2( + TRACE_EVENT_COPY_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()); @@ -54,9 +54,9 @@ const BeginFrameArgs& BeginFrameTracker::Current() const { void BeginFrameTracker::Finish() { DCHECK(!HasFinished()) << "Tried to finish an already finished frame"; current_finished_at_ = base::TimeTicks::Now(); - TRACE_EVENT_ASYNC_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), - location_string_.c_str(), - current_args_.frame_time.ToInternalValue()); + TRACE_EVENT_COPY_ASYNC_END0( + TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), + location_string_.c_str(), current_args_.frame_time.ToInternalValue()); } const BeginFrameArgs& BeginFrameTracker::Last() const { diff --git a/chromium/cc/scheduler/compositor_timing_history.cc b/chromium/cc/scheduler/compositor_timing_history.cc index 9d5a5844e5c..793ad101ec9 100644 --- a/chromium/cc/scheduler/compositor_timing_history.cc +++ b/chromium/cc/scheduler/compositor_timing_history.cc @@ -7,6 +7,7 @@ #include <stddef.h> #include <stdint.h> +#include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" #include "base/trace_event/trace_event.h" #include "cc/debug/rendering_stats_instrumentation.h" @@ -381,21 +382,21 @@ CompositorTimingHistory::CompositorTimingHistory( CompositorTimingHistory::~CompositorTimingHistory() { } -scoped_ptr<CompositorTimingHistory::UMAReporter> +std::unique_ptr<CompositorTimingHistory::UMAReporter> CompositorTimingHistory::CreateUMAReporter(UMACategory category) { switch (category) { case RENDERER_UMA: - return make_scoped_ptr(new RendererUMAReporter); + return base::WrapUnique(new RendererUMAReporter); break; case BROWSER_UMA: - return make_scoped_ptr(new BrowserUMAReporter); + return base::WrapUnique(new BrowserUMAReporter); break; case NULL_UMA: - return make_scoped_ptr(new NullUMAReporter); + return base::WrapUnique(new NullUMAReporter); break; } NOTREACHED(); - return make_scoped_ptr<CompositorTimingHistory::UMAReporter>(nullptr); + return base::WrapUnique<CompositorTimingHistory::UMAReporter>(nullptr); } void CompositorTimingHistory::AsValueInto( diff --git a/chromium/cc/scheduler/compositor_timing_history.h b/chromium/cc/scheduler/compositor_timing_history.h index fc07c619ec5..d85078606a9 100644 --- a/chromium/cc/scheduler/compositor_timing_history.h +++ b/chromium/cc/scheduler/compositor_timing_history.h @@ -5,8 +5,9 @@ #ifndef CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_ #define CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/rolling_time_delta_history.h" namespace base { @@ -85,7 +86,7 @@ class CC_EXPORT CompositorTimingHistory { bool ShouldReportUma() const; - static scoped_ptr<UMAReporter> CreateUMAReporter(UMACategory category); + static std::unique_ptr<UMAReporter> CreateUMAReporter(UMACategory category); virtual base::TimeTicks Now() const; bool using_synchronous_renderer_compositor_; @@ -125,7 +126,7 @@ class CC_EXPORT CompositorTimingHistory { base::TimeTicks draw_start_time_; base::TimeTicks swap_start_time_; - scoped_ptr<UMAReporter> uma_reporter_; + std::unique_ptr<UMAReporter> uma_reporter_; RenderingStatsInstrumentation* rendering_stats_instrumentation_; private: diff --git a/chromium/cc/scheduler/compositor_timing_history_unittest.cc b/chromium/cc/scheduler/compositor_timing_history_unittest.cc index f57d44340c5..8bbe93d999c 100644 --- a/chromium/cc/scheduler/compositor_timing_history_unittest.cc +++ b/chromium/cc/scheduler/compositor_timing_history_unittest.cc @@ -43,7 +43,7 @@ class CompositorTimingHistoryTest : public testing::Test { base::TimeTicks Now() { return now_; } protected: - scoped_ptr<RenderingStatsInstrumentation> rendering_stats_; + std::unique_ptr<RenderingStatsInstrumentation> rendering_stats_; TestCompositorTimingHistory timing_history_; base::TimeTicks now_; }; diff --git a/chromium/cc/scheduler/delay_based_time_source.h b/chromium/cc/scheduler/delay_based_time_source.h index 1be9d9b5a0e..be9e5c4b5d2 100644 --- a/chromium/cc/scheduler/delay_based_time_source.h +++ b/chromium/cc/scheduler/delay_based_time_source.h @@ -5,11 +5,12 @@ #ifndef CC_SCHEDULER_DELAY_BASED_TIME_SOURCE_H_ #define CC_SCHEDULER_DELAY_BASED_TIME_SOURCE_H_ +#include <memory> #include <string> #include "base/cancelable_callback.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/values.h" #include "cc/base/cc_export.h" @@ -35,10 +36,10 @@ class CC_EXPORT DelayBasedTimeSourceClient { // delays. DelayBasedTimeSource uses base::TimeTicks::Now as its timebase. class CC_EXPORT DelayBasedTimeSource { public: - static scoped_ptr<DelayBasedTimeSource> Create( + static std::unique_ptr<DelayBasedTimeSource> Create( base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner) { - return make_scoped_ptr(new DelayBasedTimeSource(interval, task_runner)); + return base::WrapUnique(new DelayBasedTimeSource(interval, task_runner)); } virtual ~DelayBasedTimeSource(); diff --git a/chromium/cc/scheduler/delay_based_time_source_unittest.cc b/chromium/cc/scheduler/delay_based_time_source_unittest.cc index 0acee34efef..7a6d0876aad 100644 --- a/chromium/cc/scheduler/delay_based_time_source_unittest.cc +++ b/chromium/cc/scheduler/delay_based_time_source_unittest.cc @@ -22,7 +22,7 @@ TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); @@ -40,7 +40,7 @@ TEST(DelayBasedTimeSourceTest, TickNotCalledWithTaskPosted) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -54,7 +54,7 @@ TEST(DelayBasedTimeSourceTest, StartTwiceEnqueuesOneTask) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -68,7 +68,7 @@ TEST(DelayBasedTimeSourceTest, StartWhenRunningDoesntTick) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -85,7 +85,7 @@ TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenExactlyOnRequestedTime) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -106,7 +106,7 @@ TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenSlightlyAfterRequestedTime) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -129,7 +129,7 @@ TEST(DelayBasedTimeSourceTest, scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -151,7 +151,7 @@ TEST(DelayBasedTimeSourceTest, scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -173,7 +173,7 @@ TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenHalfAfterRequestedTime) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -193,7 +193,7 @@ TEST(DelayBasedTimeSourceTest, JitteryRuntimeWithFutureTimebases) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -304,7 +304,7 @@ TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); @@ -329,7 +329,7 @@ TEST(DelayBasedTimeSourceTest, TestDeactivateWhilePending) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Should post a task. @@ -344,7 +344,7 @@ TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateBeforeNextTickTime) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_ptr<FakeDelayBasedTimeSource> timer = FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); @@ -369,7 +369,7 @@ TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateAfterNextTickTime) { scoped_refptr<base::TestSimpleTaskRunner> task_runner = new base::TestSimpleTaskRunner; FakeDelayBasedTimeSourceClient client; - scoped_ptr<FakeDelayBasedTimeSource> timer = + std::unique_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 3fb8b3b13de..6696c29afae 100644 --- a/chromium/cc/scheduler/scheduler.cc +++ b/chromium/cc/scheduler/scheduler.cc @@ -8,6 +8,7 @@ #include "base/auto_reset.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/profiler/scoped_tracker.h" #include "base/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" @@ -26,16 +27,16 @@ const base::TimeDelta kDeadlineFudgeFactor = base::TimeDelta::FromMicroseconds(1000); } -scoped_ptr<Scheduler> Scheduler::Create( +std::unique_ptr<Scheduler> Scheduler::Create( SchedulerClient* client, const SchedulerSettings& settings, int layer_tree_host_id, base::SingleThreadTaskRunner* task_runner, BeginFrameSource* begin_frame_source, - scoped_ptr<CompositorTimingHistory> compositor_timing_history) { - return make_scoped_ptr(new Scheduler(client, settings, layer_tree_host_id, - task_runner, begin_frame_source, - std::move(compositor_timing_history))); + std::unique_ptr<CompositorTimingHistory> compositor_timing_history) { + return base::WrapUnique(new Scheduler(client, settings, layer_tree_host_id, + task_runner, begin_frame_source, + std::move(compositor_timing_history))); } Scheduler::Scheduler( @@ -44,7 +45,7 @@ Scheduler::Scheduler( int layer_tree_host_id, base::SingleThreadTaskRunner* task_runner, BeginFrameSource* begin_frame_source, - scoped_ptr<CompositorTimingHistory> compositor_timing_history) + std::unique_ptr<CompositorTimingHistory> compositor_timing_history) : settings_(settings), client_(client), layer_tree_host_id_(layer_tree_host_id), @@ -289,11 +290,6 @@ bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { BeginFrameArgs adjusted_args(args); adjusted_args.deadline -= EstimatedParentDrawTime(); - // Deliver BeginFrames to children. - // TODO(brianderson): Move this responsibility to the DisplayScheduler. - if (state_machine_.children_need_begin_frames()) - client_->SendBeginFramesToChildren(adjusted_args); - if (settings_.using_synchronous_renderer_compositor) { BeginImplFrameSynchronous(adjusted_args); return true; @@ -327,11 +323,6 @@ bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { return true; } -void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { - state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); - ProcessScheduledActions(); -} - void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); ProcessScheduledActions(); @@ -384,7 +375,7 @@ void Scheduler::BeginRetroFrame() { "BeginFrameArgs", begin_retro_frame_args_.front().AsValue()); begin_retro_frame_args_.pop_front(); if (begin_frame_source_) - begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); + begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); } if (begin_retro_frame_args_.empty()) { @@ -478,15 +469,11 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", TRACE_EVENT_SCOPE_THREAD); if (begin_frame_source_) - begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); + begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); return; } BeginImplFrame(adjusted_args); - - // The deadline will be scheduled in ProcessScheduledActions. - state_machine_.OnBeginImplFrameDeadlinePending(); - ProcessScheduledActions(); } void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { @@ -511,7 +498,7 @@ void Scheduler::FinishImplFrame() { client_->DidFinishImplFrame(); if (begin_frame_source_) - begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); + begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); begin_impl_frame_tracker_.Finish(); } @@ -741,32 +728,16 @@ void Scheduler::ProcessScheduledActions() { SetupNextBeginFrameIfNeeded(); } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() - const { - scoped_ptr<base::trace_event::TracedValue> state( +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> +Scheduler::AsValue() const { + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); - AsValueInto(state.get()); - return std::move(state); -} - -void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const { base::TimeTicks now = Now(); state->BeginDictionary("state_machine"); - state_machine_.AsValueInto(state); + state_machine_.AsValueInto(state.get()); state->EndDictionary(); - // Only trace frame sources when explicitly enabled - http://crbug.com/420607 - bool frame_tracing_enabled = false; - TRACE_EVENT_CATEGORY_GROUP_ENABLED( - TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), - &frame_tracing_enabled); - if (frame_tracing_enabled && begin_frame_source_) { - state->BeginDictionary("begin_frame_source_"); - begin_frame_source_->AsValueInto(state); - state->EndDictionary(); - } - state->BeginDictionary("scheduler_state"); state->SetBoolean("throttle_frame_production_", settings_.throttle_frame_production); @@ -784,7 +755,7 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const { SchedulerStateMachine::ActionToString(inside_action_)); state->BeginDictionary("begin_impl_frame_args"); - begin_impl_frame_tracker_.AsValueInto(now, state); + begin_impl_frame_tracker_.AsValueInto(now, state.get()); state->EndDictionary(); state->SetString("begin_impl_frame_deadline_mode_", @@ -793,8 +764,10 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const { state->EndDictionary(); state->BeginDictionary("compositor_timing_history"); - compositor_timing_history_->AsValueInto(state); + compositor_timing_history_->AsValueInto(state.get()); state->EndDictionary(); + + return std::move(state); } void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() { diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h index 6672de44352..017307eb5f9 100644 --- a/chromium/cc/scheduler/scheduler.h +++ b/chromium/cc/scheduler/scheduler.h @@ -6,11 +6,11 @@ #define CC_SCHEDULER_SCHEDULER_H_ #include <deque> +#include <memory> #include <string> #include "base/cancelable_callback.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/output/begin_frame_args.h" @@ -46,7 +46,6 @@ class SchedulerClient { virtual void ScheduledActionPrepareTiles() = 0; virtual void ScheduledActionInvalidateOutputSurface() = 0; virtual void DidFinishImplFrame() = 0; - virtual void SendBeginFramesToChildren(const BeginFrameArgs& args) = 0; virtual void SendBeginMainFrameNotExpectedSoon() = 0; protected: @@ -55,13 +54,13 @@ class SchedulerClient { class CC_EXPORT Scheduler : public BeginFrameObserverBase { public: - static scoped_ptr<Scheduler> Create( + static std::unique_ptr<Scheduler> Create( SchedulerClient* client, const SchedulerSettings& scheduler_settings, int layer_tree_host_id, base::SingleThreadTaskRunner* task_runner, BeginFrameSource* begin_frame_source, - scoped_ptr<CompositorTimingHistory> compositor_timing_history); + std::unique_ptr<CompositorTimingHistory> compositor_timing_history); ~Scheduler() override; @@ -135,10 +134,8 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase { void SetDeferCommits(bool defer_commits); - scoped_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; - void AsValueInto(base::trace_event::TracedValue* value) const override; + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; - void SetChildrenNeedBeginFrames(bool children_need_begin_frames); void SetVideoNeedsBeginFrames(bool video_needs_begin_frames); const BeginFrameSource* begin_frame_source() const { @@ -151,7 +148,7 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase { int layer_tree_host_id, base::SingleThreadTaskRunner* task_runner, BeginFrameSource* begin_frame_source, - scoped_ptr<CompositorTimingHistory> compositor_timing_history); + std::unique_ptr<CompositorTimingHistory> compositor_timing_history); // Virtual for testing. virtual base::TimeTicks Now() const; @@ -166,7 +163,7 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase { BeginFrameSource* begin_frame_source_; bool observing_begin_frame_source_; - scoped_ptr<CompositorTimingHistory> compositor_timing_history_; + std::unique_ptr<CompositorTimingHistory> compositor_timing_history_; base::TimeDelta estimated_parent_draw_time_; std::deque<BeginFrameArgs> begin_retro_frame_args_; diff --git a/chromium/cc/scheduler/scheduler_settings.cc b/chromium/cc/scheduler/scheduler_settings.cc index 79576acc1a4..6f174fa1ba9 100644 --- a/chromium/cc/scheduler/scheduler_settings.cc +++ b/chromium/cc/scheduler/scheduler_settings.cc @@ -24,9 +24,9 @@ SchedulerSettings::SchedulerSettings(const SchedulerSettings& other) = default; SchedulerSettings::~SchedulerSettings() {} -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> SchedulerSettings::AsValue() const { - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); state->SetBoolean("use_external_begin_frame_source", use_external_begin_frame_source); diff --git a/chromium/cc/scheduler/scheduler_settings.h b/chromium/cc/scheduler/scheduler_settings.h index 2f07b30ad54..bc047179444 100644 --- a/chromium/cc/scheduler/scheduler_settings.h +++ b/chromium/cc/scheduler/scheduler_settings.h @@ -5,8 +5,9 @@ #ifndef CC_SCHEDULER_SCHEDULER_SETTINGS_H_ #define CC_SCHEDULER_SCHEDULER_SETTINGS_H_ +#include <memory> + #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "base/values.h" #include "cc/base/cc_export.h" @@ -37,7 +38,7 @@ class CC_EXPORT SchedulerSettings { int maximum_number_of_failed_draws_before_draw_is_forced; base::TimeDelta background_frame_interval; - scoped_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; }; } // namespace cc diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc index 266f8870b56..438447cdfdd 100644 --- a/chromium/cc/scheduler/scheduler_state_machine.cc +++ b/chromium/cc/scheduler/scheduler_state_machine.cc @@ -55,7 +55,6 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) critical_begin_main_frame_to_activate_is_fast_(true), main_thread_missed_last_deadline_(false), skip_next_begin_main_frame_to_reduce_latency_(false), - children_need_begin_frames_(false), defer_commits_(false), video_needs_begin_frames_(false), last_commit_had_no_updates_(false), @@ -86,8 +85,6 @@ const char* SchedulerStateMachine::BeginImplFrameStateToString( switch (state) { case BEGIN_IMPL_FRAME_STATE_IDLE: return "BEGIN_IMPL_FRAME_STATE_IDLE"; - case BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING: - return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING"; case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME: return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME"; case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE: @@ -189,9 +186,9 @@ const char* SchedulerStateMachine::ActionToString(Action action) { return "???"; } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> SchedulerStateMachine::AsValue() const { - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); AsValueInto(state.get()); return std::move(state); @@ -256,7 +253,6 @@ void SchedulerStateMachine::AsValueInto( main_thread_missed_last_deadline_); state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", skip_next_begin_main_frame_to_reduce_latency_); - state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); state->SetBoolean("defer_commits", defer_commits_); state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); @@ -415,18 +411,6 @@ 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; @@ -463,9 +447,6 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { // 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; @@ -473,10 +454,6 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { if (!HasInitializedOutputSurface()) return false; - // Make sure the BeginMainFrame can finish eventually if we start it. - if (SendingBeginMainFrameMightCauseDeadlock()) - return false; - 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. @@ -537,7 +514,7 @@ bool SchedulerStateMachine::ShouldInvalidateOutputSurface() const { return false; // Invalidations are only performed inside a BeginFrame. - if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) + if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) return false; // TODO(sunnyps): needs_prepare_tiles_ is needed here because PrepareTiles is @@ -582,7 +559,11 @@ void SchedulerStateMachine::WillSendBeginMainFrame() { } void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { + DCHECK(!has_pending_tree_ || + (settings_.main_frame_before_activation_enabled && + commit_has_no_updates)); commit_count_++; + last_commit_had_no_updates_ = commit_has_no_updates; if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; @@ -590,11 +571,12 @@ void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION; } - // If the commit was aborted, then there is no pending tree. - has_pending_tree_ = !commit_has_no_updates; - - wait_for_ready_to_draw_ = - !commit_has_no_updates && settings_.commit_to_active_tree; + if (!commit_has_no_updates) { + // Pending tree only exists if commit had updates. + has_pending_tree_ = true; + pending_tree_is_ready_for_activation_ = false; + wait_for_ready_to_draw_ = settings_.commit_to_active_tree; + } // Update state related to forced draws. if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { @@ -604,27 +586,11 @@ void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { } // Update the output surface state. - DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { - if (has_pending_tree_) { - output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION; - } else { - output_surface_state_ = OUTPUT_SURFACE_ACTIVE; - } - } - - // Update state if there's no updates heading for the active tree, but we need - // to do a forced draw. - if (commit_has_no_updates && - forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { - DCHECK(!has_pending_tree_); - needs_redraw_ = true; + output_surface_state_ = has_pending_tree_ + ? OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION + : OUTPUT_SURFACE_ACTIVE; } - - // This post-commit work is common to both completed and aborted commits. - pending_tree_is_ready_for_activation_ = false; - - last_commit_had_no_updates_ = commit_has_no_updates; } void SchedulerStateMachine::WillActivate() { @@ -765,10 +731,6 @@ void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { skip_next_begin_main_frame_to_reduce_latency_ = true; } -bool SchedulerStateMachine::BeginFrameRequiredForChildren() const { - return children_need_begin_frames_; -} - bool SchedulerStateMachine::BeginFrameNeededForVideo() const { return video_needs_begin_frames_; } @@ -783,13 +745,8 @@ bool SchedulerStateMachine::BeginFrameNeeded() const { if (!visible_) return false; - return (BeginFrameRequiredForAction() || BeginFrameRequiredForChildren() || - BeginFrameNeededForVideo() || ProactiveBeginFrameWanted()); -} - -void SchedulerStateMachine::SetChildrenNeedBeginFrames( - bool children_need_begin_frames) { - children_need_begin_frames_ = children_need_begin_frames; + return BeginFrameRequiredForAction() || BeginFrameNeededForVideo() || + ProactiveBeginFrameWanted(); } void SchedulerStateMachine::SetVideoNeedsBeginFrames( @@ -860,7 +817,7 @@ bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { } void SchedulerStateMachine::OnBeginImplFrame() { - begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; + begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; current_frame_number_++; last_commit_had_no_updates_ = false; @@ -877,10 +834,6 @@ void SchedulerStateMachine::OnBeginImplFrame() { prepare_tiles_funnel_--; } -void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { - begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; -} - void SchedulerStateMachine::OnBeginImplFrameDeadline() { begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; diff --git a/chromium/cc/scheduler/scheduler_state_machine.h b/chromium/cc/scheduler/scheduler_state_machine.h index f1872fe62d0..e89edddd6ec 100644 --- a/chromium/cc/scheduler/scheduler_state_machine.h +++ b/chromium/cc/scheduler/scheduler_state_machine.h @@ -5,10 +5,10 @@ #ifndef CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_ #define CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_ +#include <memory> #include <string> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/begin_frame_args.h" #include "cc/scheduler/commit_earlyout_reason.h" @@ -59,11 +59,8 @@ class CC_EXPORT SchedulerStateMachine { // Note: BeginImplFrameState does not cycle through these states in a fixed // order on all platforms. It's up to the scheduler to set these correctly. - // TODO(sunnyps): Rename the states to IDLE, ANIMATE, WAITING_FOR_DEADLINE and - // DRAW. enum BeginImplFrameState { BEGIN_IMPL_FRAME_STATE_IDLE, - BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, }; @@ -129,7 +126,7 @@ class CC_EXPORT SchedulerStateMachine { }; static const char* ActionToString(Action action); - scoped_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; void AsValueInto(base::trace_event::TracedValue* dict) const; Action NextAction() const; @@ -153,7 +150,6 @@ class CC_EXPORT SchedulerStateMachine { // The scheduler will not draw more than once in a given BeginImplFrame // callback nor send more than one BeginMainFrame message. void OnBeginImplFrame(); - void OnBeginImplFrameDeadlinePending(); // Indicates that the scheduler has entered the draw phase. The scheduler // will not draw more than once in a single draw phase. // TODO(sunnyps): Rename OnBeginImplFrameDeadline to OnDraw or similar. @@ -272,17 +268,11 @@ class CC_EXPORT SchedulerStateMachine { void SetDeferCommits(bool defer_commits); - void SetChildrenNeedBeginFrames(bool children_need_begin_frames); - bool children_need_begin_frames() const { - return children_need_begin_frames_; - } - void SetVideoNeedsBeginFrames(bool video_needs_begin_frames); bool video_needs_begin_frames() const { return video_needs_begin_frames_; } protected: bool BeginFrameRequiredForAction() const; - bool BeginFrameRequiredForChildren() const; bool BeginFrameNeededForVideo() const; bool ProactiveBeginFrameWanted() const; @@ -292,9 +282,6 @@ class CC_EXPORT SchedulerStateMachine { // TODO(sunnyps): Rename this to ShouldAbortCurrentFrame or similar. bool PendingActivationsShouldBeForced() const; - // TODO(brianderson): Remove this once NPAPI support is removed. - bool SendingBeginMainFrameMightCauseDeadlock() const; - bool ShouldBeginOutputSurfaceCreation() const; bool ShouldDraw() const; bool ShouldActivatePendingTree() const; @@ -353,7 +340,6 @@ class CC_EXPORT SchedulerStateMachine { bool critical_begin_main_frame_to_activate_is_fast_; bool main_thread_missed_last_deadline_; bool skip_next_begin_main_frame_to_reduce_latency_; - bool children_need_begin_frames_; bool defer_commits_; bool video_needs_begin_frames_; bool last_commit_had_no_updates_; diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc index ee88bfc1efd..8f86c3d213e 100644 --- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc +++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc @@ -45,9 +45,6 @@ PerformAction(&state, action); \ if (action == SchedulerStateMachine::ACTION_NONE) { \ if (state.begin_impl_frame_state() == \ - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \ - state.OnBeginImplFrameDeadlinePending(); \ - if (state.begin_impl_frame_state() == \ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \ state.OnBeginImplFrameIdle(); \ } @@ -66,7 +63,6 @@ namespace { const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] = {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE, - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING, SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME, SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, }; @@ -149,6 +145,7 @@ class StateMachine : public SchedulerStateMachine { return SchedulerStateMachine::PendingActivationsShouldBeForced(); } + bool has_pending_tree() const { return has_pending_tree_; } void SetHasPendingTree(bool has_pending_tree) { has_pending_tree_ = has_pending_tree; } @@ -426,8 +423,6 @@ TEST(SchedulerStateMachineTest, // Start a frame. state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.OnBeginImplFrameDeadlinePending(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); EXPECT_FALSE(state.CommitPending()); // Failing a draw triggers request for a new BeginMainFrame. @@ -447,8 +442,6 @@ TEST(SchedulerStateMachineTest, EXPECT_TRUE(state.RedrawPending()); state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.OnBeginImplFrameDeadlinePending(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); EXPECT_ACTION_UPDATE_STATE( @@ -469,8 +462,6 @@ TEST(SchedulerStateMachineTest, FailedDrawForMissingHighResNeedsCommit) { // Start a frame. state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.OnBeginImplFrameDeadlinePending(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); EXPECT_FALSE(state.CommitPending()); // Failing a draw triggers because of high res tiles missing @@ -490,8 +481,6 @@ TEST(SchedulerStateMachineTest, FailedDrawForMissingHighResNeedsCommit) { EXPECT_FALSE(state.RedrawPending()); state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.OnBeginImplFrameDeadlinePending(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameIdle(); @@ -510,8 +499,6 @@ TEST(SchedulerStateMachineTest, FailedDrawForMissingHighResNeedsCommit) { // Verify we draw with the new frame. state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.OnBeginImplFrameDeadlinePending(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_SUCCESS); EXPECT_ACTION_UPDATE_STATE( @@ -606,8 +593,6 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { state.SetNeedsRedraw(true); state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.OnBeginImplFrameDeadlinePending(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); EXPECT_ACTION_UPDATE_STATE( @@ -624,25 +609,12 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { EXPECT_TRUE(state.ForcedRedrawState() == SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT); - state.NotifyBeginMainFrameStarted(); - state.NotifyReadyToCommit(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - EXPECT_TRUE(state.RedrawPending()); - EXPECT_FALSE(state.CommitPending()); - - // Now force redraw should be in waiting for activation - EXPECT_TRUE(state.ForcedRedrawState() == - SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION); - // After failing additional draws, we should still be in a forced - // redraw, but not back in WAITING_FOR_COMMIT. + // redraw, but not back in IDLE. for (int i = 0; i < draw_limit; ++i) { state.SetNeedsRedraw(true); state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.OnBeginImplFrameDeadlinePending(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); EXPECT_ACTION_UPDATE_STATE( @@ -653,7 +625,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { } EXPECT_TRUE(state.RedrawPending()); EXPECT_TRUE(state.ForcedRedrawState() == - SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION); + SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT); } TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) { @@ -922,11 +894,6 @@ TEST(SchedulerStateMachineTest, TestSetNeedsBeginMainFrameIsNotLost) { // Expect to commit regardless of BeginImplFrame state. EXPECT_IMPL_FRAME_STATE( - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); - EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); - - state.OnBeginImplFrameDeadlinePending(); - EXPECT_IMPL_FRAME_STATE( SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME); EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); @@ -941,7 +908,7 @@ TEST(SchedulerStateMachineTest, TestSetNeedsBeginMainFrameIsNotLost) { state.OnBeginImplFrame(); EXPECT_IMPL_FRAME_STATE( - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME); EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); // Finish the commit and activate, then make sure we start the next commit @@ -1043,6 +1010,7 @@ TEST(SchedulerStateMachineTest, CommitWithoutDrawWithPendingTree) { TEST(SchedulerStateMachineTest, DontCommitWithoutDrawWithoutPendingTree) { SchedulerSettings scheduler_settings; scheduler_settings.commit_to_active_tree = true; + scheduler_settings.main_frame_before_activation_enabled = false; StateMachine state(scheduler_settings); SET_UP_STATE(state) @@ -1066,9 +1034,65 @@ TEST(SchedulerStateMachineTest, DontCommitWithoutDrawWithoutPendingTree) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } +TEST(SchedulerStateMachineTest, AbortedMainFrameDoesNotResetPendingTree) { + SchedulerSettings scheduler_settings; + scheduler_settings.main_frame_before_activation_enabled = true; + StateMachine state(scheduler_settings); + SET_UP_STATE(state); + + // Perform a commit so that we have an active tree. + state.SetNeedsBeginMainFrame(); + state.OnBeginImplFrame(); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + state.NotifyBeginMainFrameStarted(); + state.NotifyReadyToCommit(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_TRUE(state.has_pending_tree()); + state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + // Ask for another commit but abort it. Verify that we didn't reset pending + // tree state. + state.SetNeedsBeginMainFrame(); + state.OnBeginImplFrame(); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_TRUE(state.has_pending_tree()); + state.NotifyBeginMainFrameStarted(); + state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_TRUE(state.has_pending_tree()); + state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + // Ask for another commit that doesn't abort. + state.SetNeedsBeginMainFrame(); + state.OnBeginImplFrame(); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + state.NotifyBeginMainFrameStarted(); + state.NotifyReadyToCommit(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_TRUE(state.has_pending_tree()); + + // Verify that commit is delayed until the pending tree is activated. + state.NotifyReadyToActivate(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); + EXPECT_FALSE(state.has_pending_tree()); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_TRUE(state.has_pending_tree()); +} + TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) { SchedulerSettings scheduler_settings; scheduler_settings.commit_to_active_tree = true; + scheduler_settings.main_frame_before_activation_enabled = false; StateMachine state(scheduler_settings); SET_UP_STATE(state) @@ -1562,11 +1586,6 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { state.OnBeginImplFrame(); EXPECT_IMPL_FRAME_STATE( - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); - EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); - - state.OnBeginImplFrameDeadlinePending(); - EXPECT_IMPL_FRAME_STATE( SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME); EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); @@ -1624,11 +1643,6 @@ TEST(SchedulerStateMachineTest, state.OnBeginImplFrame(); EXPECT_IMPL_FRAME_STATE( - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); - EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); - - state.OnBeginImplFrameDeadlinePending(); - EXPECT_IMPL_FRAME_STATE( SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME); EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); @@ -2060,16 +2074,6 @@ TEST(SchedulerStateMachineTest, EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); } -TEST(SchedulerStateMachineTest, TestForwardBeginFramesToChildren) { - SchedulerSettings settings; - StateMachine state(settings); - SET_UP_STATE(state) - - EXPECT_FALSE(state.BeginFrameNeeded()); - state.SetChildrenNeedBeginFrames(true); - EXPECT_TRUE(state.BeginFrameNeeded()); -} - TEST(SchedulerStateMachineTest, TestDeferCommit) { SchedulerSettings settings; StateMachine state(settings); @@ -2125,7 +2129,6 @@ TEST(SchedulerStateMachineTest, NoOutputSurfaceCreationWhileCommitPending) { // Trigger the deadline and ensure that the scheduler does not trigger any // actions until we receive a response for the pending commit. - state.OnBeginImplFrameDeadlinePending(); state.OnBeginImplFrameDeadline(); state.OnBeginImplFrameIdle(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -2161,7 +2164,6 @@ TEST(SchedulerStateMachineTest, OutputSurfaceCreationWhileCommitPending) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // Cycle through the frame stages to clear the scheduler state. - state.OnBeginImplFrameDeadlinePending(); state.OnBeginImplFrameDeadline(); state.OnBeginImplFrameIdle(); diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc index 75652c793cb..751c9649e49 100644 --- a/chromium/cc/scheduler/scheduler_unittest.cc +++ b/chromium/cc/scheduler/scheduler_unittest.cc @@ -10,6 +10,7 @@ #include <vector> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/numerics/safe_conversions.h" #include "base/run_loop.h" @@ -66,7 +67,6 @@ class FakeSchedulerClient : public SchedulerClient { draw_will_happen_ = true; swap_will_happen_if_draw_happens_ = true; num_draws_ = 0; - begin_frame_args_sent_to_children_ = BeginFrameArgs(); last_begin_main_frame_args_ = BeginFrameArgs(); } @@ -165,10 +165,6 @@ class FakeSchedulerClient : public SchedulerClient { states_.push_back(scheduler_->AsValue()); } - void SendBeginFramesToChildren(const BeginFrameArgs& args) override { - begin_frame_args_sent_to_children_ = args; - } - void SendBeginMainFrameNotExpectedSoon() override { PushAction("SendBeginMainFrameNotExpectedSoon"); } @@ -179,14 +175,6 @@ class FakeSchedulerClient : public SchedulerClient { state); } - bool begin_frame_is_sent_to_children() const { - return begin_frame_args_sent_to_children_.IsValid(); - } - - const BeginFrameArgs& begin_frame_args_sent_to_children() const { - return begin_frame_args_sent_to_children_; - } - void PushAction(const char* description) { actions_.push_back(description); states_.push_back(scheduler_->AsValue()); @@ -203,11 +191,11 @@ class FakeSchedulerClient : public SchedulerClient { bool swap_will_happen_if_draw_happens_; bool automatic_swap_ack_; int num_draws_; - BeginFrameArgs begin_frame_args_sent_to_children_; BeginFrameArgs last_begin_main_frame_args_; base::TimeTicks posted_begin_impl_frame_deadline_; std::vector<const char*> actions_; - std::vector<scoped_ptr<base::trace_event::ConvertableToTraceFormat>> states_; + std::vector<std::unique_ptr<base::trace_event::ConvertableToTraceFormat>> + states_; TestScheduler* scheduler_; }; @@ -271,8 +259,8 @@ class SchedulerTest : public testing::Test { frame_source = synthetic_frame_source_.get(); } - scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history = - FakeCompositorTimingHistory::Create( + std::unique_ptr<FakeCompositorTimingHistory> + fake_compositor_timing_history = FakeCompositorTimingHistory::Create( scheduler_settings_.using_synchronous_renderer_compositor); fake_compositor_timing_history_ = fake_compositor_timing_history.get(); @@ -295,10 +283,10 @@ class SchedulerTest : public testing::Test { } void SetUpScheduler(bool initSurface) { - SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface); + SetUpScheduler(base::WrapUnique(new FakeSchedulerClient), initSurface); } - void SetUpScheduler(scoped_ptr<FakeSchedulerClient> client, + void SetUpScheduler(std::unique_ptr<FakeSchedulerClient> client, bool initSurface) { client_ = std::move(client); if (initSurface) @@ -437,14 +425,15 @@ class SchedulerTest : public testing::Test { ScrollHandlerState scroll_handler_state, base::TimeDelta durations); - scoped_ptr<base::SimpleTestTickClock> now_src_; + std::unique_ptr<base::SimpleTestTickClock> now_src_; scoped_refptr<OrderedSimpleTaskRunner> task_runner_; - scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_; - scoped_ptr<TestSyntheticBeginFrameSource> synthetic_frame_source_; - scoped_ptr<TestBackToBackBeginFrameSource> unthrottled_frame_source_; + std::unique_ptr<FakeExternalBeginFrameSource> + fake_external_begin_frame_source_; + std::unique_ptr<TestSyntheticBeginFrameSource> synthetic_frame_source_; + std::unique_ptr<TestBackToBackBeginFrameSource> unthrottled_frame_source_; SchedulerSettings scheduler_settings_; - scoped_ptr<FakeSchedulerClient> client_; - scoped_ptr<TestScheduler> scheduler_; + std::unique_ptr<FakeSchedulerClient> client_; + std::unique_ptr<TestScheduler> scheduler_; FakeCompositorTimingHistory* fake_compositor_timing_history_; }; @@ -460,69 +449,6 @@ TEST_F(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) { EXPECT_NO_ACTION(client_); } -TEST_F(SchedulerTest, SendBeginFramesToChildren) { - scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(true); - - EXPECT_FALSE(client_->begin_frame_is_sent_to_children()); - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - scheduler_->SetChildrenNeedBeginFrames(true); - - client_->Reset(); - EXPECT_SCOPED(AdvanceFrame()); - EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); - EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); - EXPECT_TRUE(scheduler_->begin_frames_expected()); -} - -TEST_F(SchedulerTest, SendBeginFramesToChildrenWithoutCommit) { - scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(true); - - EXPECT_FALSE(scheduler_->begin_frames_expected()); - scheduler_->SetChildrenNeedBeginFrames(true); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - client_->Reset(); - EXPECT_SCOPED(AdvanceFrame()); - EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); -} - -TEST_F(SchedulerTest, SendBeginFramesToChildrenDeadlineNotAdjusted) { - // Set up client with specified estimates. - scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(true); - - fake_compositor_timing_history_ - ->SetBeginMainFrameStartToCommitDurationEstimate( - base::TimeDelta::FromMilliseconds(2)); - fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( - base::TimeDelta::FromMilliseconds(4)); - fake_compositor_timing_history_->SetDrawDurationEstimate( - base::TimeDelta::FromMilliseconds(1)); - - EXPECT_FALSE(scheduler_->begin_frames_expected()); - scheduler_->SetChildrenNeedBeginFrames(true); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - client_->Reset(); - - BeginFrameArgs frame_args = - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); - fake_external_begin_frame_source()->TestOnBeginFrame(frame_args); - - EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); - EXPECT_EQ(client_->begin_frame_args_sent_to_children().deadline, - frame_args.deadline); -} - TEST_F(SchedulerTest, VideoNeedsBeginFrames) { scheduler_settings_.use_external_begin_frame_source = true; SetUpScheduler(true); @@ -784,7 +710,7 @@ TEST_F(SchedulerTest, RequestRedrawInsideDraw) { SchedulerClientThatsetNeedsDrawInsideDraw* client = new SchedulerClientThatsetNeedsDrawInsideDraw; scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); client->SetRequestRedrawsInsideDraw(true); scheduler_->SetNeedsRedraw(); @@ -820,7 +746,7 @@ TEST_F(SchedulerTest, RequestRedrawInsideFailedDraw) { SchedulerClientThatsetNeedsDrawInsideDraw* client = new SchedulerClientThatsetNeedsDrawInsideDraw; scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); client->SetRequestRedrawsInsideDraw(true); client->SetDrawWillHappen(false); @@ -896,7 +822,7 @@ TEST_F(SchedulerTest, RequestCommitInsideDraw) { new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw; scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); EXPECT_FALSE(client->needs_begin_frames()); scheduler_->SetNeedsRedraw(); @@ -938,7 +864,7 @@ TEST_F(SchedulerTest, RequestCommitInsideFailedDraw) { SchedulerClientThatsetNeedsDrawInsideDraw* client = new SchedulerClientThatsetNeedsDrawInsideDraw; scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); client->SetDrawWillHappen(false); @@ -981,7 +907,7 @@ TEST_F(SchedulerTest, NoSwapWhenDrawFails) { SchedulerClientThatSetNeedsBeginMainFrameInsideDraw* client = new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw; scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); scheduler_->SetNeedsRedraw(); EXPECT_TRUE(scheduler_->RedrawPending()); @@ -1019,7 +945,7 @@ TEST_F(SchedulerTest, PrepareTiles) { SchedulerClientNeedsPrepareTilesInDraw* client = new SchedulerClientNeedsPrepareTilesInDraw; scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); // Request both draw and prepare tiles. PrepareTiles shouldn't // be trigged until BeginImplFrame. @@ -1229,8 +1155,8 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) { } TEST_F(SchedulerTest, PrepareTilesFunnelResetOnVisibilityChange) { - scoped_ptr<SchedulerClientNeedsPrepareTilesInDraw> client = - make_scoped_ptr(new SchedulerClientNeedsPrepareTilesInDraw); + std::unique_ptr<SchedulerClientNeedsPrepareTilesInDraw> client = + base::WrapUnique(new SchedulerClientNeedsPrepareTilesInDraw); scheduler_settings_.use_external_begin_frame_source = true; SetUpScheduler(std::move(client), true); @@ -1265,7 +1191,7 @@ TEST_F(SchedulerTest, TriggerBeginFrameDeadlineEarly) { SchedulerClientNeedsPrepareTilesInDraw* client = new SchedulerClientNeedsPrepareTilesInDraw; scheduler_settings_.use_external_begin_frame_source = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); scheduler_->SetNeedsRedraw(); EXPECT_SCOPED(AdvanceFrame()); @@ -1280,7 +1206,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) { new SchedulerClientNeedsPrepareTilesInDraw; scheduler_settings_.use_external_begin_frame_source = true; scheduler_settings_.commit_to_active_tree = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. scheduler_->SetNeedsBeginMainFrame(); @@ -1320,7 +1246,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostOutputSurface) { new SchedulerClientNeedsPrepareTilesInDraw; scheduler_settings_.use_external_begin_frame_source = true; scheduler_settings_.commit_to_active_tree = true; - SetUpScheduler(make_scoped_ptr(client), true); + SetUpScheduler(base::WrapUnique(client), true); // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. scheduler_->SetNeedsBeginMainFrame(); @@ -2053,84 +1979,6 @@ TEST_F( EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); } -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. - 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_->SetNeedsBeginMainFrame(); - 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(base::TimeTicks()); - scheduler_->NotifyReadyToCommit(); - EXPECT_FALSE(scheduler_->CommitPending()); - EXPECT_ACTION("AddObserver(this)", client_, 0, 5); - EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 5); - EXPECT_ACTION("ScheduledActionCommit", client_, 4, 5); - - // Start another commit while we still have aa pending tree. - // Enter a swap throttled state. - client_->Reset(); - EXPECT_FALSE(scheduler_->CommitPending()); - scheduler_->SetNeedsBeginMainFrame(); - 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(base::TimeTicks()); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3); - - // 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_->SetNeedsBeginMainFrame(); - EXPECT_SCOPED(AdvanceFrame()); - EXPECT_FALSE(scheduler_->CommitPending()); - task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); -} - TEST_F( SchedulerTest, CommitMakesProgressWhenIdleAndHasPendingTreeAndActiveTreeNeedsFirstDraw) { @@ -3114,12 +2962,9 @@ TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); - client_->Reset(); - + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); // Unthrottled frame source will immediately begin a new frame. - task_runner().RunPendingTasks(); // Run BeginFrame. - EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); + EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2); scheduler_->SetNeedsRedraw(); client_->Reset(); @@ -3544,8 +3389,8 @@ TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) { scheduler_settings_.using_synchronous_renderer_compositor = true; scheduler_settings_.use_external_begin_frame_source = true; - scoped_ptr<FakeSchedulerClient> client = - make_scoped_ptr(new SchedulerClientSetNeedsPrepareTilesOnDraw); + std::unique_ptr<FakeSchedulerClient> client = + base::WrapUnique(new SchedulerClientSetNeedsPrepareTilesOnDraw); SetUpScheduler(std::move(client), true); scheduler_->SetNeedsRedraw(); diff --git a/chromium/cc/surfaces/display.cc b/chromium/cc/surfaces/display.cc index 6866cedc9cf..4776df1bf14 100644 --- a/chromium/cc/surfaces/display.cc +++ b/chromium/cc/surfaces/display.cc @@ -6,7 +6,7 @@ #include <stddef.h> -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "cc/debug/benchmark_instrumentation.h" #include "cc/output/compositor_frame.h" @@ -24,50 +24,98 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "ui/gfx/buffer_types.h" +#if defined(ENABLE_VULKAN) +#include "cc/output/vulkan_renderer.h" +#endif + +namespace { + +class EmptyBeginFrameSource : public cc::BeginFrameSource { + public: + void DidFinishFrame(cc::BeginFrameObserver* obs, + size_t remaining_frames) override{}; + void AddObserver(cc::BeginFrameObserver* obs) override{}; + void RemoveObserver(cc::BeginFrameObserver* obs) override{}; +}; + +} // namespace + namespace cc { Display::Display(DisplayClient* client, SurfaceManager* manager, SharedBitmapManager* bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - const RendererSettings& settings) + const RendererSettings& settings, + uint32_t compositor_surface_namespace) : client_(client), - manager_(manager), + surface_manager_(manager), bitmap_manager_(bitmap_manager), gpu_memory_buffer_manager_(gpu_memory_buffer_manager), settings_(settings), + compositor_surface_namespace_(compositor_surface_namespace), device_scale_factor_(1.f), swapped_since_resize_(false), - scheduler_(nullptr), + vsync_begin_frame_source_(nullptr), + observed_begin_frame_source_(nullptr), texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) { - manager_->AddObserver(this); + surface_manager_->AddObserver(this); } Display::~Display() { - manager_->RemoveObserver(this); + if (observed_begin_frame_source_) + surface_manager_->UnregisterBeginFrameSource(observed_begin_frame_source_); + surface_manager_->RemoveObserver(this); if (aggregator_) { for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { - Surface* surface = manager_->GetSurfaceForId(id_entry.first); + Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); if (surface) surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); } } } -bool Display::Initialize(scoped_ptr<OutputSurface> output_surface, - DisplayScheduler* scheduler) { - // TODO(enne): register/unregister BeginFrameSource with SurfaceManager here. +void Display::CreateScheduler(base::SingleThreadTaskRunner* task_runner) { + DCHECK(!scheduler_); + if (!task_runner) { + // WebView doesn't have a task runner or a real begin frame source, + // so just create something fake here. + internal_begin_frame_source_.reset(new EmptyBeginFrameSource()); + vsync_begin_frame_source_ = internal_begin_frame_source_.get(); + observed_begin_frame_source_ = vsync_begin_frame_source_; + } else { + DCHECK(vsync_begin_frame_source_); + + observed_begin_frame_source_ = vsync_begin_frame_source_; + if (settings_.disable_display_vsync) { + internal_begin_frame_source_.reset( + new BackToBackBeginFrameSource(task_runner)); + observed_begin_frame_source_ = internal_begin_frame_source_.get(); + } + } + + scheduler_.reset( + new DisplayScheduler(this, observed_begin_frame_source_, task_runner, + output_surface_->capabilities().max_frames_pending)); + surface_manager_->RegisterBeginFrameSource(observed_begin_frame_source_, + compositor_surface_namespace_); +} + +bool Display::Initialize(std::unique_ptr<OutputSurface> output_surface, + base::SingleThreadTaskRunner* task_runner) { output_surface_ = std::move(output_surface); - scheduler_ = scheduler; - return output_surface_->BindToClient(this); + if (!output_surface_->BindToClient(this)) + return false; + CreateScheduler(task_runner); + return true; } void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { + DCHECK_EQ(id.id_namespace(), compositor_surface_namespace_); if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) return; TRACE_EVENT0("cc", "Display::SetSurfaceId"); - current_surface_id_ = id; device_scale_factor_ = device_scale_factor; @@ -101,30 +149,56 @@ void Display::SetExternalClip(const gfx::Rect& clip) { external_clip_ = clip; } +void Display::SetOutputIsSecure(bool secure) { + if (secure == output_is_secure_) + return; + output_is_secure_ = secure; + + if (aggregator_) { + aggregator_->set_output_is_secure(secure); + // Force a redraw. + if (!current_surface_id_.is_null()) + aggregator_->SetFullDamageForSurface(current_surface_id_); + } +} + void Display::InitializeRenderer() { if (resource_provider_) return; - scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( - output_surface_.get(), bitmap_manager_, gpu_memory_buffer_manager_, - nullptr, settings_.highp_threshold_min, - settings_.texture_id_allocation_chunk_size, - settings_.use_gpu_memory_buffer_resources, - std::vector<unsigned>(static_cast<size_t>(gfx::BufferFormat::LAST) + 1, - GL_TEXTURE_2D)); + std::unique_ptr<ResourceProvider> resource_provider = + ResourceProvider::Create( + output_surface_.get(), bitmap_manager_, gpu_memory_buffer_manager_, + nullptr, settings_.highp_threshold_min, + settings_.texture_id_allocation_chunk_size, + settings_.use_gpu_memory_buffer_resources, + std::vector<unsigned>( + static_cast<size_t>(gfx::BufferFormat::LAST) + 1, GL_TEXTURE_2D)); if (!resource_provider) return; if (output_surface_->context_provider()) { - scoped_ptr<GLRenderer> renderer = GLRenderer::Create( + std::unique_ptr<GLRenderer> renderer = GLRenderer::Create( this, &settings_, output_surface_.get(), resource_provider.get(), texture_mailbox_deleter_.get(), settings_.highp_threshold_min); if (!renderer) return; renderer_ = std::move(renderer); + } else if (output_surface_->vulkan_context_provider()) { +#if defined(ENABLE_VULKAN) + std::unique_ptr<VulkanRenderer> renderer = VulkanRenderer::Create( + this, &settings_, output_surface_.get(), resource_provider.get(), + texture_mailbox_deleter_.get(), settings_.highp_threshold_min); + if (!renderer) + return; + renderer_ = std::move(renderer); +#else + NOTREACHED(); +#endif } else { - scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( - this, &settings_, output_surface_.get(), resource_provider.get()); + std::unique_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( + this, &settings_, output_surface_.get(), resource_provider.get(), + true /* use_image_hijack_canvas */); if (!renderer) return; renderer_ = std::move(renderer); @@ -135,8 +209,9 @@ void Display::InitializeRenderer() { // overlays. bool output_partial_list = renderer_->Capabilities().using_partial_swap && !output_surface_->GetOverlayCandidateValidator(); - aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get(), - output_partial_list)); + aggregator_.reset(new SurfaceAggregator( + surface_manager_, resource_provider_.get(), output_partial_list)); + aggregator_->set_output_is_secure(output_is_secure_); } void Display::DidLoseOutputSurface() { @@ -148,7 +223,7 @@ void Display::DidLoseOutputSurface() { } void Display::UpdateRootSurfaceResourcesLocked() { - Surface* surface = manager_->GetSurfaceForId(current_surface_id_); + Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame(); if (scheduler_) scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); @@ -168,7 +243,7 @@ bool Display::DrawAndSwap() { return false; } - scoped_ptr<CompositorFrame> frame = + std::unique_ptr<CompositorFrame> frame = aggregator_->Aggregate(current_surface_id_); if (!frame) { TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", @@ -178,7 +253,7 @@ bool Display::DrawAndSwap() { // Run callbacks early to allow pipelining. for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { - Surface* surface = manager_->GetSurfaceForId(id_entry.first); + Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); if (surface) surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN); } @@ -276,9 +351,15 @@ void Display::DidSwapBuffersComplete() { renderer_->SwapBuffersComplete(); } -void Display::CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) { - client_->CommitVSyncParameters(timebase, interval); +void Display::SetBeginFrameSource(BeginFrameSource* source) { + // It's expected that there's only a single source from the + // BrowserCompositorOutputSurface that corresponds to vsync. The BFS is + // passed BrowserCompositorOutputSurface -> Display -> DisplayScheduler as an + // input. DisplayScheduler makes a decision about which BFS to use and + // calls back to Display as DisplaySchedulerClient to register for that + // surface id. + DCHECK(!vsync_begin_frame_source_); + vsync_begin_frame_source_ = source; } void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { @@ -320,7 +401,7 @@ void Display::SetFullRootLayerDamage() { void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) { if (aggregator_ && aggregator_->previous_contained_surfaces().count(surface_id)) { - Surface* surface = manager_->GetSurfaceForId(surface_id); + Surface* surface = surface_manager_->GetSurfaceForId(surface_id); if (surface) { const CompositorFrame* current_frame = surface->GetEligibleFrame(); if (!current_frame || !current_frame->delegated_frame_data || diff --git a/chromium/cc/surfaces/display.h b/chromium/cc/surfaces/display.h index 4646179d0a4..76e7735a42d 100644 --- a/chromium/cc/surfaces/display.h +++ b/chromium/cc/surfaces/display.h @@ -5,10 +5,10 @@ #ifndef CC_SURFACES_DISPLAY_H_ #define CC_SURFACES_DISPLAY_H_ +#include <memory> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/output/output_surface_client.h" #include "cc/output/renderer.h" #include "cc/resources/returned_resource.h" @@ -55,17 +55,19 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, SurfaceManager* manager, SharedBitmapManager* bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - const RendererSettings& settings); + const RendererSettings& settings, + uint32_t compositor_surface_namespace); ~Display() override; - bool Initialize(scoped_ptr<OutputSurface> output_surface, - DisplayScheduler* scheduler); + bool Initialize(std::unique_ptr<OutputSurface> output_surface, + base::SingleThreadTaskRunner* task_runner); // 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); void SetExternalClip(const gfx::Rect& clip); + void SetOutputIsSecure(bool secure); SurfaceId CurrentSurfaceId(); @@ -74,7 +76,8 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, // OutputSurfaceClient implementation. void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) override; + base::TimeDelta interval) override {} + void SetBeginFrameSource(BeginFrameSource* source) override; void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override; void DidSwapBuffers() override; void DidSwapBuffersComplete() override; @@ -96,28 +99,41 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, // SurfaceDamageObserver implementation. void OnSurfaceDamaged(SurfaceId surface, bool* changed) override; - private: + protected: + // Virtual for tests. + virtual void CreateScheduler(base::SingleThreadTaskRunner* task_runner); + void InitializeRenderer(); void UpdateRootSurfaceResourcesLocked(); DisplayClient* client_; - SurfaceManager* manager_; + SurfaceManager* surface_manager_; SharedBitmapManager* bitmap_manager_; gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; RendererSettings settings_; SurfaceId current_surface_id_; + uint32_t compositor_surface_namespace_; 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<TextureMailboxDeleter> texture_mailbox_deleter_; + bool output_is_secure_ = false; + + std::unique_ptr<OutputSurface> output_surface_; + // An internal synthetic BFS. May be null when not used. + std::unique_ptr<BeginFrameSource> internal_begin_frame_source_; + // The real BFS tied to vsync provided by the BrowserCompositorOutputSurface. + BeginFrameSource* vsync_begin_frame_source_; + // The current BFS driving the Display/DisplayScheduler. + BeginFrameSource* observed_begin_frame_source_; + std::unique_ptr<DisplayScheduler> scheduler_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<SurfaceAggregator> aggregator_; + std::unique_ptr<DirectRenderer> renderer_; + std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter_; std::vector<ui::LatencyInfo> stored_latency_info_; + private: DISALLOW_COPY_AND_ASSIGN(Display); }; diff --git a/chromium/cc/surfaces/display_client.h b/chromium/cc/surfaces/display_client.h index 61ea4d39970..bc455bb957b 100644 --- a/chromium/cc/surfaces/display_client.h +++ b/chromium/cc/surfaces/display_client.h @@ -5,17 +5,17 @@ #ifndef CC_SURFACES_DISPLAY_CLIENT_H_ #define CC_SURFACES_DISPLAY_CLIENT_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "base/time/time.h" namespace cc { +class BeginFrameSource; struct ManagedMemoryPolicy; class DisplayClient { public: - virtual void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) = 0; virtual void OutputSurfaceLost() = 0; virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0; diff --git a/chromium/cc/surfaces/display_scheduler.cc b/chromium/cc/surfaces/display_scheduler.cc index 9f19fdcb413..881f8e55209 100644 --- a/chromium/cc/surfaces/display_scheduler.cc +++ b/chromium/cc/surfaces/display_scheduler.cc @@ -33,10 +33,6 @@ DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client, weak_ptr_factory_(this) { begin_frame_deadline_closure_ = base::Bind( &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr()); - - // TODO(tansell): Set this to something useful. - begin_frame_source_for_children_.reset(new SyntheticBeginFrameSource( - task_runner, BeginFrameArgs::DefaultInterval())); } DisplayScheduler::~DisplayScheduler() { @@ -59,7 +55,7 @@ void DisplayScheduler::ForceImmediateSwapIfPossible() { bool in_begin = inside_begin_frame_deadline_interval_; AttemptDrawAndSwap(); if (in_begin) - begin_frame_source_->DidFinishFrame(0); + begin_frame_source_->DidFinishFrame(this, 0); } void DisplayScheduler::DisplayResized() { @@ -293,7 +289,7 @@ void DisplayScheduler::OnBeginFrameDeadline() { TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline"); AttemptDrawAndSwap(); - begin_frame_source_->DidFinishFrame(0); + begin_frame_source_->DidFinishFrame(this, 0); } void DisplayScheduler::DidSwapBuffers() { diff --git a/chromium/cc/surfaces/display_scheduler.h b/chromium/cc/surfaces/display_scheduler.h index 90e99f4344a..fd868b8d241 100644 --- a/chromium/cc/surfaces/display_scheduler.h +++ b/chromium/cc/surfaces/display_scheduler.h @@ -5,11 +5,13 @@ #ifndef CC_SURFACES_DISPLAY_SCHEDULER_H_ #define CC_SURFACES_DISPLAY_SCHEDULER_H_ +#include <memory> + #include "base/cancelable_callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/single_thread_task_runner.h" +#include "cc/output/renderer_settings.h" #include "cc/scheduler/begin_frame_source.h" #include "cc/surfaces/surface_id.h" #include "cc/surfaces/surfaces_export.h" @@ -49,10 +51,6 @@ class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase { bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override; void OnBeginFrameSourcePausedChanged(bool paused) override; - BeginFrameSource* begin_frame_source_for_children() { - return begin_frame_source_for_children_.get(); - } - protected: base::TimeTicks DesiredBeginFrameDeadlineTime(); virtual void ScheduleBeginFrameDeadline(); @@ -69,9 +67,6 @@ class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase { base::CancelableClosure begin_frame_deadline_task_; base::TimeTicks begin_frame_deadline_task_time_; - // TODO(tansell): Set this to something useful. - scoped_ptr<BeginFrameSource> begin_frame_source_for_children_; - bool output_surface_lost_; bool root_surface_resources_locked_; diff --git a/chromium/cc/surfaces/display_scheduler_unittest.cc b/chromium/cc/surfaces/display_scheduler_unittest.cc index 18e630314f2..50c082c8ee1 100644 --- a/chromium/cc/surfaces/display_scheduler_unittest.cc +++ b/chromium/cc/surfaces/display_scheduler_unittest.cc @@ -101,10 +101,10 @@ class DisplaySchedulerTest : public testing::Test { FakeBeginFrameSource fake_begin_frame_source_; - scoped_ptr<base::SimpleTestTickClock> now_src_; + std::unique_ptr<base::SimpleTestTickClock> now_src_; scoped_refptr<base::NullTaskRunner> task_runner_; - scoped_ptr<FakeDisplaySchedulerClient> client_; - scoped_ptr<TestDisplayScheduler> scheduler_; + std::unique_ptr<FakeDisplaySchedulerClient> client_; + std::unique_ptr<TestDisplayScheduler> scheduler_; }; TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) { diff --git a/chromium/cc/surfaces/display_unittest.cc b/chromium/cc/surfaces/display_unittest.cc index cbc7e34e378..312c3a4a9da 100644 --- a/chromium/cc/surfaces/display_unittest.cc +++ b/chromium/cc/surfaces/display_unittest.cc @@ -57,16 +57,19 @@ class DisplayTest : public testing::Test { public: DisplayTest() : factory_(&manager_, &surface_factory_client_), + id_allocator_(kArbitrarySurfaceNamespace), software_output_device_(nullptr), - task_runner_(new base::NullTaskRunner) {} + task_runner_(new base::NullTaskRunner) { + id_allocator_.RegisterSurfaceIdNamespace(&manager_); + } protected: - void SetUpContext(scoped_ptr<TestWebGraphicsContext3D> context) { + void SetUpContext(std::unique_ptr<TestWebGraphicsContext3D> context) { if (context) { output_surface_ = FakeOutputSurface::Create3d( TestContextProvider::Create(std::move(context))); } else { - scoped_ptr<TestSoftwareOutputDevice> output_device( + std::unique_ptr<TestSoftwareOutputDevice> output_device( new TestSoftwareOutputDevice); software_output_device_ = output_device.get(); output_surface_ = @@ -77,25 +80,27 @@ class DisplayTest : public testing::Test { } void SubmitCompositorFrame(RenderPassList* pass_list, SurfaceId surface_id) { - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); pass_list->swap(frame_data->render_pass_list); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory_.SubmitCompositorFrame(surface_id, std::move(frame), SurfaceFactory::DrawCallback()); } + enum { kArbitrarySurfaceNamespace = 3 }; + SurfaceManager manager_; FakeSurfaceFactoryClient surface_factory_client_; SurfaceFactory factory_; + SurfaceIdAllocator id_allocator_; TestSoftwareOutputDevice* software_output_device_; - scoped_ptr<FakeOutputSurface> output_surface_; + std::unique_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_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; }; class TestDisplayClient : public DisplayClient { @@ -103,8 +108,6 @@ class TestDisplayClient : public DisplayClient { TestDisplayClient() {} ~TestDisplayClient() override {} - void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) override {} void OutputSurfaceLost() override {} void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override {} }; @@ -113,14 +116,12 @@ class TestDisplayScheduler : public DisplayScheduler { public: TestDisplayScheduler(DisplaySchedulerClient* client, BeginFrameSource* begin_frame_source, - base::NullTaskRunner* task_runner) + base::SingleThreadTaskRunner* task_runner) : DisplayScheduler(client, begin_frame_source, task_runner, 1), damaged(false), display_resized_(false), has_new_root_surface(false), - swapped(false) { - begin_frame_source_for_children_.reset(new FakeBeginFrameSource); - } + swapped(false) {} ~TestDisplayScheduler() override {} @@ -147,9 +148,38 @@ class TestDisplayScheduler : public DisplayScheduler { bool display_resized_; bool has_new_root_surface; bool swapped; + + private: + RendererSettings settings_; +}; + +class TestDisplay : public Display { + public: + TestDisplay(DisplayClient* client, + SurfaceManager* manager, + SharedBitmapManager* bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const RendererSettings& settings, + uint32_t compositor_surface_namespace) + : Display(client, + manager, + bitmap_manager, + gpu_memory_buffer_manager, + settings, + compositor_surface_namespace) {} + + TestDisplayScheduler& scheduler() { + return *static_cast<TestDisplayScheduler*>(scheduler_.get()); + } + + protected: + void CreateScheduler(base::SingleThreadTaskRunner* task_runner) override { + scheduler_.reset( + new TestDisplayScheduler(this, vsync_begin_frame_source_, task_runner)); + } }; -void CopyCallback(bool* called, scoped_ptr<CopyOutputResult> result) { +void CopyCallback(bool* called, std::unique_ptr<CopyOutputResult> result) { *called = true; } @@ -160,14 +190,12 @@ TEST_F(DisplayTest, DisplayDamaged) { RendererSettings settings; settings.partial_swap_enabled = true; settings.finish_rendering_on_resize = true; - Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr, - settings); + TestDisplay display(&client, &manager_, shared_bitmap_manager_.get(), nullptr, + settings, id_allocator_.id_namespace()); + display.Initialize(std::move(output_surface_), task_runner_.get()); + TestDisplayScheduler& scheduler = display.scheduler(); - TestDisplayScheduler scheduler(&display, &fake_begin_frame_source_, - task_runner_.get()); - display.Initialize(std::move(output_surface_), &scheduler); - - SurfaceId surface_id(7u); + SurfaceId surface_id(id_allocator_.GenerateId()); EXPECT_FALSE(scheduler.damaged); EXPECT_FALSE(scheduler.has_new_root_surface); display.SetSurfaceId(surface_id, 1.f); @@ -185,7 +213,7 @@ TEST_F(DisplayTest, DisplayDamaged) { // First draw from surface should have full damage. RenderPassList pass_list; - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_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); @@ -325,10 +353,10 @@ TEST_F(DisplayTest, DisplayDamaged) { pass_list.push_back(std::move(pass)); scheduler.ResetDamageForTest(); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); pass_list.swap(frame_data->render_pass_list); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); frame->metadata.latency_info.push_back(ui::LatencyInfo()); @@ -358,10 +386,10 @@ TEST_F(DisplayTest, DisplayDamaged) { pass_list.push_back(std::move(pass)); scheduler.ResetDamageForTest(); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); pass_list.swap(frame_data->render_pass_list); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory_.SubmitCompositorFrame(surface_id, std::move(frame), @@ -417,23 +445,22 @@ class MockedContext : public TestWebGraphicsContext3D { }; TEST_F(DisplayTest, Finish) { - scoped_ptr<MockedContext> context(new MockedContext()); + std::unique_ptr<MockedContext> context(new MockedContext()); MockedContext* context_ptr = context.get(); SetUpContext(std::move(context)); EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0); + + SurfaceId surface_id(id_allocator_.GenerateId()); + 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(std::move(output_surface_), &scheduler); + TestDisplay display(&client, &manager_, shared_bitmap_manager_.get(), nullptr, + settings, surface_id.id_namespace()); + display.Initialize(std::move(output_surface_), task_runner_.get()); - SurfaceId surface_id(7u); display.SetSurfaceId(surface_id, 1.f); display.Resize(gfx::Size(100, 100)); @@ -441,7 +468,7 @@ TEST_F(DisplayTest, Finish) { { RenderPassList pass_list; - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_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); @@ -467,7 +494,7 @@ TEST_F(DisplayTest, Finish) { EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0); { RenderPassList pass_list; - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_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); diff --git a/chromium/cc/surfaces/onscreen_display_client.cc b/chromium/cc/surfaces/onscreen_display_client.cc index e8baf1b8a8a..b408ed4bebc 100644 --- a/chromium/cc/surfaces/onscreen_display_client.cc +++ b/chromium/cc/surfaces/onscreen_display_client.cc @@ -15,56 +15,29 @@ namespace cc { OnscreenDisplayClient::OnscreenDisplayClient( - scoped_ptr<OutputSurface> output_surface, + std::unique_ptr<OutputSurface> output_surface, SurfaceManager* manager, SharedBitmapManager* bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& settings, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + uint32_t compositor_surface_namespace) : output_surface_(std::move(output_surface)), task_runner_(task_runner), display_(new Display(this, manager, bitmap_manager, gpu_memory_buffer_manager, - settings)), - output_surface_lost_(false), - disable_display_vsync_(settings.disable_display_vsync) {} + settings, + compositor_surface_namespace)), + output_surface_lost_(false) {} OnscreenDisplayClient::~OnscreenDisplayClient() { } bool OnscreenDisplayClient::Initialize() { DCHECK(output_surface_); - - BeginFrameSource* frame_source; - if (disable_display_vsync_) { - unthrottled_frame_source_.reset( - new BackToBackBeginFrameSource(task_runner_.get())); - frame_source = unthrottled_frame_source_.get(); - } else { - synthetic_frame_source_.reset(new SyntheticBeginFrameSource( - task_runner_.get(), BeginFrameArgs::DefaultInterval())); - frame_source = synthetic_frame_source_.get(); - } - - scheduler_.reset( - new DisplayScheduler(display_.get(), frame_source, task_runner_.get(), - output_surface_->capabilities().max_frames_pending)); - - return display_->Initialize(std::move(output_surface_), scheduler_.get()); -} - -void OnscreenDisplayClient::CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) { - if (interval == base::TimeDelta()) { - // TODO(brianderson): We should not be receiving 0 intervals. - interval = BeginFrameArgs::DefaultInterval(); - } - - surface_display_output_surface_->ReceivedVSyncParameters(timebase, interval); - if (synthetic_frame_source_.get()) - synthetic_frame_source_->OnUpdateVSyncParameters(timebase, interval); + return display_->Initialize(std::move(output_surface_), task_runner_.get()); } void OnscreenDisplayClient::OutputSurfaceLost() { diff --git a/chromium/cc/surfaces/onscreen_display_client.h b/chromium/cc/surfaces/onscreen_display_client.h index d91f9c4908c..91bb5c09987 100644 --- a/chromium/cc/surfaces/onscreen_display_client.h +++ b/chromium/cc/surfaces/onscreen_display_client.h @@ -5,13 +5,13 @@ #ifndef CC_SURFACES_ONSCREEN_DISPLAY_CLIENT_H_ #define CC_SURFACES_ONSCREEN_DISPLAY_CLIENT_H_ -#include "cc/surfaces/display_client.h" +#include <memory> #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "cc/surfaces/display.h" +#include "cc/surfaces/display_client.h" #include "cc/surfaces/surfaces_export.h" namespace base { @@ -19,7 +19,6 @@ class SingleThreadTaskRunner; } namespace cc { -class BeginFrameSource; class ContextProvider; class DisplayScheduler; class SurfaceManager; @@ -30,13 +29,13 @@ class SurfaceDisplayOutputSurface; class CC_SURFACES_EXPORT OnscreenDisplayClient : NON_EXPORTED_BASE(DisplayClient) { public: - OnscreenDisplayClient( - scoped_ptr<OutputSurface> output_surface, - SurfaceManager* manager, - SharedBitmapManager* bitmap_manager, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - const RendererSettings& settings, - scoped_refptr<base::SingleThreadTaskRunner> task_runner); + OnscreenDisplayClient(std::unique_ptr<OutputSurface> output_surface, + SurfaceManager* manager, + SharedBitmapManager* bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const RendererSettings& settings, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + uint32_t compositor_surface_namespace); ~OnscreenDisplayClient() override; bool Initialize(); @@ -46,26 +45,20 @@ class CC_SURFACES_EXPORT OnscreenDisplayClient } // DisplayClient implementation. - void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) override; void OutputSurfaceLost() override; void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override; bool output_surface_lost() { return output_surface_lost_; } protected: - scoped_ptr<OutputSurface> output_surface_; + std::unique_ptr<OutputSurface> output_surface_; // Be careful of destruction order: // Display depends on DisplayScheduler depends on *BeginFrameSource // depends on TaskRunner. scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source_; - scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source_; - scoped_ptr<DisplayScheduler> scheduler_; - scoped_ptr<Display> display_; + std::unique_ptr<Display> display_; SurfaceDisplayOutputSurface* surface_display_output_surface_; bool output_surface_lost_; - bool disable_display_vsync_; private: DISALLOW_COPY_AND_ASSIGN(OnscreenDisplayClient); diff --git a/chromium/cc/surfaces/surface.cc b/chromium/cc/surfaces/surface.cc index 281a69012a4..73181292cc1 100644 --- a/chromium/cc/surfaces/surface.cc +++ b/chromium/cc/surfaces/surface.cc @@ -24,6 +24,7 @@ static const int kFrameIndexStart = 2; Surface::Surface(SurfaceId id, SurfaceFactory* factory) : surface_id_(id), + previous_frame_surface_id_(id), factory_(factory->AsWeakPtr()), frame_index_(kFrameIndexStart), destroyed_(false) {} @@ -41,7 +42,13 @@ Surface::~Surface() { draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED); } -void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, +void Surface::SetPreviousFrameSurface(Surface* surface) { + DCHECK(surface); + frame_index_ = surface->frame_index() + 1; + previous_frame_surface_id_ = surface->surface_id(); +} + +void Surface::QueueFrame(std::unique_ptr<CompositorFrame> frame, const DrawCallback& callback) { DCHECK(factory_); ClearCopyRequests(); @@ -50,7 +57,7 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, TakeLatencyInfo(&frame->metadata.latency_info); } - scoped_ptr<CompositorFrame> previous_frame = std::move(current_frame_); + std::unique_ptr<CompositorFrame> previous_frame = std::move(current_frame_); current_frame_ = std::move(frame); if (current_frame_) { @@ -64,6 +71,8 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, !current_frame_->delegated_frame_data->render_pass_list.empty()) ++frame_index_; + previous_frame_surface_id_ = surface_id(); + std::vector<SurfaceId> new_referenced_surfaces; if (current_frame_) { new_referenced_surfaces = current_frame_->metadata.referenced_surfaces; @@ -95,10 +104,11 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, } } -void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) { +void Surface::RequestCopyOfOutput( + std::unique_ptr<CopyOutputRequest> copy_request) { if (current_frame_ && !current_frame_->delegated_frame_data->render_pass_list.empty()) { - std::vector<scoped_ptr<CopyOutputRequest>>& copy_requests = + std::vector<std::unique_ptr<CopyOutputRequest>>& copy_requests = current_frame_->delegated_frame_data->render_pass_list.back() ->copy_requests; @@ -107,7 +117,7 @@ void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) { // source. auto to_remove = std::remove_if(copy_requests.begin(), copy_requests.end(), - [source](const scoped_ptr<CopyOutputRequest>& x) { + [source](const std::unique_ptr<CopyOutputRequest>& x) { return x->source() == source; }); copy_requests.erase(to_remove, copy_requests.end()); @@ -119,7 +129,8 @@ void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) { } void Surface::TakeCopyOutputRequests( - std::multimap<RenderPassId, scoped_ptr<CopyOutputRequest>>* copy_requests) { + std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>>* + copy_requests) { DCHECK(copy_requests->empty()); if (current_frame_) { for (const auto& render_pass : diff --git a/chromium/cc/surfaces/surface.h b/chromium/cc/surfaces/surface.h index 340db193fb6..e6aeb84f7f5 100644 --- a/chromium/cc/surfaces/surface.h +++ b/chromium/cc/surfaces/surface.h @@ -9,13 +9,13 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <unordered_set> #include <vector> #include "base/callback.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "cc/output/copy_output_request.h" #include "cc/quads/render_pass_id.h" @@ -44,14 +44,19 @@ class CC_SURFACES_EXPORT Surface { ~Surface(); SurfaceId surface_id() const { return surface_id_; } + SurfaceId previous_frame_surface_id() const { + return previous_frame_surface_id_; + } + + void SetPreviousFrameSurface(Surface* surface); - void QueueFrame(scoped_ptr<CompositorFrame> frame, + void QueueFrame(std::unique_ptr<CompositorFrame> frame, const DrawCallback& draw_callback); - void RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request); + void RequestCopyOfOutput(std::unique_ptr<CopyOutputRequest> copy_request); // Adds each CopyOutputRequest in the current frame to copy_requests. The // caller takes ownership of them. void TakeCopyOutputRequests( - std::multimap<RenderPassId, scoped_ptr<CopyOutputRequest>>* + std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>>* copy_requests); // Returns the most recent frame that is eligible to be rendered. const CompositorFrame* GetEligibleFrame(); @@ -88,9 +93,10 @@ class CC_SURFACES_EXPORT Surface { void ClearCopyRequests(); SurfaceId surface_id_; + SurfaceId previous_frame_surface_id_; base::WeakPtr<SurfaceFactory> factory_; // TODO(jamesr): Support multiple frames in flight. - scoped_ptr<CompositorFrame> current_frame_; + std::unique_ptr<CompositorFrame> current_frame_; int frame_index_; bool destroyed_; std::vector<SurfaceSequence> destruction_dependencies_; diff --git a/chromium/cc/surfaces/surface_aggregator.cc b/chromium/cc/surfaces/surface_aggregator.cc index 4c7e04ea4be..75b8f6c9f1f 100644 --- a/chromium/cc/surfaces/surface_aggregator.cc +++ b/chromium/cc/surfaces/surface_aggregator.cc @@ -9,8 +9,10 @@ #include <map> #include "base/bind.h" +#include "base/containers/adapters.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "base/trace_event/trace_event.h" #include "cc/base/math_util.h" @@ -19,7 +21,9 @@ #include "cc/quads/draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" #include "cc/quads/shared_quad_state.h" +#include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/surface_draw_quad.h" +#include "cc/quads/texture_draw_quad.h" #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_factory.h" #include "cc/surfaces/surface_manager.h" @@ -30,8 +34,9 @@ namespace { void MoveMatchingRequests( RenderPassId id, - std::multimap<RenderPassId, scoped_ptr<CopyOutputRequest>>* copy_requests, - std::vector<scoped_ptr<CopyOutputRequest>>* output_requests) { + std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>>* + copy_requests, + std::vector<std::unique_ptr<CopyOutputRequest>>* output_requests) { auto request_range = copy_requests->equal_range(id); for (auto it = request_range.first; it != request_range.second; ++it) { DCHECK(it->second); @@ -120,7 +125,7 @@ static void UnrefHelper(base::WeakPtr<SurfaceFactory> surface_factory, RenderPassId SurfaceAggregator::RemapPassId(RenderPassId surface_local_pass_id, SurfaceId surface_id) { - scoped_ptr<RenderPassIdAllocator>& allocator = + std::unique_ptr<RenderPassIdAllocator>& allocator = render_pass_allocator_map_[surface_id]; if (!allocator) allocator.reset(new RenderPassIdAllocator(&next_render_pass_id_)); @@ -150,14 +155,22 @@ gfx::Rect SurfaceAggregator::DamageRectForSurface( const RenderPass& source, const gfx::Rect& full_rect) const { auto it = previous_contained_surfaces_.find(surface->surface_id()); - if (it == previous_contained_surfaces_.end()) - return full_rect; + if (it != previous_contained_surfaces_.end()) { + int previous_index = it->second; + if (previous_index == surface->frame_index()) + return gfx::Rect(); + } + SurfaceId previous_surface_id = surface->previous_frame_surface_id(); + + if (surface->surface_id() != previous_surface_id) { + it = previous_contained_surfaces_.find(previous_surface_id); + } + if (it != previous_contained_surfaces_.end()) { + int previous_index = it->second; + if (previous_index == surface->frame_index() - 1) + return source.damage_rect; + } - int previous_index = it->second; - if (previous_index == surface->frame_index()) - return gfx::Rect(); - if (previous_index == surface->frame_index() - 1) - return source.damage_rect; return full_rect; } @@ -181,7 +194,7 @@ void SurfaceAggregator::HandleSurfaceQuad( if (!frame_data) return; - std::multimap<RenderPassId, scoped_ptr<CopyOutputRequest>> copy_requests; + std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>> copy_requests; surface->TakeCopyOutputRequests(©_requests); const RenderPassList& render_pass_list = frame_data->render_pass_list; @@ -209,11 +222,12 @@ void SurfaceAggregator::HandleSurfaceQuad( size_t sqs_size = source.shared_quad_state_list.size(); size_t dq_size = source.quad_list.size(); - scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); + std::unique_ptr<RenderPass> copy_pass( + RenderPass::Create(sqs_size, dq_size)); RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); - copy_pass->SetAll(remapped_pass_id, source.output_rect, gfx::Rect(), + copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, source.transform_to_root_target, source.has_transparent_background); @@ -232,6 +246,17 @@ void SurfaceAggregator::HandleSurfaceQuad( child_to_parent_map, gfx::Transform(), ClipData(), copy_pass.get(), surface_id); + if (!copy_request_passes_.count(remapped_pass_id) && + !moved_pixel_passes_.count(remapped_pass_id)) { + gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); + if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { + gfx::Rect damage_rect_in_render_pass_space = + MathUtil::ProjectEnclosingClippedRect(inverse_transform, + root_damage_rect_); + copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); + } + } + dest_pass_list_->push_back(std::move(copy_pass)); } @@ -310,18 +335,22 @@ SharedQuadState* SurfaceAggregator::CopySharedQuadState( return copy_shared_quad_state; } -static gfx::Rect CalculateQuadSpaceDamageRect( +// Returns true if the damage rect is valid. +static bool CalculateQuadSpaceDamageRect( const gfx::Transform& quad_to_target_transform, const gfx::Transform& target_to_root_transform, - const gfx::Rect& root_damage_rect) { + const gfx::Rect& root_damage_rect, + gfx::Rect* quad_space_damage_rect) { gfx::Transform quad_to_root_transform(target_to_root_transform, quad_to_target_transform); gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); bool inverse_valid = quad_to_root_transform.GetInverse(&inverse_transform); - DCHECK(inverse_valid); + if (!inverse_valid) + return false; - return MathUtil::ProjectEnclosingClippedRect(inverse_transform, - root_damage_rect); + *quad_space_damage_rect = MathUtil::ProjectEnclosingClippedRect( + inverse_transform, root_damage_rect); + return true; } void SurfaceAggregator::CopyQuadsToPass( @@ -336,11 +365,14 @@ void SurfaceAggregator::CopyQuadsToPass( const SharedQuadState* dest_shared_quad_state = nullptr; // If the current frame has copy requests then aggregate the entire // thing, as otherwise parts of the copy requests may be ignored. - const bool ignore_undamaged = aggregate_only_damaged_ && !has_copy_requests_; + const bool ignore_undamaged = aggregate_only_damaged_ && + !has_copy_requests_ && + !moved_pixel_passes_.count(dest_pass->id); // Damage rect in the quad space of the current shared quad state. // TODO(jbauman): This rect may contain unnecessary area if // transform isn't axis-aligned. gfx::Rect damage_rect_in_quad_space; + bool damage_rect_in_quad_space_valid = false; #if DCHECK_IS_ON() // If quads have come in with SharedQuadState out of order, or when quads have @@ -367,10 +399,11 @@ void SurfaceAggregator::CopyQuadsToPass( gfx::Transform quad_to_target_transform( target_transform, quad->shared_quad_state->quad_to_target_transform); - damage_rect_in_quad_space = CalculateQuadSpaceDamageRect( + damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect( quad_to_target_transform, dest_pass->transform_to_root_target, - root_damage_rect_); - if (!damage_rect_in_quad_space.Intersects(quad->visible_rect)) + root_damage_rect_, &damage_rect_in_quad_space); + if (damage_rect_in_quad_space_valid && + !damage_rect_in_quad_space.Intersects(quad->visible_rect)) continue; } HandleSurfaceQuad(surface_quad, target_transform, clip_rect, dest_pass); @@ -380,14 +413,16 @@ void SurfaceAggregator::CopyQuadsToPass( quad->shared_quad_state, target_transform, clip_rect, dest_pass); last_copied_source_shared_quad_state = quad->shared_quad_state; if (aggregate_only_damaged_ && !has_copy_requests_) { - damage_rect_in_quad_space = CalculateQuadSpaceDamageRect( + damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect( dest_shared_quad_state->quad_to_target_transform, - dest_pass->transform_to_root_target, root_damage_rect_); + dest_pass->transform_to_root_target, root_damage_rect_, + &damage_rect_in_quad_space); } } if (ignore_undamaged) { - if (!damage_rect_in_quad_space.Intersects(quad->visible_rect)) + if (damage_rect_in_quad_space_valid && + !damage_rect_in_quad_space.Intersects(quad->visible_rect)) continue; } @@ -401,6 +436,20 @@ void SurfaceAggregator::CopyQuadsToPass( dest_quad = dest_pass->CopyFromAndAppendRenderPassDrawQuad( pass_quad, dest_shared_quad_state, remapped_pass_id); + } else if (quad->material == DrawQuad::TEXTURE_CONTENT) { + const TextureDrawQuad* texture_quad = + TextureDrawQuad::MaterialCast(quad); + if (texture_quad->secure_output_only && + (!output_is_secure_ || copy_request_passes_.count(dest_pass->id))) { + SolidColorDrawQuad* solid_color_quad = + dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); + solid_color_quad->SetNew(dest_shared_quad_state, quad->rect, + quad->visible_rect, SK_ColorBLACK, false); + dest_quad = solid_color_quad; + } else { + dest_quad = dest_pass->CopyFromAndAppendDrawQuad( + quad, dest_shared_quad_state); + } } else { dest_quad = dest_pass->CopyFromAndAppendDrawQuad(quad, dest_shared_quad_state); @@ -424,7 +473,7 @@ void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, Surface* surface) { // The root surface is allowed to have copy output requests, so grab them // off its render passes. - std::multimap<RenderPassId, scoped_ptr<CopyOutputRequest>> copy_requests; + std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>> copy_requests; surface->TakeCopyOutputRequests(©_requests); const RenderPassList& source_pass_list = frame_data->render_pass_list; @@ -443,20 +492,31 @@ void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, size_t sqs_size = source.shared_quad_state_list.size(); size_t dq_size = source.quad_list.size(); - scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); + std::unique_ptr<RenderPass> copy_pass( + RenderPass::Create(sqs_size, dq_size)); MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); RenderPassId remapped_pass_id = RemapPassId(source.id, surface->surface_id()); - copy_pass->SetAll(remapped_pass_id, source.output_rect, gfx::Rect(), + copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, source.transform_to_root_target, source.has_transparent_background); CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, child_to_parent_map, gfx::Transform(), ClipData(), copy_pass.get(), surface->surface_id()); + if (!copy_request_passes_.count(remapped_pass_id) && + !moved_pixel_passes_.count(remapped_pass_id)) { + gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); + if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { + gfx::Rect damage_rect_in_render_pass_space = + MathUtil::ProjectEnclosingClippedRect(inverse_transform, + root_damage_rect_); + copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); + } + } dest_pass_list_->push_back(std::move(copy_pass)); } @@ -486,6 +546,8 @@ void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { // surface and its descendants, check if there are any copy requests, and // return the combined damage rect. gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, + bool in_moved_pixel_pass, + RenderPassId parent_pass, PrewalkResult* result) { // This is for debugging a possible use after free. // TODO(jbauman): Remove this once we have enough information. @@ -527,10 +589,26 @@ gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, provider_ ? provider_->GetChildToParentMap(child_id) : empty_map; CHECK(debug_weak_this.get()); - // 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) { + if (!frame_data->render_pass_list.empty()) { + RenderPassId remapped_pass_id = + RemapPassId(frame_data->render_pass_list.back()->id, surface_id); + if (in_moved_pixel_pass) + moved_pixel_passes_.insert(remapped_pass_id); + if (parent_pass.IsValid()) + render_pass_dependencies_[parent_pass].insert(remapped_pass_id); + } + + struct SurfaceInfo { + SurfaceId id; + bool has_moved_pixels; + RenderPassId parent_pass; + gfx::Transform target_to_surface_transform; + }; + std::vector<SurfaceInfo> child_surfaces; + + for (const auto& render_pass : base::Reversed(frame_data->render_pass_list)) { + RenderPassId remapped_pass_id = RemapPassId(render_pass->id, surface_id); + bool in_moved_pixel_pass = !!moved_pixel_passes_.count(remapped_pass_id); for (const auto& quad : render_pass->quad_list) { if (quad->material == DrawQuad::SURFACE_CONTENT) { const SurfaceDrawQuad* surface_quad = @@ -538,8 +616,22 @@ gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, gfx::Transform target_to_surface_transform( render_pass->transform_to_root_target, surface_quad->shared_quad_state->quad_to_target_transform); - child_surfaces.push_back(std::make_pair(surface_quad->surface_id, - target_to_surface_transform)); + child_surfaces.push_back( + SurfaceInfo{surface_quad->surface_id, in_moved_pixel_pass, + remapped_pass_id, target_to_surface_transform}); + } else if (quad->material == DrawQuad::RENDER_PASS) { + const RenderPassDrawQuad* render_pass_quad = + RenderPassDrawQuad::MaterialCast(quad); + if (in_moved_pixel_pass || + render_pass_quad->filters.HasFilterThatMovesPixels()) { + moved_pixel_passes_.insert( + RemapPassId(render_pass_quad->render_pass_id, surface_id)); + } + if (render_pass_quad->background_filters.HasFilterThatMovesPixels()) { + in_moved_pixel_pass = true; + } + render_pass_dependencies_[remapped_pass_id].insert( + RemapPassId(render_pass_quad->render_pass_id, surface_id)); } if (!provider_) @@ -564,8 +656,10 @@ gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, CHECK(debug_weak_this.get()); gfx::Rect damage_rect; + gfx::Rect full_damage; if (!frame_data->render_pass_list.empty()) { RenderPass* last_pass = frame_data->render_pass_list.back().get(); + full_damage = last_pass->output_rect; damage_rect = DamageRectForSurface(surface, *last_pass, last_pass->output_rect); } @@ -575,16 +669,27 @@ gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, SurfaceSet::iterator it = referenced_surfaces_.insert(surface->surface_id()).first; for (const auto& surface_info : child_surfaces) { - gfx::Rect surface_damage = PrewalkTree(surface_info.first, result); - damage_rect.Union( - MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); + gfx::Rect surface_damage = + PrewalkTree(surface_info.id, surface_info.has_moved_pixels, + surface_info.parent_pass, result); + if (surface_damage.IsEmpty()) + continue; + if (surface_info.has_moved_pixels) { + // Areas outside the rect hit by target_to_surface_transform may be + // modified if there is a filter that moves pixels. + damage_rect = full_damage; + continue; + } + + damage_rect.Union(MathUtil::MapEnclosingClippedRect( + surface_info.target_to_surface_transform, surface_damage)); } CHECK(debug_weak_this.get()); for (const auto& surface_id : surface_frame->metadata.referenced_surfaces) { if (!contained_surfaces_.count(surface_id)) { result->undrawn_surfaces.insert(surface_id); - PrewalkTree(surface_id, result); + PrewalkTree(surface_id, false, RenderPassId(), result); } } @@ -593,8 +698,12 @@ gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, surface->factory()->WillDrawSurface(surface->surface_id(), damage_rect); CHECK(debug_weak_this.get()); - for (const auto& render_pass : frame_data->render_pass_list) - result->has_copy_requests |= !render_pass->copy_requests.empty(); + for (const auto& render_pass : frame_data->render_pass_list) { + if (!render_pass->copy_requests.empty()) { + RenderPassId remapped_pass_id = RemapPassId(render_pass->id, surface_id); + copy_request_passes_.insert(remapped_pass_id); + } + } referenced_surfaces_.erase(it); return damage_rect; @@ -643,7 +752,25 @@ void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { } } -scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { +void SurfaceAggregator::PropagateCopyRequestPasses() { + std::vector<RenderPassId> copy_requests_to_iterate( + copy_request_passes_.begin(), copy_request_passes_.end()); + while (!copy_requests_to_iterate.empty()) { + RenderPassId first = copy_requests_to_iterate.back(); + copy_requests_to_iterate.pop_back(); + auto it = render_pass_dependencies_.find(first); + if (it == render_pass_dependencies_.end()) + continue; + for (auto pass : it->second) { + if (copy_request_passes_.insert(pass).second) { + copy_requests_to_iterate.push_back(pass); + } + } + } +} + +std::unique_ptr<CompositorFrame> SurfaceAggregator::Aggregate( + SurfaceId surface_id) { Surface* surface = manager_->GetSurfaceForId(surface_id); DCHECK(surface); contained_surfaces_[surface_id] = surface->frame_index(); @@ -652,8 +779,8 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { return nullptr; TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); - frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); + frame->delegated_frame_data = base::WrapUnique(new DelegatedFrameData); DCHECK(root_surface_frame->delegated_frame_data); @@ -662,19 +789,24 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { valid_surfaces_.clear(); PrewalkResult prewalk_result; - root_damage_rect_ = PrewalkTree(surface_id, &prewalk_result); - has_copy_requests_ = prewalk_result.has_copy_requests; + root_damage_rect_ = + PrewalkTree(surface_id, false, RenderPassId(), &prewalk_result); + PropagateCopyRequestPasses(); + has_copy_requests_ = !copy_request_passes_.empty(); CopyUndrawnSurfaces(&prewalk_result); SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); referenced_surfaces_.erase(it); + moved_pixel_passes_.clear(); + copy_request_passes_.clear(); + render_pass_dependencies_.clear(); + DCHECK(referenced_surfaces_.empty()); if (dest_pass_list_->empty()) return nullptr; - dest_pass_list_->back()->damage_rect = root_damage_rect_; dest_pass_list_ = NULL; ProcessAddedAndRemovedSurfaces(); diff --git a/chromium/cc/surfaces/surface_aggregator.h b/chromium/cc/surfaces/surface_aggregator.h index 9360ed9ec85..e94261ecca1 100644 --- a/chromium/cc/surfaces/surface_aggregator.h +++ b/chromium/cc/surfaces/surface_aggregator.h @@ -5,12 +5,12 @@ #ifndef CC_SURFACES_SURFACE_AGGREGATOR_H_ #define CC_SURFACES_SURFACE_AGGREGATOR_H_ +#include <memory> #include <set> #include <unordered_map> #include <unordered_set> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "cc/quads/draw_quad.h" #include "cc/quads/render_pass.h" @@ -36,12 +36,13 @@ class CC_SURFACES_EXPORT SurfaceAggregator { bool aggregate_only_damaged); ~SurfaceAggregator(); - scoped_ptr<CompositorFrame> Aggregate(SurfaceId surface_id); + std::unique_ptr<CompositorFrame> Aggregate(SurfaceId surface_id); void ReleaseResources(SurfaceId surface_id); SurfaceIndexMap& previous_contained_surfaces() { return previous_contained_surfaces_; } void SetFullDamageForSurface(SurfaceId surface_id); + void set_output_is_secure(bool secure) { output_is_secure_ = secure; } private: struct ClipData { @@ -56,7 +57,6 @@ class CC_SURFACES_EXPORT SurfaceAggregator { struct PrewalkResult { PrewalkResult(); ~PrewalkResult(); - bool has_copy_requests = false; // This is the set of Surfaces that were referenced by another Surface, but // not included in a SurfaceDrawQuad. std::set<SurfaceId> undrawn_surfaces; @@ -85,7 +85,10 @@ class CC_SURFACES_EXPORT SurfaceAggregator { const ClipData& clip_rect, RenderPass* dest_pass, SurfaceId surface_id); - gfx::Rect PrewalkTree(SurfaceId surface_id, PrewalkResult* result); + gfx::Rect PrewalkTree(SurfaceId surface_id, + bool in_moved_pixel_pass, + RenderPassId parent_pass, + PrewalkResult* result); void CopyUndrawnSurfaces(PrewalkResult* prewalk); void CopyPasses(const DelegatedFrameData* frame_data, Surface* surface); @@ -95,6 +98,8 @@ class CC_SURFACES_EXPORT SurfaceAggregator { // child surfaces. void ProcessAddedAndRemovedSurfaces(); + void PropagateCopyRequestPasses(); + int ChildIdForSurface(Surface* surface); gfx::Rect DamageRectForSurface(const Surface* surface, const RenderPass& source, @@ -106,11 +111,12 @@ class CC_SURFACES_EXPORT SurfaceAggregator { class RenderPassIdAllocator; using RenderPassIdAllocatorMap = std::unordered_map<SurfaceId, - scoped_ptr<RenderPassIdAllocator>, + std::unique_ptr<RenderPassIdAllocator>, SurfaceIdHash>; RenderPassIdAllocatorMap render_pass_allocator_map_; int next_render_pass_id_; const bool aggregate_only_damaged_; + bool output_is_secure_; using SurfaceToResourceChildIdMap = std::unordered_map<SurfaceId, int, SurfaceIdHash>; @@ -136,6 +142,21 @@ class CC_SURFACES_EXPORT SurfaceAggregator { // This is the pass list for the aggregated frame. RenderPassList* dest_pass_list_; + // This is the set of aggregated pass ids that are affected by filters that + // move pixels. + std::unordered_set<RenderPassId, RenderPassIdHash> moved_pixel_passes_; + + // This is the set of aggregated pass ids that are drawn by copy requests, so + // should not have their damage rects clipped to the root damage rect. + std::unordered_set<RenderPassId, RenderPassIdHash> copy_request_passes_; + + // This maps each aggregated pass id to the set of (aggregated) pass ids + // that its RenderPassDrawQuads depend on + std::unordered_map<RenderPassId, + std::unordered_set<RenderPassId, RenderPassIdHash>, + RenderPassIdHash> + render_pass_dependencies_; + // The root damage rect of the currently-aggregating frame. gfx::Rect root_damage_rect_; diff --git a/chromium/cc/surfaces/surface_aggregator_perftest.cc b/chromium/cc/surfaces/surface_aggregator_perftest.cc index b79bd881f55..3cc6a079972 100644 --- a/chromium/cc/surfaces/surface_aggregator_perftest.cc +++ b/chromium/cc/surfaces/surface_aggregator_perftest.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/memory/ptr_util.h" #include "cc/debug/lap_timer.h" #include "cc/output/compositor_frame.h" #include "cc/output/delegated_frame_data.h" @@ -31,7 +32,7 @@ class SurfaceAggregatorPerfTest : public testing::Test { public: SurfaceAggregatorPerfTest() : factory_(&manager_, &empty_client_) { output_surface_ = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager); @@ -49,8 +50,8 @@ class SurfaceAggregatorPerfTest : public testing::Test { optimize_damage)); for (int i = 1; i <= num_surfaces; i++) { factory_.Create(SurfaceId(i)); - scoped_ptr<RenderPass> pass(RenderPass::Create()); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> pass(RenderPass::Create()); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); for (int j = 0; j < num_textures; j++) { @@ -77,7 +78,7 @@ class SurfaceAggregatorPerfTest : public testing::Test { quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending, j, gfx::Size(), premultiplied_alpha, uv_top_left, uv_bottom_right, background_color, vertex_opacity, flipped, - nearest_neighbor); + nearest_neighbor, false); } sqs = pass->CreateAndAppendSharedQuadState(); sqs->opacity = opacity; @@ -89,7 +90,7 @@ class SurfaceAggregatorPerfTest : public testing::Test { } frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory_.SubmitCompositorFrame(SurfaceId(i), std::move(frame), SurfaceFactory::DrawCallback()); @@ -98,8 +99,8 @@ class SurfaceAggregatorPerfTest : public testing::Test { factory_.Create(SurfaceId(num_surfaces + 1)); timer_.Reset(); do { - scoped_ptr<RenderPass> pass(RenderPass::Create()); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> pass(RenderPass::Create()); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); SurfaceDrawQuad* surface_quad = @@ -113,13 +114,13 @@ class SurfaceAggregatorPerfTest : public testing::Test { pass->damage_rect = gfx::Rect(0, 0, 1, 1); frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory_.SubmitCompositorFrame(SurfaceId(num_surfaces + 1), std::move(frame), SurfaceFactory::DrawCallback()); - scoped_ptr<CompositorFrame> aggregated = + std::unique_ptr<CompositorFrame> aggregated = aggregator_->Aggregate(SurfaceId(num_surfaces + 1)); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); @@ -137,10 +138,10 @@ class SurfaceAggregatorPerfTest : public testing::Test { EmptySurfaceFactoryClient empty_client_; SurfaceFactory factory_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<SurfaceAggregator> aggregator_; + std::unique_ptr<OutputSurface> output_surface_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<SurfaceAggregator> aggregator_; LapTimer timer_; }; diff --git a/chromium/cc/surfaces/surface_aggregator_unittest.cc b/chromium/cc/surfaces/surface_aggregator_unittest.cc index dca531d84e6..b0ab189c474 100644 --- a/chromium/cc/surfaces/surface_aggregator_unittest.cc +++ b/chromium/cc/surfaces/surface_aggregator_unittest.cc @@ -10,6 +10,7 @@ #include <utility> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/output/compositor_frame.h" #include "cc/output/delegated_frame_data.h" #include "cc/quads/render_pass.h" @@ -43,7 +44,7 @@ SurfaceId InvalidSurfaceId() { } gfx::Size SurfaceSize() { - static gfx::Size size(5, 5); + static gfx::Size size(100, 100); return size; } @@ -81,7 +82,7 @@ TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) { SurfaceId one_id(7); factory_.Create(one_id); - scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id); + std::unique_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id); EXPECT_FALSE(frame); factory_.Destroy(one_id); @@ -112,7 +113,7 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { size_t expected_pass_count, SurfaceId* surface_ids, size_t expected_surface_count) { - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -140,10 +141,10 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { } void SubmitPassListAsFrame(SurfaceId surface_id, RenderPassList* pass_list) { - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); pass_list->swap(frame_data->render_pass_list); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory_.SubmitCompositorFrame(surface_id, std::move(frame), @@ -158,11 +159,13 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { SubmitPassListAsFrame(surface_id, &pass_list); } - void QueuePassAsFrame(scoped_ptr<RenderPass> pass, SurfaceId surface_id) { - scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); + void QueuePassAsFrame(std::unique_ptr<RenderPass> pass, + SurfaceId surface_id) { + std::unique_ptr<DelegatedFrameData> delegated_frame_data( + new DelegatedFrameData); delegated_frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = std::move(delegated_frame_data); factory_.SubmitCompositorFrame(surface_id, std::move(child_frame), @@ -211,7 +214,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) { SubmitCompositorFrame(passes, arraysize(passes), root_surface_id_); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -295,7 +298,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) { SubmitCompositorFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id); - scoped_ptr<CopyOutputRequest> copy_request( + std::unique_ptr<CopyOutputRequest> copy_request( CopyOutputRequest::CreateEmptyRequest()); CopyOutputRequest* copy_request_ptr = copy_request.get(); factory_.RequestCopyOfSurface(embedded_surface_id, std::move(copy_request)); @@ -307,7 +310,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) { SubmitCompositorFrame(root_passes, arraysize(root_passes), root_surface_id_); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -353,10 +356,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) { SubmitCompositorFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id); - scoped_ptr<CopyOutputRequest> copy_request( + std::unique_ptr<CopyOutputRequest> copy_request( CopyOutputRequest::CreateEmptyRequest()); CopyOutputRequest* copy_request_ptr = copy_request.get(); - scoped_ptr<CopyOutputRequest> copy_request2( + std::unique_ptr<CopyOutputRequest> copy_request2( CopyOutputRequest::CreateEmptyRequest()); CopyOutputRequest* copy_request2_ptr = copy_request2.get(); @@ -376,17 +379,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) { pass_list[0]->copy_requests.push_back(std::move(copy_request)); pass_list[1]->copy_requests.push_back(std::move(copy_request2)); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); pass_list.swap(frame_data->render_pass_list); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory_.SubmitCompositorFrame(root_surface_id_, std::move(frame), SurfaceFactory::DrawCallback()); } - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -443,7 +446,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) { SubmitCompositorFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id); - scoped_ptr<CopyOutputRequest> copy_request( + std::unique_ptr<CopyOutputRequest> copy_request( CopyOutputRequest::CreateEmptyRequest()); CopyOutputRequest* copy_request_ptr = copy_request.get(); factory_.RequestCopyOfSurface(embedded_surface_id, std::move(copy_request)); @@ -459,11 +462,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) { test::Pass(parent_quads, arraysize(parent_quads))}; { - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); AddPasses(&frame_data->render_pass_list, gfx::Rect(SurfaceSize()), parent_passes, arraysize(parent_passes)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); frame->metadata.referenced_surfaces.push_back(embedded_surface_id); @@ -476,11 +479,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) { test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; { - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); AddPasses(&frame_data->render_pass_list, gfx::Rect(SurfaceSize()), root_passes, arraysize(root_passes)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); frame->metadata.referenced_surfaces.push_back(parent_surface_id); // Reference to Surface ID of a Surface that doesn't exist should be @@ -491,7 +494,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) { SurfaceFactory::DrawCallback()); } - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -559,7 +562,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) { SubmitCompositorFrame(root_passes, arraysize(root_passes), root_surface_id_); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -795,7 +798,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) { SubmitCompositorFrame(parent_passes, arraysize(parent_passes), root_surface_id_); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -895,7 +898,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { RenderPassId pass_id(1, 1); SurfaceId grandchild_surface_id = allocator_.GenerateId(); factory_.Create(grandchild_surface_id); - scoped_ptr<RenderPass> grandchild_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> grandchild_pass = RenderPass::Create(); gfx::Rect output_rect(SurfaceSize()); gfx::Rect damage_rect(SurfaceSize()); gfx::Transform transform_to_root_target; @@ -908,7 +911,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { SurfaceId child_one_surface_id = allocator_.GenerateId(); factory_.Create(child_one_surface_id); - scoped_ptr<RenderPass> child_one_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> child_one_pass = RenderPass::Create(); child_one_pass->SetNew( pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode( @@ -926,14 +929,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { SurfaceId child_two_surface_id = allocator_.GenerateId(); factory_.Create(child_two_surface_id); - scoped_ptr<RenderPass> child_two_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> child_two_pass = RenderPass::Create(); child_two_pass->SetNew( pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode( SurfaceSize(), child_two_pass.get(), blend_modes[5]); QueuePassAsFrame(std::move(child_two_pass), child_two_surface_id); - scoped_ptr<RenderPass> root_pass = RenderPass::Create(); + std::unique_ptr<RenderPass> root_pass = RenderPass::Create(); root_pass->SetNew( pass_id, output_rect, damage_rect, transform_to_root_target); @@ -958,7 +961,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { QueuePassAsFrame(std::move(root_pass), root_surface_id_); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1035,10 +1038,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { child_root_pass_sqs->is_clipped = true; child_root_pass_sqs->clip_rect = gfx::Rect(0, 0, 5, 5); - scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> child_frame_data( + new DelegatedFrameData); child_pass_list.swap(child_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = std::move(child_frame_data); factory_.SubmitCompositorFrame(child_surface_id, std::move(child_frame), @@ -1066,10 +1070,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { middle_root_pass->shared_quad_state_list.front(); middle_root_pass_sqs->quad_to_target_transform.Scale(2, 3); - scoped_ptr<DelegatedFrameData> middle_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> middle_frame_data( + new DelegatedFrameData); middle_pass_list.swap(middle_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> middle_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> middle_frame(new CompositorFrame); middle_frame->delegated_frame_data = std::move(middle_frame_data); factory_.SubmitCompositorFrame(middle_surface_id, std::move(middle_frame), @@ -1102,16 +1107,16 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { root_pass_list[0]->transform_to_root_target.Translate(10, 5); - scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); root_pass_list.swap(root_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = std::move(root_frame_data); factory_.SubmitCompositorFrame(root_surface_id_, std::move(root_frame), SurfaceFactory::DrawCallback()); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1209,10 +1214,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { child_root_pass->shared_quad_state_list.front(); child_root_pass_sqs->quad_to_target_transform.Translate(8, 0); - scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData); child_pass_list.swap(child_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = std::move(child_frame_data); SurfaceId child_surface_id = allocator_.GenerateId(); @@ -1234,11 +1239,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { // 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( + std::unique_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); + std::unique_ptr<CompositorFrame> parent_surface_frame(new CompositorFrame); parent_surface_frame->delegated_frame_data = std::move(parent_surface_frame_data); @@ -1271,16 +1276,16 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { root_pass_list[0]->damage_rect = gfx::Rect(5, 5, 10, 10); root_pass_list[1]->damage_rect = gfx::Rect(5, 5, 100, 100); - scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); root_pass_list.swap(root_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = std::move(root_frame_data); factory_.SubmitCompositorFrame(root_surface_id_, std::move(root_frame), SurfaceFactory::DrawCallback()); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1308,16 +1313,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { 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); + std::unique_ptr<DelegatedFrameData> child_frame_data( + new DelegatedFrameData); child_pass_list.swap(child_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = std::move(child_frame_data); factory_.SubmitCompositorFrame(child_surface_id, std::move(child_frame), SurfaceFactory::DrawCallback()); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1348,10 +1354,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { ->quad_to_target_transform.Translate(0, 10); root_pass_list[0]->damage_rect = gfx::Rect(0, 0, 1, 1); - scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); root_pass_list.swap(root_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = std::move(root_frame_data); factory_.SubmitCompositorFrame(root_surface_id_, std::move(root_frame), @@ -1370,16 +1376,16 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { ->quad_to_target_transform.Translate(0, 10); root_pass_list[0]->damage_rect = gfx::Rect(1, 1, 1, 1); - scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); root_pass_list.swap(root_frame_data->render_pass_list); - scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = std::move(root_frame_data); factory_.SubmitCompositorFrame(root_surface_id_, std::move(root_frame), SurfaceFactory::DrawCallback()); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1400,7 +1406,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { // No Surface changed, so no damage should be given. { - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1420,7 +1426,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { // marked as damaged. { aggregator_.SetFullDamageForSurface(root_surface_id_); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1440,6 +1446,113 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { factory_.Destroy(child_surface_id); } +// Check that damage is correctly calculated for surfaces with +// SetPreviousFrameSurface. +TEST_F(SurfaceAggregatorValidSurfaceTest, SwitchSurfaceDamage) { + test::Quad root_render_pass_quads[] = {test::Quad::SolidColorQuad(1)}; + + test::Pass root_passes[] = {test::Pass(root_render_pass_quads, + arraysize(root_render_pass_quads), + RenderPassId(2, 1))}; + + RenderPassList root_pass_list; + AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes, + arraysize(root_passes)); + + root_pass_list[0]->damage_rect = gfx::Rect(5, 5, 100, 100); + + std::unique_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + root_pass_list.swap(root_frame_data->render_pass_list); + + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); + root_frame->delegated_frame_data = std::move(root_frame_data); + + factory_.SubmitCompositorFrame(root_surface_id_, std::move(root_frame), + SurfaceFactory::DrawCallback()); + + { + std::unique_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(root_surface_id_); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = + aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // Damage rect for first aggregation should contain entire root surface. + EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.Contains( + gfx::Rect(SurfaceSize()))); + } + + SurfaceId second_root_surface_id = allocator_.GenerateId(); + { + test::Quad root_render_pass_quads[] = {test::Quad::SolidColorQuad(1)}; + + test::Pass root_passes[] = {test::Pass(root_render_pass_quads, + arraysize(root_render_pass_quads), + RenderPassId(2, 1))}; + + RenderPassList root_pass_list; + AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes, + arraysize(root_passes)); + + root_pass_list[0]->damage_rect = gfx::Rect(1, 2, 3, 4); + + std::unique_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + root_pass_list.swap(root_frame_data->render_pass_list); + + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); + root_frame->delegated_frame_data = std::move(root_frame_data); + + factory_.Create(second_root_surface_id); + factory_.SubmitCompositorFrame(second_root_surface_id, + std::move(root_frame), + SurfaceFactory::DrawCallback()); + factory_.SetPreviousFrameSurface(second_root_surface_id, root_surface_id_); + } + { + std::unique_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(second_root_surface_id); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = + aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // Frame from SetPreviousFrameSurface was aggregated last, so damage rect + // from new surface should be used. + EXPECT_EQ(gfx::Rect(1, 2, 3, 4), aggregated_pass_list[0]->damage_rect); + } + { + std::unique_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(second_root_surface_id); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = + aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // No new frame, so no new damage. + EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.IsEmpty()); + } + factory_.Destroy(second_root_surface_id); +} + class SurfaceAggregatorPartialSwapTest : public SurfaceAggregatorValidSurfaceTest { public: @@ -1451,16 +1564,18 @@ class SurfaceAggregatorPartialSwapTest TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { SurfaceId child_surface_id = allocator_.GenerateId(); factory_.Create(child_surface_id); - // The child surface has two quads, one with a visible rect of 13,13 4x4 and + // The child surface has three quads, one with a visible rect of 13,13 4x4 and // the other other with a visible rect of 10,10 2x2 (relative to root target - // space). + // space), and one with a non-invertible transform. { RenderPassId child_pass_id = RenderPassId(1, 1); test::Quad child_quads1[] = {test::Quad::RenderPassQuad(child_pass_id)}; test::Quad child_quads2[] = {test::Quad::RenderPassQuad(child_pass_id)}; + test::Quad child_quads3[] = {test::Quad::RenderPassQuad(child_pass_id)}; test::Pass child_passes[] = { test::Pass(child_quads1, arraysize(child_quads1), child_pass_id), - test::Pass(child_quads2, arraysize(child_quads2), child_pass_id)}; + test::Pass(child_quads2, arraysize(child_quads2), child_pass_id), + test::Pass(child_quads3, arraysize(child_quads2), child_pass_id)}; RenderPassList child_pass_list; AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes, @@ -1476,6 +1591,15 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { child_pass_list[1]->quad_list.ElementAt(0)->visible_rect = gfx::Rect(0, 0, 2, 2); + SharedQuadState* child_noninvertible_sqs = + child_pass_list[2]->shared_quad_state_list.ElementAt(0u); + child_noninvertible_sqs->quad_to_target_transform.matrix().setDouble(0, 0, + 0.0); + EXPECT_FALSE( + child_noninvertible_sqs->quad_to_target_transform.IsInvertible()); + child_pass_list[2]->quad_list.ElementAt(0)->visible_rect = + gfx::Rect(0, 0, 2, 2); + SubmitPassListAsFrame(child_surface_id, &child_pass_list); } @@ -1496,7 +1620,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { SubmitPassListAsFrame(root_surface_id_, &root_pass_list); } - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1506,12 +1630,13 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; - ASSERT_EQ(2u, aggregated_pass_list.size()); + ASSERT_EQ(3u, aggregated_pass_list.size()); // Damage rect for first aggregation should contain entire root surface. - EXPECT_EQ(gfx::Rect(0, 0, 15, 15), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[2]->damage_rect); EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); // Create a root surface with a smaller damage rect. { @@ -1531,7 +1656,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { } { - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1542,26 +1667,27 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; - ASSERT_EQ(2u, aggregated_pass_list.size()); + ASSERT_EQ(3u, aggregated_pass_list.size()); // Only first quad from surface is inside damage rect and should be // included. - EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect); EXPECT_EQ(0u, aggregated_pass_list[0]->quad_list.size()); EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); EXPECT_EQ(gfx::Rect(0, 0, 2, 2), aggregated_pass_list[1]->quad_list.back()->visible_rect); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); } // New child frame has same content and no damage, but has a // CopyOutputRequest. { - RenderPassId child_pass_id = RenderPassId(1, 1); - test::Quad child_quads1[] = {test::Quad::RenderPassQuad(child_pass_id)}; - test::Quad child_quads2[] = {test::Quad::RenderPassQuad(child_pass_id)}; + RenderPassId child_pass_ids[] = {RenderPassId(1, 1), RenderPassId(1, 2)}; + test::Quad child_quads1[] = {test::Quad::SolidColorQuad(1)}; + test::Quad child_quads2[] = {test::Quad::RenderPassQuad(child_pass_ids[0])}; test::Pass child_passes[] = { - test::Pass(child_quads1, arraysize(child_quads1), child_pass_id), - test::Pass(child_quads2, arraysize(child_quads2), child_pass_id)}; + test::Pass(child_quads1, arraysize(child_quads1), child_pass_ids[0]), + test::Pass(child_quads2, arraysize(child_quads2), child_pass_ids[1])}; RenderPassList child_pass_list; AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes, @@ -1586,7 +1712,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { } { - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1600,17 +1726,20 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { // Output frame should have no damage, but all quads included. ASSERT_EQ(3u, aggregated_pass_list.size()); - EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.IsEmpty()); + EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect); + EXPECT_TRUE(aggregated_pass_list[2]->damage_rect.IsEmpty()); ASSERT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); ASSERT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); EXPECT_EQ(gfx::Rect(1, 1, 2, 2), aggregated_pass_list[0]->quad_list.ElementAt(0)->visible_rect); EXPECT_EQ(gfx::Rect(0, 0, 2, 2), aggregated_pass_list[1]->quad_list.ElementAt(0)->visible_rect); + ASSERT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); } { - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); @@ -1627,6 +1756,110 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { ASSERT_EQ(0u, aggregated_pass_list[0]->quad_list.size()); } + // Root surface has smaller damage rect, but filter on render pass means all + // of it should be aggregated. + { + RenderPassId root_pass_ids[] = {RenderPassId(1, 1), RenderPassId(1, 2)}; + test::Quad root_quads1[] = {test::Quad::SurfaceQuad(child_surface_id, 1.f)}; + test::Quad root_quads2[] = {test::Quad::RenderPassQuad(root_pass_ids[0])}; + test::Pass root_passes[] = { + test::Pass(root_quads1, arraysize(root_quads1), root_pass_ids[0]), + test::Pass(root_quads2, arraysize(root_quads2), root_pass_ids[1])}; + + RenderPassList root_pass_list; + AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes, + arraysize(root_passes)); + + RenderPass* pass = root_pass_list[0].get(); + pass->shared_quad_state_list.front()->quad_to_target_transform.Translate( + 10, 10); + RenderPass* root_pass = root_pass_list[1].get(); + RenderPassDrawQuad* quad = + static_cast<RenderPassDrawQuad*>(root_pass->quad_list.front()); + quad->filters.Append(FilterOperation::CreateBlurFilter(2)); + root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); + SubmitPassListAsFrame(root_surface_id_, &root_pass_list); + } + + { + std::unique_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(root_surface_id_); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = + aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(3u, aggregated_pass_list.size()); + + EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + // First render pass draw quad is outside damage rect, so shouldn't be + // drawn. + EXPECT_EQ(0u, aggregated_pass_list[2]->quad_list.size()); + } + + // Root surface has smaller damage rect. Background filter on render pass + // means Surface + // quad under it should be aggregated. + { + RenderPassId root_pass_ids[] = {RenderPassId(1, 1), RenderPassId(1, 2)}; + test::Quad root_quads1[] = { + test::Quad::SolidColorQuad(1), + }; + test::Quad root_quads2[] = {test::Quad::RenderPassQuad(root_pass_ids[0]), + test::Quad::SurfaceQuad(child_surface_id, 1.f)}; + test::Pass root_passes[] = { + test::Pass(root_quads1, arraysize(root_quads1), root_pass_ids[0]), + test::Pass(root_quads2, arraysize(root_quads2), root_pass_ids[1])}; + + RenderPassList root_pass_list; + AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes, + arraysize(root_passes)); + + RenderPass* root_pass = root_pass_list[1].get(); + root_pass->shared_quad_state_list.ElementAt(1) + ->quad_to_target_transform.Translate(10, 10); + RenderPassDrawQuad* quad = + static_cast<RenderPassDrawQuad*>(root_pass->quad_list.front()); + quad->background_filters.Append(FilterOperation::CreateBlurFilter(2)); + root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); + SubmitPassListAsFrame(root_surface_id_, &root_pass_list); + } + + { + std::unique_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(root_surface_id_); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = + aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(3u, aggregated_pass_list.size()); + + // Pass 0 is solid color quad from root, but outside damage rect. + EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(0u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + + // First render pass draw quad is outside damage rect, so shouldn't be + // drawn. SurfaceDrawQuad is after background filter, so corresponding + // RenderPassDrawQuad should be drawn. + EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + } + factory_.Destroy(child_surface_id); } @@ -1634,7 +1867,7 @@ class SurfaceAggregatorWithResourcesTest : public testing::Test { public: void SetUp() override { output_surface_ = FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager); @@ -1643,15 +1876,16 @@ class SurfaceAggregatorWithResourcesTest : public testing::Test { aggregator_.reset( new SurfaceAggregator(&manager_, resource_provider_.get(), false)); + aggregator_->set_output_is_secure(true); } protected: SurfaceManager manager_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<SurfaceAggregator> aggregator_; + std::unique_ptr<OutputSurface> output_surface_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<SurfaceAggregator> aggregator_; }; class ResourceTrackingSurfaceFactoryClient : public SurfaceFactoryClient { @@ -1681,8 +1915,8 @@ void SubmitCompositorFrameWithResources(ResourceId* resource_ids, SurfaceId child_id, SurfaceFactory* factory, SurfaceId surface_id) { - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->id = RenderPassId(1, 1); SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); sqs->opacity = 1.f; @@ -1711,13 +1945,14 @@ void SubmitCompositorFrameWithResources(ResourceId* resource_ids, const float vertex_opacity[4] = {0.f, 0.f, 1.f, 1.f}; bool flipped = false; bool nearest_neighbor = false; + bool secure_output_only = true; quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending, resource_ids[i], gfx::Size(), premultiplied_alpha, uv_top_left, uv_bottom_right, background_color, vertex_opacity, flipped, - nearest_neighbor); + nearest_neighbor, secure_output_only); } frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory->SubmitCompositorFrame(surface_id, std::move(frame), SurfaceFactory::DrawCallback()); @@ -1733,7 +1968,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) { SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), &factory, surface_id); - scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id); + std::unique_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id); // Nothing should be available to be returned yet. EXPECT_TRUE(client.returned_resources().empty()); @@ -1759,8 +1994,8 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { SurfaceId surface_id(7u); factory.Create(surface_id); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->id = RenderPassId(1, 1); TransferableResource resource; resource.id = 11; @@ -1769,12 +2004,12 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { resource.is_software = false; frame_data->resource_list.push_back(resource); frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory.SubmitCompositorFrame(surface_id, std::move(frame), SurfaceFactory::DrawCallback()); - scoped_ptr<CompositorFrame> returned_frame = + std::unique_ptr<CompositorFrame> returned_frame = aggregator_->Aggregate(surface_id); // Nothing should be available to be returned yet. @@ -1804,7 +2039,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) { SubmitCompositorFrameWithResources(ids2, arraysize(ids2), true, SurfaceId(), &factory, surface2_id); - scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface1_id); + std::unique_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface1_id); SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), &factory, surface1_id); @@ -1853,7 +2088,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { middle_surface_id, &factory, root_surface_id); - scoped_ptr<CompositorFrame> frame; + std::unique_ptr<CompositorFrame> frame; frame = aggregator_->Aggregate(root_surface_id); RenderPassList* pass_list = &frame->delegated_frame_data->render_pass_list; @@ -1877,6 +2112,72 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { factory.Destroy(middle_surface_id); } +TEST_F(SurfaceAggregatorWithResourcesTest, SecureOutputTexture) { + ResourceTrackingSurfaceFactoryClient client; + SurfaceFactory factory(&manager_, &client); + SurfaceId surface1_id(7u); + factory.Create(surface1_id); + + SurfaceId surface2_id(8u); + factory.Create(surface2_id); + + ResourceId ids[] = {11, 12, 13}; + SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), + &factory, surface1_id); + + std::unique_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface1_id); + + RenderPass* render_pass = + frame->delegated_frame_data->render_pass_list.back().get(); + + EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, render_pass->quad_list.back()->material); + + { + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); + pass->id = RenderPassId(1, 1); + SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); + sqs->opacity = 1.f; + SurfaceDrawQuad* surface_quad = + pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); + surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1), + surface1_id); + pass->copy_requests.push_back(CopyOutputRequest::CreateEmptyRequest()); + + frame_data->render_pass_list.push_back(std::move(pass)); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); + frame->delegated_frame_data = std::move(frame_data); + factory.SubmitCompositorFrame(surface2_id, std::move(frame), + SurfaceFactory::DrawCallback()); + } + + frame = aggregator_->Aggregate(surface2_id); + EXPECT_EQ(1u, frame->delegated_frame_data->render_pass_list.size()); + render_pass = frame->delegated_frame_data->render_pass_list.front().get(); + + // Parent has copy request, so texture should not be drawn. + EXPECT_EQ(DrawQuad::SOLID_COLOR, render_pass->quad_list.back()->material); + + frame = aggregator_->Aggregate(surface2_id); + EXPECT_EQ(1u, frame->delegated_frame_data->render_pass_list.size()); + render_pass = frame->delegated_frame_data->render_pass_list.front().get(); + + // Copy request has been executed earlier, so texture should be drawn. + EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, + render_pass->quad_list.front()->material); + + aggregator_->set_output_is_secure(false); + + frame = aggregator_->Aggregate(surface2_id); + render_pass = frame->delegated_frame_data->render_pass_list.back().get(); + + // Output is insecure, so texture should be drawn. + EXPECT_EQ(DrawQuad::SOLID_COLOR, render_pass->quad_list.back()->material); + + factory.Destroy(surface1_id); + factory.Destroy(surface2_id); +} + } // namespace } // namespace cc diff --git a/chromium/cc/surfaces/surface_display_output_surface.cc b/chromium/cc/surfaces/surface_display_output_surface.cc index dfb491ede62..749791ef0de 100644 --- a/chromium/cc/surfaces/surface_display_output_surface.cc +++ b/chromium/cc/surfaces/surface_display_output_surface.cc @@ -21,7 +21,7 @@ SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface( scoped_refptr<ContextProvider> worker_context_provider) : OutputSurface(std::move(context_provider), std::move(worker_context_provider)), - display_client_(NULL), + display_client_(nullptr), factory_(surface_manager, this), allocator_(allocator) { factory_.set_needs_sync_points(false); @@ -33,6 +33,22 @@ SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface( capabilities_.delegated_sync_points_required = false; } +SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface( + SurfaceManager* surface_manager, + SurfaceIdAllocator* allocator, + scoped_refptr<VulkanContextProvider> vulkan_context_provider) + : OutputSurface(nullptr, + nullptr, + std::move(vulkan_context_provider), + nullptr), + display_client_(NULL), + factory_(surface_manager, this), + allocator_(allocator) { + capabilities_.delegated_rendering = true; + capabilities_.adjust_deadline_for_parent = true; + capabilities_.can_force_reclaim_resources = true; +} + SurfaceDisplayOutputSurface::~SurfaceDisplayOutputSurface() { if (HasClient()) DetachFromClient(); @@ -41,12 +57,6 @@ SurfaceDisplayOutputSurface::~SurfaceDisplayOutputSurface() { } } -void SurfaceDisplayOutputSurface::ReceivedVSyncParameters( - base::TimeTicks timebase, - base::TimeDelta interval) { - CommitVSyncParameters(timebase, interval); -} - void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) { gfx::Size frame_size = frame->delegated_frame_data->render_pass_list.back()->output_rect.size(); @@ -63,7 +73,7 @@ void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) { client_->DidSwapBuffers(); - scoped_ptr<CompositorFrame> frame_copy(new CompositorFrame()); + std::unique_ptr<CompositorFrame> frame_copy(new CompositorFrame()); frame->AssignTo(frame_copy.get()); factory_.SubmitCompositorFrame( surface_id_, std::move(frame_copy), @@ -74,10 +84,10 @@ void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) { bool SurfaceDisplayOutputSurface::BindToClient(OutputSurfaceClient* client) { DCHECK(client); DCHECK(display_client_); + client_ = client; factory_.manager()->RegisterSurfaceFactoryClient(allocator_->id_namespace(), this); - client_ = client; // Avoid initializing GL context here, as this should be sharing the // Display's context. return display_client_->Initialize(); @@ -109,7 +119,8 @@ void SurfaceDisplayOutputSurface::ReturnResources( void SurfaceDisplayOutputSurface::SetBeginFrameSource( BeginFrameSource* begin_frame_source) { - // TODO(tansell): Hook this up. + DCHECK(client_); + client_->SetBeginFrameSource(begin_frame_source); } void SurfaceDisplayOutputSurface::SwapBuffersComplete(SurfaceDrawStatus drawn) { diff --git a/chromium/cc/surfaces/surface_display_output_surface.h b/chromium/cc/surfaces/surface_display_output_surface.h index cececd3b012..d9abb70bf7a 100644 --- a/chromium/cc/surfaces/surface_display_output_surface.h +++ b/chromium/cc/surfaces/surface_display_output_surface.h @@ -30,14 +30,17 @@ class CC_SURFACES_EXPORT SurfaceDisplayOutputSurface SurfaceIdAllocator* allocator, scoped_refptr<ContextProvider> context_provider, scoped_refptr<ContextProvider> worker_context_provider); + SurfaceDisplayOutputSurface( + SurfaceManager* surface_manager, + SurfaceIdAllocator* allocator, + scoped_refptr<VulkanContextProvider> vulkan_context_provider); ~SurfaceDisplayOutputSurface() override; void set_display_client(OnscreenDisplayClient* display_client) { + DCHECK(!display_client_); display_client_ = display_client; } SurfaceFactory* factory() { return &factory_; } - void ReceivedVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval); // OutputSurface implementation. void SwapBuffers(CompositorFrame* frame) override; diff --git a/chromium/cc/surfaces/surface_display_output_surface_unittest.cc b/chromium/cc/surfaces/surface_display_output_surface_unittest.cc index 367891cd5b7..f263363bd14 100644 --- a/chromium/cc/surfaces/surface_display_output_surface_unittest.cc +++ b/chromium/cc/surfaces/surface_display_output_surface_unittest.cc @@ -4,6 +4,8 @@ #include "cc/surfaces/surface_display_output_surface.h" +#include <memory> + #include "cc/surfaces/onscreen_display_client.h" #include "cc/surfaces/surface_id_allocator.h" #include "cc/surfaces/surface_manager.h" @@ -25,13 +27,15 @@ class FakeOnscreenDisplayClient : public OnscreenDisplayClient { SharedBitmapManager* bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& settings, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + uint32_t compositor_surface_namespace) : OnscreenDisplayClient(FakeOutputSurface::Create3d(), manager, bitmap_manager, gpu_memory_buffer_manager, settings, - task_runner) { + task_runner, + compositor_surface_namespace) { // Ownership is passed to another object later, store a pointer // to it now for future reference. fake_output_surface_ = @@ -57,7 +61,8 @@ class SurfaceDisplayOutputSurfaceTest : public testing::Test { &bitmap_manager_, &gpu_memory_buffer_manager_, renderer_settings_, - task_runner_), + task_runner_, + allocator_.id_namespace()), context_provider_(TestContextProvider::Create()), surface_display_output_surface_(&surface_manager_, &allocator_, @@ -68,8 +73,16 @@ class SurfaceDisplayOutputSurfaceTest : public testing::Test { display_client_.set_surface_output_surface( &surface_display_output_surface_); surface_display_output_surface_.set_display_client(&display_client_); + + // Set the Display's begin frame source like a real browser compositor + // output surface would. + begin_frame_source_.reset( + new BackToBackBeginFrameSource(task_runner_.get())); + display_client_.display()->SetBeginFrameSource(begin_frame_source_.get()); + surface_display_output_surface_.BindToClient( &surface_display_output_surface_client_); + display_client_.display()->Resize(display_size_); EXPECT_FALSE(surface_display_output_surface_client_ @@ -79,11 +92,11 @@ class SurfaceDisplayOutputSurfaceTest : public testing::Test { ~SurfaceDisplayOutputSurfaceTest() override {} void SwapBuffersWithDamage(const gfx::Rect& damage_rect_) { - scoped_ptr<RenderPass> render_pass(RenderPass::Create()); + std::unique_ptr<RenderPass> render_pass(RenderPass::Create()); render_pass->SetNew(RenderPassId(1, 1), display_rect_, damage_rect_, gfx::Transform()); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); frame_data->render_pass_list.push_back(std::move(render_pass)); CompositorFrame frame; @@ -102,8 +115,9 @@ class SurfaceDisplayOutputSurfaceTest : public testing::Test { } protected: - scoped_ptr<base::SimpleTestTickClock> now_src_; + std::unique_ptr<base::SimpleTestTickClock> now_src_; scoped_refptr<OrderedSimpleTaskRunner> task_runner_; + std::unique_ptr<BackToBackBeginFrameSource> begin_frame_source_; SurfaceIdAllocator allocator_; const gfx::Size display_size_; diff --git a/chromium/cc/surfaces/surface_factory.cc b/chromium/cc/surfaces/surface_factory.cc index d7f4810d688..aca36bb9398 100644 --- a/chromium/cc/surfaces/surface_factory.cc +++ b/chromium/cc/surfaces/surface_factory.cc @@ -38,7 +38,7 @@ void SurfaceFactory::DestroyAll() { } void SurfaceFactory::Create(SurfaceId surface_id) { - scoped_ptr<Surface> surface(new Surface(surface_id, this)); + std::unique_ptr<Surface> surface(new Surface(surface_id, this)); manager_->RegisterSurface(surface.get()); DCHECK(!surface_map_.count(surface_id)); surface_map_[surface_id] = std::move(surface); @@ -48,14 +48,25 @@ void SurfaceFactory::Destroy(SurfaceId surface_id) { OwningSurfaceMap::iterator it = surface_map_.find(surface_id); DCHECK(it != surface_map_.end()); DCHECK(it->second->factory().get() == this); - scoped_ptr<Surface> surface(std::move(it->second)); + std::unique_ptr<Surface> surface(std::move(it->second)); surface_map_.erase(it); manager_->Destroy(std::move(surface)); } -void SurfaceFactory::SubmitCompositorFrame(SurfaceId surface_id, - scoped_ptr<CompositorFrame> frame, - const DrawCallback& callback) { +void SurfaceFactory::SetPreviousFrameSurface(SurfaceId new_id, + SurfaceId old_id) { + OwningSurfaceMap::iterator it = surface_map_.find(new_id); + DCHECK(it != surface_map_.end()); + Surface* old_surface = manager_->GetSurfaceForId(old_id); + if (old_surface) { + it->second->SetPreviousFrameSurface(old_surface); + } +} + +void SurfaceFactory::SubmitCompositorFrame( + SurfaceId surface_id, + std::unique_ptr<CompositorFrame> frame, + const DrawCallback& callback) { TRACE_EVENT0("cc", "SurfaceFactory::SubmitCompositorFrame"); OwningSurfaceMap::iterator it = surface_map_.find(surface_id); DCHECK(it != surface_map_.end()); @@ -69,7 +80,7 @@ void SurfaceFactory::SubmitCompositorFrame(SurfaceId surface_id, void SurfaceFactory::RequestCopyOfSurface( SurfaceId surface_id, - scoped_ptr<CopyOutputRequest> copy_request) { + std::unique_ptr<CopyOutputRequest> copy_request) { OwningSurfaceMap::iterator it = surface_map_.find(surface_id); if (it == surface_map_.end()) { copy_request->SendEmptyResult(); diff --git a/chromium/cc/surfaces/surface_factory.h b/chromium/cc/surfaces/surface_factory.h index 742cc2a4730..1cb7d6fe0ae 100644 --- a/chromium/cc/surfaces/surface_factory.h +++ b/chromium/cc/surfaces/surface_factory.h @@ -5,12 +5,12 @@ #ifndef CC_SURFACES_SURFACE_FACTORY_H_ #define CC_SURFACES_SURFACE_FACTORY_H_ +#include <memory> #include <set> #include <unordered_map> #include "base/callback_forward.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "cc/output/compositor_frame.h" @@ -49,15 +49,19 @@ class CC_SURFACES_EXPORT SurfaceFactory void Destroy(SurfaceId surface_id); void DestroyAll(); + // Set that the current frame on new_id is to be treated as the successor to + // the current frame on old_id for the purposes of calculating damage. + void SetPreviousFrameSurface(SurfaceId new_id, SurfaceId old_id); + // A frame can only be submitted to a surface created by this factory, // although the frame may reference surfaces created by other factories. // The callback is called the first time this frame is used to draw, or if // the frame is discarded. void SubmitCompositorFrame(SurfaceId surface_id, - scoped_ptr<CompositorFrame> frame, + std::unique_ptr<CompositorFrame> frame, const DrawCallback& callback); void RequestCopyOfSurface(SurfaceId surface_id, - scoped_ptr<CopyOutputRequest> copy_request); + std::unique_ptr<CopyOutputRequest> copy_request); void WillDrawSurface(SurfaceId id, const gfx::Rect& damage_rect); @@ -83,7 +87,7 @@ class CC_SURFACES_EXPORT SurfaceFactory bool needs_sync_points_; using OwningSurfaceMap = - std::unordered_map<SurfaceId, scoped_ptr<Surface>, SurfaceIdHash>; + std::unordered_map<SurfaceId, std::unique_ptr<Surface>, SurfaceIdHash>; OwningSurfaceMap surface_map_; DISALLOW_COPY_AND_ASSIGN(SurfaceFactory); diff --git a/chromium/cc/surfaces/surface_factory_unittest.cc b/chromium/cc/surfaces/surface_factory_unittest.cc index a48d6699d29..1d7a8b92d66 100644 --- a/chromium/cc/surfaces/surface_factory_unittest.cc +++ b/chromium/cc/surfaces/surface_factory_unittest.cc @@ -69,14 +69,14 @@ class SurfaceFactoryTest : public testing::Test { void SubmitCompositorFrameWithResources(ResourceId* resource_ids, size_t num_resource_ids) { - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); for (size_t i = 0u; i < num_resource_ids; ++i) { TransferableResource resource; resource.id = resource_ids[i]; resource.mailbox_holder.texture_target = GL_TEXTURE_2D; frame_data->resource_list.push_back(resource); } - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(surface_id_, std::move(frame), SurfaceFactory::DrawCallback()); @@ -118,7 +118,7 @@ class SurfaceFactoryTest : public testing::Test { protected: SurfaceManager manager_; TestSurfaceFactoryClient client_; - scoped_ptr<SurfaceFactory> factory_; + std::unique_ptr<SurfaceFactory> factory_; SurfaceId surface_id_; }; @@ -394,7 +394,7 @@ TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) { Surface* surface = manager_.GetSurfaceForId(surface_id); ASSERT_NE(nullptr, surface); EXPECT_EQ(2, surface->frame_index()); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data.reset(new DelegatedFrameData); factory_->SubmitCompositorFrame(surface_id, std::move(frame), @@ -415,12 +415,12 @@ TEST_F(SurfaceFactoryTest, DestroyAll) { SurfaceId id(7); factory_->Create(id); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); TransferableResource resource; resource.id = 1; resource.mailbox_holder.texture_target = GL_TEXTURE_2D; frame_data->resource_list.push_back(resource); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = std::move(frame_data); uint32_t execute_count = 0; SurfaceDrawStatus drawn = SurfaceDrawStatus::DRAW_SKIPPED; @@ -445,8 +445,8 @@ TEST_F(SurfaceFactoryTest, DestroySequence) { ->AddDestructionDependency(SurfaceSequence(0, 4)); factory_->Destroy(id2); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->metadata.satisfies_sequences.push_back(6); frame->metadata.satisfies_sequences.push_back(4); frame->delegated_frame_data = std::move(frame_data); @@ -497,10 +497,10 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { // Give id2 a frame that references surface_id_. { - scoped_ptr<RenderPass> render_pass(RenderPass::Create()); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> render_pass(RenderPass::Create()); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); frame_data->render_pass_list.push_back(std::move(render_pass)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->metadata.referenced_surfaces.push_back(surface_id_); frame->delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(id2, std::move(frame), @@ -510,10 +510,10 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { // Give surface_id_ a frame that references id2. { - scoped_ptr<RenderPass> render_pass(RenderPass::Create()); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> render_pass(RenderPass::Create()); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); frame_data->render_pass_list.push_back(std::move(render_pass)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->metadata.referenced_surfaces.push_back(id2); frame->delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(surface_id_, std::move(frame), @@ -538,16 +538,16 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { } void CopyRequestTestCallback(bool* called, - scoped_ptr<CopyOutputResult> result) { + std::unique_ptr<CopyOutputResult> result) { *called = true; } TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { { - scoped_ptr<RenderPass> render_pass(RenderPass::Create()); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<RenderPass> render_pass(RenderPass::Create()); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); frame_data->render_pass_list.push_back(std::move(render_pass)); - scoped_ptr<CompositorFrame> frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> frame(new CompositorFrame); frame->metadata.referenced_surfaces.push_back(surface_id_); frame->delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(surface_id_, std::move(frame), @@ -557,7 +557,7 @@ TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { void* source2 = &source2; bool called1 = false; - scoped_ptr<CopyOutputRequest> request; + std::unique_ptr<CopyOutputRequest> request; request = CopyOutputRequest::CreateRequest( base::Bind(&CopyRequestTestCallback, &called1)); request->set_source(source1); diff --git a/chromium/cc/surfaces/surface_hittest_unittest.cc b/chromium/cc/surfaces/surface_hittest_unittest.cc index 9c1309c4a37..fec65094221 100644 --- a/chromium/cc/surfaces/surface_hittest_unittest.cc +++ b/chromium/cc/surfaces/surface_hittest_unittest.cc @@ -66,7 +66,7 @@ TEST(SurfaceHittestTest, Hittest_BadCompositorFrameDoesNotCrash) { // Creates a root surface. gfx::Rect root_rect(300, 300); RenderPass* root_pass = nullptr; - scoped_ptr<CompositorFrame> root_frame = + std::unique_ptr<CompositorFrame> root_frame = CreateCompositorFrame(root_rect, &root_pass); // Add a reference to a non-existant child surface on the root surface. @@ -107,7 +107,7 @@ TEST(SurfaceHittestTest, Hittest_SingleSurface) { // Creates a root surface. gfx::Rect root_rect(300, 300); RenderPass* root_pass = nullptr; - scoped_ptr<CompositorFrame> root_frame = + std::unique_ptr<CompositorFrame> root_frame = CreateCompositorFrame(root_rect, &root_pass); // Submit the root frame. @@ -138,7 +138,7 @@ TEST(SurfaceHittestTest, Hittest_ChildSurface) { // Creates a root surface. gfx::Rect root_rect(300, 300); RenderPass* root_pass = nullptr; - scoped_ptr<CompositorFrame> root_frame = + std::unique_ptr<CompositorFrame> root_frame = CreateCompositorFrame(root_rect, &root_pass); // Add a reference to the child surface on the root surface. @@ -163,7 +163,7 @@ TEST(SurfaceHittestTest, Hittest_ChildSurface) { // Creates a child surface. RenderPass* child_pass = nullptr; - scoped_ptr<CompositorFrame> child_frame = + std::unique_ptr<CompositorFrame> child_frame = CreateCompositorFrame(child_rect, &child_pass); // Add a solid quad in the child surface. @@ -271,7 +271,7 @@ TEST(SurfaceHittestTest, Hittest_InvalidRenderPassDrawQuad) { // Creates a root surface. gfx::Rect root_rect(300, 300); RenderPass* root_pass = nullptr; - scoped_ptr<CompositorFrame> root_frame = + std::unique_ptr<CompositorFrame> root_frame = CreateCompositorFrame(root_rect, &root_pass); // Create a RenderPassDrawQuad to a non-existant RenderPass. @@ -303,7 +303,7 @@ TEST(SurfaceHittestTest, Hittest_InvalidRenderPassDrawQuad) { // Creates a child surface. RenderPass* child_pass = nullptr; - scoped_ptr<CompositorFrame> child_frame = + std::unique_ptr<CompositorFrame> child_frame = CreateCompositorFrame(child_rect, &child_pass); // Add a solid quad in the child surface. @@ -392,7 +392,7 @@ TEST(SurfaceHittestTest, Hittest_RenderPassDrawQuad) { &render_pass_list); RenderPass* root_pass = nullptr; - scoped_ptr<CompositorFrame> root_frame = + std::unique_ptr<CompositorFrame> root_frame = CreateCompositorFrameWithRenderPassList(&render_pass_list); root_pass = root_frame->delegated_frame_data->render_pass_list.back().get(); @@ -477,7 +477,7 @@ TEST(SurfaceHittestTest, Hittest_SingleSurface_WithInsetsDelegate) { // Creates a root surface. gfx::Rect root_rect(300, 300); RenderPass* root_pass = nullptr; - scoped_ptr<CompositorFrame> root_frame = + std::unique_ptr<CompositorFrame> root_frame = CreateCompositorFrame(root_rect, &root_pass); // Add a reference to the child surface on the root surface. @@ -501,7 +501,7 @@ TEST(SurfaceHittestTest, Hittest_SingleSurface_WithInsetsDelegate) { // Creates a child surface. RenderPass* child_pass = nullptr; - scoped_ptr<CompositorFrame> child_frame = + std::unique_ptr<CompositorFrame> child_frame = CreateCompositorFrame(child_rect, &child_pass); // Add a solid quad in the child surface. diff --git a/chromium/cc/surfaces/surface_manager.cc b/chromium/cc/surfaces/surface_manager.cc index d22d1e56c73..b97523216e6 100644 --- a/chromium/cc/surfaces/surface_manager.cc +++ b/chromium/cc/surfaces/surface_manager.cc @@ -57,7 +57,7 @@ void SurfaceManager::DeregisterSurface(SurfaceId surface_id) { surface_map_.erase(it); } -void SurfaceManager::Destroy(scoped_ptr<Surface> surface) { +void SurfaceManager::Destroy(std::unique_ptr<Surface> surface) { DCHECK(thread_checker_.CalledOnValidThread()); surface->set_destroyed(true); surfaces_to_destroy_.push_back(surface.release()); @@ -127,7 +127,7 @@ void SurfaceManager::GarbageCollectSurfaces() { for (SurfaceDestroyList::iterator dest_it = surfaces_to_destroy_.begin(); dest_it != surfaces_to_destroy_.end();) { if (!live_surfaces_set.count((*dest_it)->surface_id())) { - scoped_ptr<Surface> surf(*dest_it); + std::unique_ptr<Surface> surf(*dest_it); DeregisterSurface(surf->surface_id()); dest_it = surfaces_to_destroy_.erase(dest_it); } else { @@ -284,8 +284,11 @@ void SurfaceManager::RegisterSurfaceNamespaceHierarchy( void SurfaceManager::UnregisterSurfaceNamespaceHierarchy( uint32_t parent_namespace, uint32_t child_namespace) { - DCHECK_EQ(valid_surface_id_namespaces_.count(parent_namespace), 1u); - DCHECK_EQ(valid_surface_id_namespaces_.count(child_namespace), 1u); + // Deliberately do not check validity of either parent or child namespace + // here. They were valid during the registration, so were valid at some + // point in time. This makes it possible to invalidate parent and child + // namespaces independently of each other and not have an ordering dependency + // of unregistering the hierarchy first before either of them. DCHECK_EQ(namespace_client_map_.count(parent_namespace), 1u); auto iter = namespace_client_map_.find(parent_namespace); diff --git a/chromium/cc/surfaces/surface_manager.h b/chromium/cc/surfaces/surface_manager.h index 8bf3df8978f..c0ee515a2cc 100644 --- a/chromium/cc/surfaces/surface_manager.h +++ b/chromium/cc/surfaces/surface_manager.h @@ -8,12 +8,12 @@ #include <stdint.h> #include <list> +#include <memory> #include <unordered_map> #include <unordered_set> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "base/threading/thread_checker.h" #include "cc/surfaces/surface_damage_observer.h" @@ -36,7 +36,7 @@ class CC_SURFACES_EXPORT SurfaceManager { void DeregisterSurface(SurfaceId surface_id); // Destroy the Surface once a set of sequence numbers has been satisfied. - void Destroy(scoped_ptr<Surface> surface); + void Destroy(std::unique_ptr<Surface> surface); Surface* GetSurfaceForId(SurfaceId surface_id); diff --git a/chromium/cc/surfaces/surface_manager_unittest.cc b/chromium/cc/surfaces/surface_manager_unittest.cc index 7770d7f920e..05edb026ccf 100644 --- a/chromium/cc/surfaces/surface_manager_unittest.cc +++ b/chromium/cc/surfaces/surface_manager_unittest.cc @@ -44,7 +44,7 @@ class FakeSurfaceFactoryClient : public SurfaceFactoryClient { } // SurfaceFactoryClient implementation. - void ReturnResources(const ReturnedResourceArray& resources) override{}; + void ReturnResources(const ReturnedResourceArray& resources) override {} void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override { DCHECK(!source_ || !begin_frame_source); source_ = begin_frame_source; @@ -58,10 +58,10 @@ class FakeSurfaceFactoryClient : public SurfaceFactoryClient { class EmptyBeginFrameSource : public BeginFrameSource { public: - void DidFinishFrame(size_t remaining_frames) override{}; - void AddObserver(BeginFrameObserver* obs) override{}; - void RemoveObserver(BeginFrameObserver* obs) override{}; - void AsValueInto(base::trace_event::TracedValue* dict) const override{}; + void DidFinishFrame(BeginFrameObserver* obs, + size_t remaining_frames) override {} + void AddObserver(BeginFrameObserver* obs) override {} + void RemoveObserver(BeginFrameObserver* obs) override {} }; class SurfaceManagerTest : public testing::Test { diff --git a/chromium/cc/surfaces/surfaces_pixeltest.cc b/chromium/cc/surfaces/surfaces_pixeltest.cc index 405a3d814b6..9af4ed93e52 100644 --- a/chromium/cc/surfaces/surfaces_pixeltest.cc +++ b/chromium/cc/surfaces/surfaces_pixeltest.cc @@ -58,7 +58,7 @@ SharedQuadState* CreateAndAppendTestSharedQuadState( TEST_F(SurfacesPixelTest, DrawSimpleFrame) { gfx::Rect rect(device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetNew(id, rect, rect, gfx::Transform()); CreateAndAppendTestSharedQuadState( @@ -73,10 +73,11 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) { SK_ColorGREEN, force_anti_aliasing_off); - scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> delegated_frame_data( + new DelegatedFrameData); delegated_frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = std::move(delegated_frame_data); SurfaceId root_surface_id = allocator_.GenerateId(); @@ -85,7 +86,7 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) { SurfaceFactory::DrawCallback()); SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator.Aggregate(root_surface_id); factory_.Destroy(root_surface_id); @@ -108,7 +109,7 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { { gfx::Rect rect(device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetNew(id, rect, rect, gfx::Transform()); CreateAndAppendTestSharedQuadState( @@ -130,10 +131,11 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { SK_ColorYELLOW, force_anti_aliasing_off); - scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> delegated_frame_data( + new DelegatedFrameData); delegated_frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = std::move(delegated_frame_data); factory_.SubmitCompositorFrame(root_surface_id, std::move(root_frame), @@ -143,7 +145,7 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { { gfx::Rect rect(child_size); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetNew(id, rect, rect, gfx::Transform()); CreateAndAppendTestSharedQuadState( @@ -158,10 +160,11 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { SK_ColorBLUE, force_anti_aliasing_off); - scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> delegated_frame_data( + new DelegatedFrameData); delegated_frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = std::move(delegated_frame_data); factory_.SubmitCompositorFrame(child_surface_id, std::move(child_frame), @@ -169,7 +172,7 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { } SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator.Aggregate(root_surface_id); bool discard_alpha = false; @@ -204,7 +207,7 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { { gfx::Rect rect(device_viewport_size_); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetNew(id, rect, rect, gfx::Transform()); gfx::Transform surface_transform; @@ -229,10 +232,11 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { gfx::Rect(child_size), right_child_id); - scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> delegated_frame_data( + new DelegatedFrameData); delegated_frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> root_frame(new CompositorFrame); root_frame->delegated_frame_data = std::move(delegated_frame_data); factory_.SubmitCompositorFrame(root_surface_id, std::move(root_frame), @@ -242,7 +246,7 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { { gfx::Rect rect(child_size); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetNew(id, rect, rect, gfx::Transform()); CreateAndAppendTestSharedQuadState( @@ -265,10 +269,11 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { SK_ColorBLUE, force_anti_aliasing_off); - scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> delegated_frame_data( + new DelegatedFrameData); delegated_frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = std::move(delegated_frame_data); factory_.SubmitCompositorFrame(left_child_id, std::move(child_frame), @@ -278,7 +283,7 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { { gfx::Rect rect(child_size); RenderPassId id(1, 1); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetNew(id, rect, rect, gfx::Transform()); CreateAndAppendTestSharedQuadState( @@ -301,10 +306,11 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { SK_ColorGREEN, force_anti_aliasing_off); - scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> delegated_frame_data( + new DelegatedFrameData); delegated_frame_data->render_pass_list.push_back(std::move(pass)); - scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + std::unique_ptr<CompositorFrame> child_frame(new CompositorFrame); child_frame->delegated_frame_data = std::move(delegated_frame_data); factory_.SubmitCompositorFrame(right_child_id, std::move(child_frame), @@ -312,7 +318,7 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { } SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); - scoped_ptr<CompositorFrame> aggregated_frame = + std::unique_ptr<CompositorFrame> aggregated_frame = aggregator.Aggregate(root_surface_id); bool discard_alpha = false; diff --git a/chromium/cc/tiles/eviction_tile_priority_queue.cc b/chromium/cc/tiles/eviction_tile_priority_queue.cc index 5668f0f9ccb..e7fd54e8682 100644 --- a/chromium/cc/tiles/eviction_tile_priority_queue.cc +++ b/chromium/cc/tiles/eviction_tile_priority_queue.cc @@ -4,6 +4,8 @@ #include "cc/tiles/eviction_tile_priority_queue.h" +#include "base/memory/ptr_util.h" + namespace cc { namespace { @@ -13,8 +15,9 @@ class EvictionOrderComparator { explicit EvictionOrderComparator(TreePriority tree_priority) : tree_priority_(tree_priority) {} - bool operator()(const scoped_ptr<TilingSetEvictionQueue>& a_queue, - const scoped_ptr<TilingSetEvictionQueue>& b_queue) const { + bool operator()( + const std::unique_ptr<TilingSetEvictionQueue>& a_queue, + const std::unique_ptr<TilingSetEvictionQueue>& b_queue) const { // Note that in this function, we have to return true if and only if // b is strictly lower priority than a. const PrioritizedTile& a_tile = a_queue->Top(); @@ -64,11 +67,11 @@ class EvictionOrderComparator { void CreateTilingSetEvictionQueues( const std::vector<PictureLayerImpl*>& layers, TreePriority tree_priority, - std::vector<scoped_ptr<TilingSetEvictionQueue>>* queues) { + std::vector<std::unique_ptr<TilingSetEvictionQueue>>* queues) { DCHECK(queues->empty()); for (auto* layer : layers) { - scoped_ptr<TilingSetEvictionQueue> tiling_set_queue = make_scoped_ptr( + std::unique_ptr<TilingSetEvictionQueue> tiling_set_queue = base::WrapUnique( new TilingSetEvictionQueue(layer->picture_layer_tiling_set())); // Queues will only contain non empty tiling sets. if (!tiling_set_queue->IsEmpty()) @@ -125,16 +128,16 @@ void EvictionTilePriorityQueue::Pop() { } } -std::vector<scoped_ptr<TilingSetEvictionQueue>>& +std::vector<std::unique_ptr<TilingSetEvictionQueue>>& EvictionTilePriorityQueue::GetNextQueues() { const EvictionTilePriorityQueue* const_this = static_cast<const EvictionTilePriorityQueue*>(this); const auto& const_queues = const_this->GetNextQueues(); - return const_cast<std::vector<scoped_ptr<TilingSetEvictionQueue>>&>( + return const_cast<std::vector<std::unique_ptr<TilingSetEvictionQueue>>&>( const_queues); } -const std::vector<scoped_ptr<TilingSetEvictionQueue>>& +const std::vector<std::unique_ptr<TilingSetEvictionQueue>>& EvictionTilePriorityQueue::GetNextQueues() const { DCHECK(!IsEmpty()); diff --git a/chromium/cc/tiles/eviction_tile_priority_queue.h b/chromium/cc/tiles/eviction_tile_priority_queue.h index 558c1fe939b..d97bee6a238 100644 --- a/chromium/cc/tiles/eviction_tile_priority_queue.h +++ b/chromium/cc/tiles/eviction_tile_priority_queue.h @@ -32,11 +32,12 @@ class CC_EXPORT EvictionTilePriorityQueue { void Pop(); private: - std::vector<scoped_ptr<TilingSetEvictionQueue>>& GetNextQueues(); - const std::vector<scoped_ptr<TilingSetEvictionQueue>>& GetNextQueues() const; + std::vector<std::unique_ptr<TilingSetEvictionQueue>>& GetNextQueues(); + const std::vector<std::unique_ptr<TilingSetEvictionQueue>>& GetNextQueues() + const; - std::vector<scoped_ptr<TilingSetEvictionQueue>> active_queues_; - std::vector<scoped_ptr<TilingSetEvictionQueue>> pending_queues_; + std::vector<std::unique_ptr<TilingSetEvictionQueue>> active_queues_; + std::vector<std::unique_ptr<TilingSetEvictionQueue>> pending_queues_; TreePriority tree_priority_; DISALLOW_COPY_AND_ASSIGN(EvictionTilePriorityQueue); diff --git a/chromium/cc/tiles/gpu_image_decode_controller.cc b/chromium/cc/tiles/gpu_image_decode_controller.cc index da9bd207010..69f8b56454a 100644 --- a/chromium/cc/tiles/gpu_image_decode_controller.cc +++ b/chromium/cc/tiles/gpu_image_decode_controller.cc @@ -4,35 +4,82 @@ #include "cc/tiles/gpu_image_decode_controller.h" +#include "base/memory/discardable_memory_allocator.h" +#include "base/memory/ptr_util.h" +#include "base/numerics/safe_math.h" +#include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/debug/devtools_instrumentation.h" -#include "cc/raster/tile_task_runner.h" -#include "skia/ext/refptr.h" +#include "cc/output/context_provider.h" +#include "cc/raster/tile_task.h" +#include "gpu/command_buffer/client/context_support.h" +#include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu_image_decode_controller.h" +#include "skia/ext/texture_handle.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/gpu/GrContext.h" +#include "third_party/skia/include/gpu/GrTexture.h" +#include "ui/gfx/skia_util.h" +#include "ui/gl/trace_util.h" namespace cc { +namespace { -class ImageDecodeTaskImpl : public ImageDecodeTask { +static const int kMaxGpuImageBytes = 1024 * 1024 * 96; +static const int kMaxDiscardableItems = 2000; + +// Returns true if an image would not be drawn and should therefore be +// skipped rather than decoded. +bool SkipImage(const DrawImage& draw_image) { + if (!SkIRect::Intersects(draw_image.src_rect(), draw_image.image()->bounds())) + return true; + if (std::abs(draw_image.scale().width()) < + std::numeric_limits<float>::epsilon() || + std::abs(draw_image.scale().height()) < + std::numeric_limits<float>::epsilon()) { + return true; + } + return false; +} + +SkImage::DeferredTextureImageUsageParams ParamsFromDrawImage( + const DrawImage& draw_image) { + SkImage::DeferredTextureImageUsageParams params; + params.fMatrix = draw_image.matrix(); + params.fQuality = draw_image.filter_quality(); + + return params; +} + +} // namespace + +// Task which decodes an image and stores the result in discardable memory. +// This task does not use GPU resources and can be run on any thread. +class ImageDecodeTaskImpl : public TileTask { public: ImageDecodeTaskImpl(GpuImageDecodeController* controller, - const DrawImage& image, - uint64_t source_prepare_tiles_id) - : controller_(controller), - image_(image), - image_ref_(skia::SharePtr(image.image())), - source_prepare_tiles_id_(source_prepare_tiles_id) {} + const DrawImage& draw_image, + const ImageDecodeController::TracingInfo& tracing_info) + : TileTask(true), + controller_(controller), + image_(draw_image), + tracing_info_(tracing_info) { + DCHECK(!SkipImage(draw_image)); + } // Overridden from Task: void RunOnWorkerThread() override { TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu", - "source_prepare_tiles_id", source_prepare_tiles_id_); - devtools_instrumentation::ScopedImageDecodeTask image_decode_task( - image_ref_.get()); + "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); controller_->DecodeImage(image_); } // Overridden from TileTask: - void ScheduleOnOriginThread(TileTaskClient* client) override {} - void CompleteOnOriginThread(TileTaskClient* client) override { - controller_->RemovePendingTaskForImage(image_); + void ScheduleOnOriginThread(RasterBufferProvider* provider) override {} + void CompleteOnOriginThread(RasterBufferProvider* provider) override { + controller_->DecodeTaskCompleted(image_); } protected: @@ -41,62 +88,779 @@ class ImageDecodeTaskImpl : public ImageDecodeTask { private: GpuImageDecodeController* controller_; DrawImage image_; - skia::RefPtr<const SkImage> image_ref_; - uint64_t source_prepare_tiles_id_; + const ImageDecodeController::TracingInfo tracing_info_; DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); }; -GpuImageDecodeController::GpuImageDecodeController() {} +// Task which creates an image from decoded data. Typically this involves +// uploading data to the GPU, which requires this task be run on the non- +// concurrent thread. +class ImageUploadTaskImpl : public TileTask { + public: + ImageUploadTaskImpl(GpuImageDecodeController* controller, + const DrawImage& draw_image, + scoped_refptr<TileTask> decode_dependency, + const ImageDecodeController::TracingInfo& tracing_info) + : TileTask(false), + controller_(controller), + image_(draw_image), + tracing_info_(tracing_info) { + DCHECK(!SkipImage(draw_image)); + // If an image is already decoded and locked, we will not generate a + // decode task. + if (decode_dependency) + dependencies_.push_back(std::move(decode_dependency)); + } + + // Override from Task: + void RunOnWorkerThread() override { + TRACE_EVENT2("cc", "ImageUploadTaskImpl::RunOnWorkerThread", "mode", "gpu", + "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); + controller_->UploadImage(image_); + } + + void ScheduleOnOriginThread(RasterBufferProvider* provider) override {} + void CompleteOnOriginThread(RasterBufferProvider* provider) override { + controller_->UploadTaskCompleted(image_); + } + + protected: + ~ImageUploadTaskImpl() override {} + + private: + GpuImageDecodeController* controller_; + DrawImage image_; + const ImageDecodeController::TracingInfo tracing_info_; + + DISALLOW_COPY_AND_ASSIGN(ImageUploadTaskImpl); +}; + +GpuImageDecodeController::DecodedImageData::DecodedImageData() + : ref_count(0), is_locked(false), decode_failure(false) {} + +GpuImageDecodeController::DecodedImageData::~DecodedImageData() = default; + +GpuImageDecodeController::UploadedImageData::UploadedImageData() + : budgeted(false), ref_count(0) {} -GpuImageDecodeController::~GpuImageDecodeController() {} +GpuImageDecodeController::UploadedImageData::~UploadedImageData() = default; + +GpuImageDecodeController::ImageData::ImageData(DecodedDataMode mode, + size_t size) + : mode(mode), size(size), is_at_raster(false) {} + +GpuImageDecodeController::ImageData::~ImageData() = default; + +GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, + ResourceFormat decode_format) + : format_(decode_format), + context_(context), + image_data_(ImageDataMRUCache::NO_AUTO_EVICT), + cached_items_limit_(kMaxDiscardableItems), + cached_bytes_limit_(kMaxGpuImageBytes), + bytes_used_(0) { + // Acquire the context_lock so that we can safely retrieve the + // GrContextThreadSafeProxy. This proxy can then be used with no lock held. + { + ContextProvider::ScopedContextLock context_lock(context_); + context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>( + context->GrContext()->threadSafeProxy()); + } + + // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). + // Don't register a dump provider in these cases. + if (base::ThreadTaskRunnerHandle::IsSet()) { + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + this, "cc::GpuImageDecodeController", + base::ThreadTaskRunnerHandle::Get()); + } +} + +GpuImageDecodeController::~GpuImageDecodeController() { + // SetShouldAggressivelyFreeResources will zero our limits and free all + // outstanding image memory. + SetShouldAggressivelyFreeResources(true); + + // It is safe to unregister, even if we didn't register in the constructor. + base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( + this); +} bool GpuImageDecodeController::GetTaskForImageAndRef( - const DrawImage& image, - uint64_t prepare_tiles_id, - scoped_refptr<ImageDecodeTask>* task) { - auto image_id = image.image()->uniqueID(); - base::AutoLock lock(lock_); - if (prerolled_images_.count(image_id) != 0) { + const DrawImage& draw_image, + const TracingInfo& tracing_info, + scoped_refptr<TileTask>* task) { + if (SkipImage(draw_image)) { *task = nullptr; return false; } - scoped_refptr<ImageDecodeTask>& existing_task = - pending_image_tasks_[image_id]; - if (!existing_task) { - existing_task = make_scoped_refptr( - new ImageDecodeTaskImpl(this, image, prepare_tiles_id)); + base::AutoLock lock(lock_); + const auto image_id = draw_image.image()->uniqueID(); + + auto found = image_data_.Get(image_id); + if (found != image_data_.end()) { + ImageData* image_data = found->second.get(); + if (image_data->is_at_raster) { + // Image is at-raster, just return, this usage will be at-raster as well. + *task = nullptr; + return false; + } + + if (image_data->decode.decode_failure) { + // We have already tried and failed to decode this image, so just return. + *task = nullptr; + return false; + } + + if (image_data->upload.image) { + // The image is already uploaded, ref and return. + RefImage(draw_image); + *task = nullptr; + return true; + } + } + + // We didn't have a pre-uploaded image, so we need an upload task. Try to find + // an existing one. + scoped_refptr<TileTask>& existing_task = + pending_image_upload_tasks_[image_id]; + if (existing_task) { + // We had an existing upload task, ref the image and return the task. + RefImage(draw_image); + *task = existing_task; + return true; + } + + // We will be creating a new upload task. If necessary, create a placeholder + // ImageData to hold the result. + std::unique_ptr<ImageData> new_data; + ImageData* data; + if (found == image_data_.end()) { + new_data = CreateImageData(draw_image); + data = new_data.get(); + } else { + data = found->second.get(); } + + // Ensure that the image we're about to decode/upload will fit in memory. + if (!EnsureCapacity(data->size)) { + // Image will not fit, do an at-raster decode. + *task = nullptr; + return false; + } + + // If we had to create new image data, add it to our map now that we know it + // will fit. + if (new_data) + found = image_data_.Put(image_id, std::move(new_data)); + + // Ref image and create a upload and decode tasks. We will release this ref + // in UploadTaskCompleted. + RefImage(draw_image); + existing_task = make_scoped_refptr(new ImageUploadTaskImpl( + this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info), + tracing_info)); + + // Ref the image again - this ref is owned by the caller, and it is their + // responsibility to release it by calling UnrefImage. + RefImage(draw_image); *task = existing_task; - return false; + return true; } -void GpuImageDecodeController::UnrefImage(const DrawImage& image) { - NOTREACHED(); +void GpuImageDecodeController::UnrefImage(const DrawImage& draw_image) { + base::AutoLock lock(lock_); + UnrefImageInternal(draw_image); } DecodedDrawImage GpuImageDecodeController::GetDecodedImageForDraw( const DrawImage& draw_image) { - return DecodedDrawImage(draw_image.image(), draw_image.filter_quality()); + // We are being called during raster. The context lock must already be + // acquired by the caller. + context_->GetLock()->AssertAcquired(); + + if (SkipImage(draw_image)) + return DecodedDrawImage(nullptr, draw_image.filter_quality()); + + TRACE_EVENT0("cc", "GpuImageDecodeController::GetDecodedImageForDraw"); + + base::AutoLock lock(lock_); + const uint32_t unique_id = draw_image.image()->uniqueID(); + auto found = image_data_.Peek(unique_id); + if (found == image_data_.end()) { + // We didn't find the image, create a new entry. + auto data = CreateImageData(draw_image); + found = image_data_.Put(unique_id, std::move(data)); + } + + ImageData* image_data = found->second.get(); + + if (!image_data->upload.budgeted) { + // If image data is not budgeted by this point, it is at-raster. + image_data->is_at_raster = true; + } + + // Ref the image and decode so that they stay alive while we are + // decoding/uploading. + RefImage(draw_image); + RefImageDecode(draw_image); + + // We may or may not need to decode and upload the image we've found, the + // following functions early-out to if we already decoded. + DecodeImageIfNecessary(draw_image, image_data); + UploadImageIfNecessary(draw_image, image_data); + // Unref the image decode, but not the image. The image ref will be released + // in DrawWithImageFinished. + UnrefImageDecode(draw_image); + + sk_sp<SkImage> image = image_data->upload.image; + DCHECK(image || image_data->decode.decode_failure); + + DecodedDrawImage decoded_draw_image(std::move(image), + draw_image.filter_quality()); + decoded_draw_image.set_at_raster_decode(image_data->is_at_raster); + return decoded_draw_image; } void GpuImageDecodeController::DrawWithImageFinished( - const DrawImage& image, - const DecodedDrawImage& decoded_image) {} + const DrawImage& draw_image, + const DecodedDrawImage& decoded_draw_image) { + // We are being called during raster. The context lock must already be + // acquired by the caller. + context_->GetLock()->AssertAcquired(); + + if (SkipImage(draw_image)) + return; + + base::AutoLock lock(lock_); + UnrefImageInternal(draw_image); + + // We are mid-draw and holding the context lock, ensure we clean up any + // textures (especially at-raster), which may have just been marked for + // deletion by UnrefImage. + DeletePendingImages(); +} + +void GpuImageDecodeController::ReduceCacheUsage() { + base::AutoLock lock(lock_); + EnsureCapacity(0); +} + +void GpuImageDecodeController::SetShouldAggressivelyFreeResources( + bool aggressively_free_resources) { + if (aggressively_free_resources) { + ContextProvider::ScopedContextLock context_lock(context_); + base::AutoLock lock(lock_); + // We want to keep as little in our cache as possible. Set our memory limit + // to zero and EnsureCapacity to clean up memory. + cached_bytes_limit_ = 0; + EnsureCapacity(0); + + // We are holding the context lock, so finish cleaning up deleted images + // now. + DeletePendingImages(); + } else { + base::AutoLock lock(lock_); + cached_bytes_limit_ = kMaxGpuImageBytes; + } +} + +bool GpuImageDecodeController::OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + for (const auto& image_pair : image_data_) { + const ImageData* image_data = image_pair.second.get(); + const uint32_t image_id = image_pair.first; + + // If we have discardable decoded data, dump this here. + if (image_data->decode.data) { + std::string discardable_dump_name = base::StringPrintf( + "cc/image_memory/controller_%p/discardable/image_%d", this, image_id); + base::trace_event::MemoryAllocatorDump* dump = + image_data->decode.data->CreateMemoryAllocatorDump( + discardable_dump_name.c_str(), pmd); + + // If our image is locked, dump the "locked_size" as an additional column. + // This lets us see the amount of discardable which is contributing to + // memory pressure. + if (image_data->decode.is_locked) { + dump->AddScalar("locked_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + image_data->size); + } + } + + // If we have an uploaded image (that is actually on the GPU, not just a CPU + // wrapper), upload it here. + if (image_data->upload.image && image_data->mode == DecodedDataMode::GPU) { + std::string gpu_dump_name = base::StringPrintf( + "cc/image_memory/controller_%p/gpu/image_%d", this, image_id); + base::trace_event::MemoryAllocatorDump* dump = + pmd->CreateAllocatorDump(gpu_dump_name); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + image_data->size); + + // Create a global shred GUID to associate this data with its GPU process + // counterpart. + GLuint gl_id = skia::GrBackendObjectToGrGLTextureInfo( + image_data->upload.image->getTextureHandle( + false /* flushPendingGrContextIO */)) + ->fID; + base::trace_event::MemoryAllocatorDumpGuid guid = + gfx::GetGLTextureClientGUIDForTracing( + context_->ContextSupport()->ShareGroupTracingGUID(), gl_id); + + // kImportance is somewhat arbitrary - we chose 3 to be higher than the + // value used in the GPU process (1), and Skia (2), causing us to appear + // as the owner in memory traces. + const int kImportance = 3; + pmd->CreateSharedGlobalAllocatorDump(guid); + pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); + } + } + + return true; +} + +void GpuImageDecodeController::DecodeImage(const DrawImage& draw_image) { + base::AutoLock lock(lock_); + auto found = image_data_.Peek(draw_image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + DCHECK(!found->second->is_at_raster); + DecodeImageIfNecessary(draw_image, found->second.get()); +} + +void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) { + ContextProvider::ScopedContextLock context_lock(context_); + base::AutoLock lock(lock_); + auto found = image_data_.Peek(draw_image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + DCHECK(!found->second->is_at_raster); + UploadImageIfNecessary(draw_image, found->second.get()); +} + +void GpuImageDecodeController::DecodeTaskCompleted( + const DrawImage& draw_image) { + base::AutoLock lock(lock_); + // Decode task is complete, remove it from our list of pending tasks. + pending_image_decode_tasks_.erase(draw_image.image()->uniqueID()); + + // While the decode task is active, we keep a ref on the decoded data. + // Release that ref now. + UnrefImageDecode(draw_image); +} + +void GpuImageDecodeController::UploadTaskCompleted( + const DrawImage& draw_image) { + base::AutoLock lock(lock_); + // Upload task is complete, remove it from our list of pending tasks. + pending_image_upload_tasks_.erase(draw_image.image()->uniqueID()); + + // While the upload task is active, we keep a ref on both the image it will be + // populating, as well as the decode it needs to populate it. Release these + // refs now. + UnrefImageDecode(draw_image); + UnrefImageInternal(draw_image); +} + +// Checks if an existing image decode exists. If not, returns a task to produce +// the requested decode. +scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef( + const DrawImage& draw_image, + const TracingInfo& tracing_info) { + lock_.AssertAcquired(); + + const uint32_t image_id = draw_image.image()->uniqueID(); + + // This ref is kept alive while an upload task may need this decode. We + // release this ref in UploadTaskCompleted. + RefImageDecode(draw_image); + + auto found = image_data_.Peek(image_id); + if (found != image_data_.end() && found->second->decode.is_locked) { + // We should never be creating a decode task for an at raster image. + DCHECK(!found->second->is_at_raster); + // We should never be creating a decode for an already-uploaded image. + DCHECK(!found->second->upload.image); + return nullptr; + } + + // We didn't have an existing locked image, create a task to lock or decode. + scoped_refptr<TileTask>& existing_task = + pending_image_decode_tasks_[image_id]; + if (!existing_task) { + // Ref image decode and create a decode task. This ref will be released in + // DecodeTaskCompleted. + RefImageDecode(draw_image); + existing_task = make_scoped_refptr( + new ImageDecodeTaskImpl(this, draw_image, tracing_info)); + } + return existing_task; +} + +void GpuImageDecodeController::RefImageDecode(const DrawImage& draw_image) { + lock_.AssertAcquired(); + auto found = image_data_.Peek(draw_image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + ++found->second->decode.ref_count; + RefCountChanged(found->second.get()); +} + +void GpuImageDecodeController::UnrefImageDecode(const DrawImage& draw_image) { + lock_.AssertAcquired(); + auto found = image_data_.Peek(draw_image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + DCHECK_GT(found->second->decode.ref_count, 0u); + --found->second->decode.ref_count; + RefCountChanged(found->second.get()); +} + +void GpuImageDecodeController::RefImage(const DrawImage& draw_image) { + lock_.AssertAcquired(); + auto found = image_data_.Peek(draw_image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + ++found->second->upload.ref_count; + RefCountChanged(found->second.get()); +} + +void GpuImageDecodeController::UnrefImageInternal(const DrawImage& draw_image) { + lock_.AssertAcquired(); + auto found = image_data_.Peek(draw_image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + DCHECK_GT(found->second->upload.ref_count, 0u); + --found->second->upload.ref_count; + RefCountChanged(found->second.get()); +} + +// Called any time an image or decode ref count changes. Takes care of any +// necessary memory budget book-keeping and cleanup. +void GpuImageDecodeController::RefCountChanged(ImageData* image_data) { + lock_.AssertAcquired(); + + bool has_any_refs = + image_data->upload.ref_count > 0 || image_data->decode.ref_count > 0; + + // Don't keep CPU images if they are unused, these images can be recreated by + // re-locking discardable (rather than requiring a full upload like GPU + // images). + if (image_data->mode == DecodedDataMode::CPU && !has_any_refs) { + images_pending_deletion_.push_back(std::move(image_data->upload.image)); + image_data->upload.image = nullptr; + } + + if (image_data->is_at_raster && !has_any_refs) { + // We have an at-raster image which has reached zero refs. If it won't fit + // in our cache, delete the image to allow it to fit. + if (image_data->upload.image && !CanFitSize(image_data->size)) { + images_pending_deletion_.push_back(std::move(image_data->upload.image)); + image_data->upload.image = nullptr; + } + + // We now have an at-raster image which will fit in our cache. Convert it + // to not-at-raster. + image_data->is_at_raster = false; + if (image_data->upload.image) { + bytes_used_ += image_data->size; + image_data->upload.budgeted = true; + } + } + + // If we have image refs on a non-at-raster image, it must be budgeted, as it + // is either uploaded or pending upload. + if (image_data->upload.ref_count > 0 && !image_data->upload.budgeted && + !image_data->is_at_raster) { + // We should only be taking non-at-raster refs on images that fit in cache. + DCHECK(CanFitSize(image_data->size)); + + bytes_used_ += image_data->size; + image_data->upload.budgeted = true; + } + + // If we have no image refs on an image, it should only be budgeted if it has + // an uploaded image. If no image exists (upload was cancelled), we should + // un-budget the image. + if (image_data->upload.ref_count == 0 && image_data->upload.budgeted && + !image_data->upload.image) { + DCHECK_GE(bytes_used_, image_data->size); + bytes_used_ -= image_data->size; + image_data->upload.budgeted = false; + } + + // We should unlock the discardable memory for the image in two cases: + // 1) The image is no longer being used (no decode or upload refs). + // 2) This is a GPU backed image that has already been uploaded (no decode + // refs). + bool should_unlock_discardable = + !has_any_refs || (image_data->mode == DecodedDataMode::GPU && + !image_data->decode.ref_count); + + if (should_unlock_discardable && image_data->decode.is_locked) { + DCHECK(image_data->decode.data); + image_data->decode.data->Unlock(); + image_data->decode.is_locked = false; + } + + // Sanity check the above logic. + if (image_data->upload.image) { + DCHECK(image_data->is_at_raster || image_data->upload.budgeted); + if (image_data->mode == DecodedDataMode::CPU) + DCHECK(image_data->decode.is_locked); + } else { + DCHECK(!image_data->upload.budgeted || image_data->upload.ref_count > 0); + } +} + +// Ensures that we can fit a new image of size |required_size| in our cache. In +// doing so, this function will free unreferenced image data as necessary to +// create rooom. +bool GpuImageDecodeController::EnsureCapacity(size_t required_size) { + lock_.AssertAcquired(); + + if (CanFitSize(required_size) && !ExceedsPreferredCount()) + return true; + + // While we are over memory or preferred item capacity, we iterate through + // our set of cached image data in LRU order. For each image, we can do two + // things: 1) We can free the uploaded image, reducing the memory usage of + // the cache and 2) we can remove the entry entirely, reducing the count of + // elements in the cache. + for (auto it = image_data_.rbegin(); it != image_data_.rend();) { + if (it->second->decode.ref_count != 0 || + it->second->upload.ref_count != 0) { + ++it; + continue; + } + + // Current entry has no refs. Ensure it is not locked. + DCHECK(!it->second->decode.is_locked); + + // If an image without refs is budgeted, it must have an associated image + // upload. + DCHECK(!it->second->upload.budgeted || it->second->upload.image); + + // Free the uploaded image if possible. + if (it->second->upload.image) { + DCHECK(it->second->upload.budgeted); + DCHECK_GE(bytes_used_, it->second->size); + bytes_used_ -= it->second->size; + images_pending_deletion_.push_back(std::move(it->second->upload.image)); + it->second->upload.image = nullptr; + it->second->upload.budgeted = false; + } -void GpuImageDecodeController::ReduceCacheUsage() {} + // Free the entire entry if necessary. + if (ExceedsPreferredCount()) { + it = image_data_.Erase(it); + } else { + ++it; + } -void GpuImageDecodeController::DecodeImage(const DrawImage& image) { - image.image()->preroll(); + if (CanFitSize(required_size) && !ExceedsPreferredCount()) + return true; + } + + // Preferred count is only used as a guideline when triming the cache. Allow + // new elements to be added as long as we are below our size limit. + return CanFitSize(required_size); +} + +bool GpuImageDecodeController::CanFitSize(size_t size) const { + lock_.AssertAcquired(); + + base::CheckedNumeric<uint32_t> new_size(bytes_used_); + new_size += size; + return new_size.IsValid() && new_size.ValueOrDie() <= cached_bytes_limit_; +} + +bool GpuImageDecodeController::ExceedsPreferredCount() const { + lock_.AssertAcquired(); + + return image_data_.size() > cached_items_limit_; +} + +void GpuImageDecodeController::DecodeImageIfNecessary( + const DrawImage& draw_image, + ImageData* image_data) { + lock_.AssertAcquired(); + + DCHECK_GT(image_data->decode.ref_count, 0u); + + if (image_data->decode.decode_failure) { + // We have already tried and failed to decode this image. Don't try again. + return; + } + + if (image_data->upload.image) { + // We already have an uploaded image, no reason to decode. + return; + } + + if (image_data->decode.data && + (image_data->decode.is_locked || image_data->decode.data->Lock())) { + // We already decoded this, or we just needed to lock, early out. + image_data->decode.is_locked = true; + return; + } + + TRACE_EVENT0("cc", "GpuImageDecodeController::DecodeImage"); + + image_data->decode.data = nullptr; + std::unique_ptr<base::DiscardableMemory> backing_memory; + { + base::AutoUnlock unlock(lock_); + switch (image_data->mode) { + case DecodedDataMode::CPU: { + backing_memory = + base::DiscardableMemoryAllocator::GetInstance() + ->AllocateLockedDiscardableMemory(image_data->size); + SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image); + if (!draw_image.image()->readPixels(image_info, backing_memory->data(), + image_info.minRowBytes(), 0, 0, + SkImage::kDisallow_CachingHint)) { + backing_memory.reset(); + } + break; + } + case DecodedDataMode::GPU: { + backing_memory = + base::DiscardableMemoryAllocator::GetInstance() + ->AllocateLockedDiscardableMemory(image_data->size); + auto params = ParamsFromDrawImage(draw_image); + if (!draw_image.image()->getDeferredTextureImageData( + *context_threadsafe_proxy_.get(), ¶ms, 1, + backing_memory->data())) { + backing_memory.reset(); + } + break; + } + } + } + + if (image_data->decode.data) { + // An at-raster task decoded this before us. Ingore our decode. + return; + } + + if (!backing_memory) { + // If |backing_memory| was not populated, we had a non-decodable image. + image_data->decode.decode_failure = true; + return; + } + + image_data->decode.data = std::move(backing_memory); + DCHECK(!image_data->decode.is_locked); + image_data->decode.is_locked = true; +} + +void GpuImageDecodeController::UploadImageIfNecessary( + const DrawImage& draw_image, + ImageData* image_data) { + context_->GetLock()->AssertAcquired(); + lock_.AssertAcquired(); + + if (image_data->decode.decode_failure) { + // We were unnable to decode this image. Don't try to upload. + return; + } + + if (image_data->upload.image) { + // Someone has uploaded this image before us (at raster). + return; + } + + TRACE_EVENT0("cc", "GpuImageDecodeController::UploadImage"); + DCHECK(image_data->decode.is_locked); + DCHECK_GT(image_data->decode.ref_count, 0u); + DCHECK_GT(image_data->upload.ref_count, 0u); + + // We are about to upload a new image and are holding the context lock. + // Ensure that any images which have been marked for deletion are actually + // cleaned up so we don't exceed our memory limit during this upload. + DeletePendingImages(); + + sk_sp<SkImage> uploaded_image; + { + base::AutoUnlock unlock(lock_); + switch (image_data->mode) { + case DecodedDataMode::CPU: { + SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image); + SkPixmap pixmap(image_info, image_data->decode.data->data(), + image_info.minRowBytes()); + uploaded_image = + SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr); + break; + } + case DecodedDataMode::GPU: { + uploaded_image = SkImage::MakeFromDeferredTextureImageData( + context_->GrContext(), image_data->decode.data->data(), + SkBudgeted::kNo); + break; + } + } + } + DCHECK(uploaded_image); + + // At-raster may have decoded this while we were unlocked. If so, ignore our + // result. + if (!image_data->upload.image) { + image_data->upload.image = std::move(uploaded_image); + } +} + +std::unique_ptr<GpuImageDecodeController::ImageData> +GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) { + lock_.AssertAcquired(); + + DecodedDataMode mode; + SkImageInfo info = CreateImageInfoForDrawImage(draw_image); + SkImage::DeferredTextureImageUsageParams params = + ParamsFromDrawImage(draw_image); + size_t data_size = draw_image.image()->getDeferredTextureImageData( + *context_threadsafe_proxy_.get(), ¶ms, 1, nullptr); + + if (data_size == 0) { + // Can't upload image, too large or other failure. Try to use SW fallback. + data_size = info.getSafeSize(info.minRowBytes()); + mode = DecodedDataMode::CPU; + } else { + mode = DecodedDataMode::GPU; + } + + return base::WrapUnique(new ImageData(mode, data_size)); +} + +void GpuImageDecodeController::DeletePendingImages() { + context_->GetLock()->AssertAcquired(); + lock_.AssertAcquired(); + images_pending_deletion_.clear(); +} + +SkImageInfo GpuImageDecodeController::CreateImageInfoForDrawImage( + const DrawImage& draw_image) const { + return SkImageInfo::Make( + draw_image.image()->width(), draw_image.image()->height(), + ResourceFormatToClosestSkColorType(format_), kPremul_SkAlphaType); +} + +void GpuImageDecodeController::SetImageDecodingFailedForTesting( + const DrawImage& image) { base::AutoLock lock(lock_); - prerolled_images_.insert(image.image()->uniqueID()); + auto found = image_data_.Peek(image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + ImageData* image_data = found->second.get(); + image_data->decode.decode_failure = true; } -void GpuImageDecodeController::RemovePendingTaskForImage( +bool GpuImageDecodeController::DiscardableIsLockedForTesting( const DrawImage& image) { base::AutoLock lock(lock_); - pending_image_tasks_.erase(image.image()->uniqueID()); + auto found = image_data_.Peek(image.image()->uniqueID()); + DCHECK(found != image_data_.end()); + ImageData* image_data = found->second.get(); + return image_data->decode.is_locked; } } // namespace cc diff --git a/chromium/cc/tiles/gpu_image_decode_controller.h b/chromium/cc/tiles/gpu_image_decode_controller.h index 390ef8ed972..26e8bd1b58e 100644 --- a/chromium/cc/tiles/gpu_image_decode_controller.h +++ b/chromium/cc/tiles/gpu_image_decode_controller.h @@ -5,40 +5,194 @@ #ifndef CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ #define CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ +#include <memory> #include <unordered_map> -#include <unordered_set> +#include <vector> +#include "base/containers/mru_cache.h" +#include "base/memory/discardable_memory.h" #include "base/synchronization/lock.h" +#include "base/trace_event/memory_dump_provider.h" #include "cc/base/cc_export.h" +#include "cc/resources/resource_format.h" #include "cc/tiles/image_decode_controller.h" +#include "third_party/skia/include/core/SkRefCnt.h" + +class SkImageTextureData; namespace cc { -class CC_EXPORT GpuImageDecodeController : public ImageDecodeController { +class ContextProvider; + +// GpuImageDecodeController handles the decode and upload of images that will +// be used by Skia's GPU raster path. It also maintains a cache of these +// decoded/uploaded images for later re-use. +// +// Generally, when an image is required for raster, GpuImageDecodeController +// creates two tasks, one to decode the image, and one to upload the image to +// the GPU. These tasks are completed before the raster task which depends on +// the image. We need to seperate decode and upload tasks, as decode can occur +// simultaneously on multiple threads, while upload requires the GL context +// lock must happen on our non-concurrent raster thread. +// +// Decoded and Uploaded image data share a single cache entry. Depending on how +// far we've progressed, this cache entry may contain CPU-side decoded data, +// GPU-side uploaded data, or both. Because CPU-side decoded data is stored in +// discardable memory, and is only locked for short periods of time (until the +// upload completes), this memory is not counted against our sized cache +// limits. Uploaded GPU memory, being non-discardable, always counts against +// our limits. +// +// In cases where the number of images needed exceeds our cache limits, we +// operate in an "at-raster" mode. In this mode, there are no decode/upload +// tasks, and images are decoded/uploaded as needed, immediately before being +// used in raster. Cache entries for at-raster tasks are marked as such, which +// prevents future tasks from taking a dependency on them and extending their +// lifetime longer than is necessary. +class CC_EXPORT GpuImageDecodeController + : public ImageDecodeController, + public base::trace_event::MemoryDumpProvider { public: - GpuImageDecodeController(); + explicit GpuImageDecodeController(ContextProvider* context, + ResourceFormat decode_format); ~GpuImageDecodeController() override; // ImageDecodeController overrides. + + // Finds the existing uploaded image for the provided DrawImage. Creates an + // upload task to upload the image if an exsiting image does not exist. bool GetTaskForImageAndRef(const DrawImage& image, - uint64_t prepare_tiles_id, - scoped_refptr<ImageDecodeTask>* task) override; + const TracingInfo& tracing_info, + scoped_refptr<TileTask>* task) override; void UnrefImage(const DrawImage& image) override; DecodedDrawImage GetDecodedImageForDraw(const DrawImage& draw_image) override; void DrawWithImageFinished(const DrawImage& image, const DecodedDrawImage& decoded_image) override; void ReduceCacheUsage() override; + void SetShouldAggressivelyFreeResources( + bool aggressively_free_resources) override; + + // MemoryDumpProvider overrides. + bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) override; + // Called by Decode / Upload tasks. void DecodeImage(const DrawImage& image); + void UploadImage(const DrawImage& image); + void DecodeTaskCompleted(const DrawImage& image); + void UploadTaskCompleted(const DrawImage& image); - void RemovePendingTaskForImage(const DrawImage& image); + // For testing only. + void SetCachedItemLimitForTesting(size_t limit) { + cached_items_limit_ = limit; + } + void SetCachedBytesLimitForTesting(size_t limit) { + cached_bytes_limit_ = limit; + } + size_t GetBytesUsedForTesting() const { return bytes_used_; } + void SetImageDecodingFailedForTesting(const DrawImage& image); + bool DiscardableIsLockedForTesting(const DrawImage& image); private: + enum class DecodedDataMode { GPU, CPU }; + + // Stores the CPU-side decoded bits of an image and supporting fields. + struct DecodedImageData { + DecodedImageData(); + ~DecodedImageData(); + + // May be null if image not yet decoded. + std::unique_ptr<base::DiscardableMemory> data; + uint32_t ref_count; + bool is_locked; + + // Set to true if the image was corrupt and could not be decoded. + bool decode_failure; + }; + + // Stores the GPU-side image and supporting fields. + struct UploadedImageData { + UploadedImageData(); + ~UploadedImageData(); + + // May be null if image not yet uploaded / prepared. + sk_sp<SkImage> image; + // True if the image is counting against our memory limits. + bool budgeted; + uint32_t ref_count; + }; + + struct ImageData { + ImageData(DecodedDataMode mode, size_t size); + ~ImageData(); + + const DecodedDataMode mode; + const size_t size; + bool is_at_raster; + + DecodedImageData decode; + UploadedImageData upload; + }; + + using ImageDataMRUCache = + base::MRUCache<uint32_t, std::unique_ptr<ImageData>>; + + // All private functions should only be called while holding |lock_|. Some + // functions also require the |context_| lock. These are indicated by + // additional comments. + + // Similar to GetTaskForImageAndRef, but gets the dependent decode task + // rather than the upload task, if necessary. + scoped_refptr<TileTask> GetImageDecodeTaskAndRef( + const DrawImage& image, + const TracingInfo& tracing_info); + + void RefImageDecode(const DrawImage& draw_image); + void UnrefImageDecode(const DrawImage& draw_image); + void RefImage(const DrawImage& draw_image); + void UnrefImageInternal(const DrawImage& draw_image); + void RefCountChanged(ImageData* image_data); + + // Ensures that the cache can hold an element of |required_size|, freeing + // unreferenced cache entries if necessary to make room. + bool EnsureCapacity(size_t required_size); + bool CanFitSize(size_t size) const; + bool ExceedsPreferredCount() const; + + void DecodeImageIfNecessary(const DrawImage& draw_image, + ImageData* image_data); + + std::unique_ptr<GpuImageDecodeController::ImageData> CreateImageData( + const DrawImage& image); + SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image) const; + + // The following two functions also require the |context_| lock to be held. + void UploadImageIfNecessary(const DrawImage& draw_image, + ImageData* image_data); + void DeletePendingImages(); + + const ResourceFormat format_; + ContextProvider* context_; + sk_sp<GrContextThreadSafeProxy> context_threadsafe_proxy_; + + // All members below this point must only be accessed while holding |lock_|. base::Lock lock_; - std::unordered_set<uint32_t> prerolled_images_; - std::unordered_map<uint32_t, scoped_refptr<ImageDecodeTask>> - pending_image_tasks_; + std::unordered_map<uint32_t, scoped_refptr<TileTask>> + pending_image_upload_tasks_; + std::unordered_map<uint32_t, scoped_refptr<TileTask>> + pending_image_decode_tasks_; + + ImageDataMRUCache image_data_; + + size_t cached_items_limit_; + size_t cached_bytes_limit_; + size_t bytes_used_; + + // We can't release GPU backed SkImages without holding the context lock, + // so we add them to this list and defer deletion until the next time the lock + // is held. + std::vector<sk_sp<SkImage>> images_pending_deletion_; }; } // namespace cc diff --git a/chromium/cc/tiles/gpu_image_decode_controller_unittest.cc b/chromium/cc/tiles/gpu_image_decode_controller_unittest.cc new file mode 100644 index 00000000000..1399c066c12 --- /dev/null +++ b/chromium/cc/tiles/gpu_image_decode_controller_unittest.cc @@ -0,0 +1,767 @@ +// Copyright 2016 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/gpu_image_decode_controller.h" + +#include "cc/playback/draw_image.h" +#include "cc/raster/tile_task.h" +#include "cc/test/test_context_provider.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkRefCnt.h" + +namespace cc { +namespace { + +sk_sp<SkImage> CreateImage(int width, int height) { + SkBitmap bitmap; + bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); + return SkImage::MakeFromBitmap(bitmap); +} + +SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) { + SkMatrix matrix; + matrix.setScale(scale.width(), scale.height()); + + if (!is_decomposable) { + // Perspective is not decomposable, add it. + matrix[SkMatrix::kMPersp0] = 0.1f; + } + + return matrix; +} + +void ScheduleTask(TileTask* task) { + task->WillSchedule(); + task->ScheduleOnOriginThread(nullptr); + task->DidSchedule(); +} + +void RunTask(TileTask* task) { + // TODO(prashant.n): Once ScheduleOnOriginThread() and + // CompleteOnOriginThread() functions are removed, modify this function + // accordingly. (crbug.com/599863) + task->state().DidSchedule(); + task->state().DidStart(); + task->RunOnWorkerThread(); + task->state().DidFinish(); +} + +void CompleteTask(TileTask* task) { + task->WillComplete(); + task->CompleteOnOriginThread(nullptr); + task->DidComplete(); +} + +void ProcessTask(TileTask* task) { + ScheduleTask(task); + RunTask(task); + CompleteTask(task); +} + +TEST(GpuImageDecodeControllerTest, GetTaskForImageSameImage) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + sk_sp<SkImage> image = CreateImage(100, 100); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + + DrawImage another_draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable)); + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + another_draw_image, ImageDecodeController::TracingInfo(), &another_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task.get() == another_task.get()); + + ProcessTask(task->dependencies()[0].get()); + ProcessTask(task.get()); + + controller.UnrefImage(draw_image); + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, GetTaskForImageDifferentImage) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> first_image = CreateImage(100, 100); + DrawImage first_draw_image( + first_image, SkIRect::MakeWH(first_image->width(), first_image->height()), + quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> first_task; + bool need_unref = controller.GetTaskForImageAndRef( + first_draw_image, ImageDecodeController::TracingInfo(), &first_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(first_task); + + sk_sp<SkImage> second_image = CreateImage(100, 100); + DrawImage second_draw_image( + second_image, + SkIRect::MakeWH(second_image->width(), second_image->height()), quality, + CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable)); + scoped_refptr<TileTask> second_task; + need_unref = controller.GetTaskForImageAndRef( + second_draw_image, ImageDecodeController::TracingInfo(), &second_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(second_task); + EXPECT_TRUE(first_task.get() != second_task.get()); + + ProcessTask(first_task->dependencies()[0].get()); + ProcessTask(first_task.get()); + ProcessTask(second_task->dependencies()[0].get()); + ProcessTask(second_task.get()); + + controller.UnrefImage(first_draw_image); + controller.UnrefImage(second_draw_image); +} + +TEST(GpuImageDecodeControllerTest, GetTaskForImageAlreadyDecodedAndLocked) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + EXPECT_EQ(task->dependencies().size(), 1u); + EXPECT_TRUE(task->dependencies()[0]); + + // Run the decode but don't complete it (this will keep the decode locked). + ScheduleTask(task->dependencies()[0].get()); + RunTask(task->dependencies()[0].get()); + + // Cancel the upload. + ScheduleTask(task.get()); + CompleteTask(task.get()); + + // Get the image again - we should have an upload task, but no dependent + // decode task, as the decode was already locked. + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(another_task); + EXPECT_EQ(another_task->dependencies().size(), 0u); + + ProcessTask(another_task.get()); + + // Finally, complete the original decode task. + CompleteTask(task->dependencies()[0].get()); + + controller.UnrefImage(draw_image); + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, GetTaskForImageAlreadyDecodedNotLocked) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + EXPECT_EQ(task->dependencies().size(), 1u); + EXPECT_TRUE(task->dependencies()[0]); + + // Run the decode. + ProcessTask(task->dependencies()[0].get()); + + // Cancel the upload. + ScheduleTask(task.get()); + CompleteTask(task.get()); + + // Unref the image. + controller.UnrefImage(draw_image); + + // Get the image again - we should have an upload task and a dependent decode + // task - this dependent task will typically just re-lock the image. + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(another_task); + EXPECT_EQ(another_task->dependencies().size(), 1u); + EXPECT_TRUE(task->dependencies()[0]); + + ProcessTask(another_task->dependencies()[0].get()); + ProcessTask(another_task.get()); + + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, GetTaskForImageAlreadyUploaded) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + EXPECT_EQ(task->dependencies().size(), 1u); + EXPECT_TRUE(task->dependencies()[0]); + + ProcessTask(task->dependencies()[0].get()); + ScheduleTask(task.get()); + RunTask(task.get()); + + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); + EXPECT_TRUE(need_unref); + EXPECT_FALSE(another_task); + + CompleteTask(task.get()); + + controller.UnrefImage(draw_image); + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, GetTaskForImageCanceledGetsNewTask) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + + ProcessTask(task->dependencies()[0].get()); + ScheduleTask(task.get()); + + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(another_task.get() == task.get()); + + // Didn't run the task, complete it (it was canceled). + CompleteTask(task.get()); + + // Fully cancel everything (so the raster would unref things). + controller.UnrefImage(draw_image); + controller.UnrefImage(draw_image); + + // Here a new task is created. + scoped_refptr<TileTask> third_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &third_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(third_task); + EXPECT_FALSE(third_task.get() == task.get()); + + ProcessTask(third_task->dependencies()[0].get()); + ProcessTask(third_task.get()); + + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, + GetTaskForImageCanceledWhileReffedGetsNewTask) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + + ProcessTask(task->dependencies()[0].get()); + ScheduleTask(task.get()); + + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(another_task.get() == task.get()); + + // Didn't run the task, complete it (it was canceled). + CompleteTask(task.get()); + + // Note that here, everything is reffed, but a new task is created. This is + // possible with repeated schedule/cancel operations. + scoped_refptr<TileTask> third_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &third_task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(third_task); + EXPECT_FALSE(third_task.get() == task.get()); + + ProcessTask(third_task->dependencies()[0].get()); + ProcessTask(third_task.get()); + + // 3 Unrefs! + controller.UnrefImage(draw_image); + controller.UnrefImage(draw_image); + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, NoTaskForImageAlreadyFailedDecoding) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + + ProcessTask(task->dependencies()[0].get()); + ScheduleTask(task.get()); + // Didn't run the task, complete it (it was canceled). + CompleteTask(task.get()); + + controller.SetImageDecodingFailedForTesting(draw_image); + + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); + EXPECT_FALSE(need_unref); + EXPECT_EQ(another_task.get(), nullptr); + + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, GetDecodedImageForDraw) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + + ProcessTask(task->dependencies()[0].get()); + ProcessTask(task.get()); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked()); + EXPECT_FALSE(decoded_draw_image.is_at_raster_decode()); + EXPECT_FALSE(controller.DiscardableIsLockedForTesting(draw_image)); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, GetLargeDecodedImageForDraw) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(1, 24000); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + + ProcessTask(task->dependencies()[0].get()); + ProcessTask(task.get()); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked()); + EXPECT_FALSE(decoded_draw_image.is_at_raster_decode()); + EXPECT_TRUE(controller.DiscardableIsLockedForTesting(draw_image)); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); + EXPECT_FALSE(controller.DiscardableIsLockedForTesting(draw_image)); +} + +TEST(GpuImageDecodeControllerTest, GetDecodedImageForDrawAtRasterDecode) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + controller.SetCachedItemLimitForTesting(0); + controller.SetCachedBytesLimitForTesting(0); + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_FALSE(need_unref); + EXPECT_FALSE(task); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked()); + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); + EXPECT_FALSE(controller.DiscardableIsLockedForTesting(draw_image)); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); +} + +TEST(GpuImageDecodeControllerTest, AtRasterUsedDirectlyIfSpaceAllows) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + controller.SetCachedItemLimitForTesting(0); + controller.SetCachedBytesLimitForTesting(0); + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_FALSE(need_unref); + EXPECT_FALSE(task); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked()); + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); + EXPECT_FALSE(controller.DiscardableIsLockedForTesting(draw_image)); + + controller.SetCachedItemLimitForTesting(1000); + controller.SetCachedBytesLimitForTesting(96 * 1024 * 1024); + + // Finish our draw after increasing the memory limit, image should be added to + // cache. + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + + scoped_refptr<TileTask> another_task; + bool another_task_needs_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(another_task_needs_unref); + EXPECT_FALSE(another_task); + controller.UnrefImage(draw_image); +} + +TEST(GpuImageDecodeControllerTest, + GetDecodedImageForDrawAtRasterDecodeMultipleTimes) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + controller.SetCachedItemLimitForTesting(0); + controller.SetCachedBytesLimitForTesting(0); + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked()); + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); + EXPECT_FALSE(controller.DiscardableIsLockedForTesting(draw_image)); + + DecodedDrawImage another_decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_EQ(decoded_draw_image.image()->uniqueID(), + another_decoded_draw_image.image()->uniqueID()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.DrawWithImageFinished(draw_image, another_decoded_draw_image); +} + +TEST(GpuImageDecodeControllerTest, + GetLargeDecodedImageForDrawAtRasterDecodeMultipleTimes) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(1, 24000); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked()); + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); + EXPECT_TRUE(controller.DiscardableIsLockedForTesting(draw_image)); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + EXPECT_FALSE(controller.DiscardableIsLockedForTesting(draw_image)); + + DecodedDrawImage second_decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(second_decoded_draw_image.image()); + EXPECT_FALSE(second_decoded_draw_image.image()->isTextureBacked()); + EXPECT_TRUE(second_decoded_draw_image.is_at_raster_decode()); + EXPECT_TRUE(controller.DiscardableIsLockedForTesting(draw_image)); + + controller.DrawWithImageFinished(draw_image, second_decoded_draw_image); + EXPECT_FALSE(controller.DiscardableIsLockedForTesting(draw_image)); +} + +TEST(GpuImageDecodeControllerTest, ZeroSizedImagesAreSkipped) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_FALSE(task); + EXPECT_FALSE(need_unref); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_FALSE(decoded_draw_image.image()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); +} + +TEST(GpuImageDecodeControllerTest, NonOverlappingSrcRectImagesAreSkipped) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image( + image, SkIRect::MakeXYWH(150, 150, image->width(), image->height()), + quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_FALSE(task); + EXPECT_FALSE(need_unref); + + // Must hold context lock before calling GetDecodedImageForDraw / + // DrawWithImageFinished. + ContextProvider::ScopedContextLock context_lock(context_provider.get()); + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_FALSE(decoded_draw_image.image()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); +} + +TEST(GpuImageDecodeControllerTest, CanceledTasksDoNotCountAgainstBudget) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image( + image, SkIRect::MakeXYWH(0, 0, image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_NE(0u, controller.GetBytesUsedForTesting()); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + ScheduleTask(task->dependencies()[0].get()); + CompleteTask(task->dependencies()[0].get()); + ScheduleTask(task.get()); + CompleteTask(task.get()); + + controller.UnrefImage(draw_image); + EXPECT_EQ(0u, controller.GetBytesUsedForTesting()); +} + +TEST(GpuImageDecodeControllerTest, ShouldAggressivelyFreeResources) { + auto context_provider = TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + GpuImageDecodeController controller(context_provider.get(), + ResourceFormat::RGBA_8888); + bool is_decomposable = true; + SkFilterQuality quality = kHigh_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + { + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + } + + ProcessTask(task->dependencies()[0].get()); + ProcessTask(task.get()); + + controller.UnrefImage(draw_image); + + // We should now have data image in our cache. + DCHECK_GT(controller.GetBytesUsedForTesting(), 0u); + + // Tell our controller to aggressively free resources. + controller.SetShouldAggressivelyFreeResources(true); + DCHECK_EQ(0u, controller.GetBytesUsedForTesting()); + + // Attempting to upload a new image should result in at-raster decode. + { + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_FALSE(need_unref); + EXPECT_FALSE(task); + } + + // We now tell the controller to not aggressively free resources. Uploads + // should work again. + controller.SetShouldAggressivelyFreeResources(false); + { + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(need_unref); + EXPECT_TRUE(task); + } + + ProcessTask(task->dependencies()[0].get()); + ProcessTask(task.get()); + + // The image should be in our cache after un-ref. + controller.UnrefImage(draw_image); + DCHECK_GT(controller.GetBytesUsedForTesting(), 0u); +} + +} // namespace +} // namespace cc diff --git a/chromium/cc/tiles/image_decode_controller.h b/chromium/cc/tiles/image_decode_controller.h index 4bf03d86bd8..10e93988ef9 100644 --- a/chromium/cc/tiles/image_decode_controller.h +++ b/chromium/cc/tiles/image_decode_controller.h @@ -8,17 +8,18 @@ #include "base/memory/ref_counted.h" #include "cc/playback/decoded_draw_image.h" #include "cc/playback/draw_image.h" +#include "cc/tiles/tile_priority.h" namespace cc { -class ImageDecodeTask; +class TileTask; // ImageDecodeController is responsible for generating decode tasks, decoding // images, storing images in cache, and being able to return the decoded images // when requested. // ImageDecodeController is responsible for the following things: -// 1. Given a DrawImage, it can return an ImageDecodeTask which when run will +// 1. Given a DrawImage, it can return an TileTask which when run will // decode and cache the resulting image. If the image does not need a task to // be decoded, then nullptr will be returned. The return value of the // function indicates whether the image was or is going to be locked, so an @@ -33,17 +34,33 @@ class ImageDecodeTask; // thread. class CC_EXPORT ImageDecodeController { public: + // This information should be used strictly in tracing, UMA, and any other + // reporting systems. + struct TracingInfo { + TracingInfo(uint64_t prepare_tiles_id, + TilePriority::PriorityBin requesting_tile_bin) + : prepare_tiles_id(prepare_tiles_id), + requesting_tile_bin(requesting_tile_bin) {} + TracingInfo() : TracingInfo(0, TilePriority::NOW) {} + + // ID for the current prepare tiles call. + const uint64_t prepare_tiles_id; + + // The bin of the tile that caused this image to be requested. + const TilePriority::PriorityBin requesting_tile_bin; + }; + virtual ~ImageDecodeController() {} - // Fill in an ImageDecodeTask which will decode the given image when run. In + // Fill in an TileTask which will decode the given image when run. In // case the image is already cached, fills in nullptr. Returns true if the // image needs to be unreffed when the caller is finished with it. // // This is called by the tile manager (on the compositor thread) when creating // a raster task. virtual bool GetTaskForImageAndRef(const DrawImage& image, - uint64_t prepare_tiles_id, - scoped_refptr<ImageDecodeTask>* task) = 0; + const TracingInfo& tracing_info, + scoped_refptr<TileTask>* task) = 0; // Unrefs an image. When the tile is finished, this should be called for every // GetTaskForImageAndRef call that returned true. virtual void UnrefImage(const DrawImage& image) = 0; @@ -62,6 +79,11 @@ class CC_EXPORT ImageDecodeController { // This function informs the controller that now is a good time to clean up // memory. This is called periodically from the compositor thread. virtual void ReduceCacheUsage() = 0; + + // This function informs the controller that we are hidden and should not be + // retaining cached resources longer than needed. + virtual void SetShouldAggressivelyFreeResources( + bool aggressively_free_resources) = 0; }; } // namespace cc diff --git a/chromium/cc/tiles/picture_layer_tiling.cc b/chromium/cc/tiles/picture_layer_tiling.cc index 6a555068c91..401dd78e81b 100644 --- a/chromium/cc/tiles/picture_layer_tiling.cc +++ b/chromium/cc/tiles/picture_layer_tiling.cc @@ -13,6 +13,7 @@ #include "base/containers/small_map.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/numerics/safe_conversions.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" @@ -28,40 +29,13 @@ #include "ui/gfx/geometry/size_conversions.h" namespace cc { -namespace { - -const float kSoonBorderDistanceViewportPercentage = 0.15f; -const float kMaxSoonBorderDistanceInScreenPixels = 312.f; - -} // namespace - -scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( - WhichTree tree, - float contents_scale, - scoped_refptr<RasterSource> raster_source, - PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, - float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content_pixels) { - return make_scoped_ptr(new PictureLayerTiling( - tree, contents_scale, raster_source, client, tiling_interest_area_padding, - skewport_target_time_in_seconds, - skewport_extrapolation_limit_in_content_pixels)); -} PictureLayerTiling::PictureLayerTiling( WhichTree tree, float contents_scale, scoped_refptr<RasterSource> raster_source, - PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, - float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content_pixels) - : tiling_interest_area_padding_(tiling_interest_area_padding), - skewport_target_time_in_seconds_(skewport_target_time_in_seconds), - skewport_extrapolation_limit_in_content_pixels_( - skewport_extrapolation_limit_in_content_pixels), - contents_scale_(contents_scale), + PictureLayerTilingClient* client) + : contents_scale_(contents_scale), client_(client), tree_(tree), raster_source_(raster_source), @@ -74,8 +48,7 @@ PictureLayerTiling::PictureLayerTiling( has_skewport_rect_tiles_(false), has_soon_border_rect_tiles_(false), has_eventually_rect_tiles_(false), - all_tiles_done_(true), - invalidated_since_last_compute_priority_rects_(false) { + all_tiles_done_(true) { DCHECK(!raster_source->IsSolidColor()); gfx::Size content_bounds = gfx::ScaleToCeiledSize(raster_source_->GetSize(), contents_scale); @@ -94,17 +67,6 @@ PictureLayerTiling::PictureLayerTiling( PictureLayerTiling::~PictureLayerTiling() { } -// static -float PictureLayerTiling::CalculateSoonBorderDistance( - const gfx::Rect& visible_rect_in_content_space, - float content_to_screen_scale) { - float max_dimension = std::max(visible_rect_in_content_space.width(), - visible_rect_in_content_space.height()); - return std::min( - kMaxSoonBorderDistanceInScreenPixels / content_to_screen_scale, - max_dimension * kSoonBorderDistanceViewportPercentage); -} - Tile* PictureLayerTiling::CreateTile(const Tile::CreateInfo& info) { const int i = info.tiling_i_index; const int j = info.tiling_j_index; @@ -288,7 +250,6 @@ void PictureLayerTiling::SetRasterSourceAndResize( void PictureLayerTiling::Invalidate(const Region& layer_invalidation) { DCHECK(tree_ != ACTIVE_TREE || !client_->GetPendingOrActiveTwinTiling(this)); - invalidated_since_last_compute_priority_rects_ = true; RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); } @@ -385,10 +346,15 @@ bool PictureLayerTiling::ShouldCreateTileAt( const Region* layer_invalidation = client_->GetPendingInvalidation(); // If this tile is invalidated, then the pending tree should create one. - if (layer_invalidation && - layer_invalidation->Intersects(info.enclosing_layer_rect)) - return true; - + // Do the intersection test in content space to match the corresponding check + // on the active tree and avoid floating point inconsistencies. + for (Region::Iterator iter(*layer_invalidation); iter.has_rect(); + iter.next()) { + gfx::Rect invalid_content_rect = + gfx::ScaleToEnclosingRect(iter.rect(), contents_scale_); + if (invalid_content_rect.Intersects(info.content_rect)) + return true; + } // If the active tree doesn't have a tile here, but it's in the pending tree's // visible rect, then the pending tree should create a tile. This can happen // if the pending visible rect is outside of the active tree's live tiles @@ -569,69 +535,12 @@ void PictureLayerTiling::Reset() { all_tiles_done_ = true; } -gfx::Rect PictureLayerTiling::ComputeSkewport( - double current_frame_time_in_seconds, - const gfx::Rect& visible_rect_in_content_space) const { - gfx::Rect skewport = visible_rect_in_content_space; - if (skewport.IsEmpty()) - return skewport; - - if (visible_rect_history_[1].frame_time_in_seconds == 0.0) - return skewport; - - double time_delta = current_frame_time_in_seconds - - visible_rect_history_[1].frame_time_in_seconds; - if (time_delta == 0.0) - return skewport; - - double extrapolation_multiplier = - skewport_target_time_in_seconds_ / time_delta; - - int old_x = visible_rect_history_[1].visible_rect_in_content_space.x(); - int old_y = visible_rect_history_[1].visible_rect_in_content_space.y(); - int old_right = - visible_rect_history_[1].visible_rect_in_content_space.right(); - int old_bottom = - visible_rect_history_[1].visible_rect_in_content_space.bottom(); - - int new_x = visible_rect_in_content_space.x(); - int new_y = visible_rect_in_content_space.y(); - int new_right = visible_rect_in_content_space.right(); - int new_bottom = visible_rect_in_content_space.bottom(); - - // Compute the maximum skewport based on - // |skewport_extrapolation_limit_in_content_pixels_|. - gfx::Rect max_skewport = skewport; - max_skewport.Inset(-skewport_extrapolation_limit_in_content_pixels_, - -skewport_extrapolation_limit_in_content_pixels_); - - // Inset the skewport by the needed adjustment. - skewport.Inset(extrapolation_multiplier * (new_x - old_x), - extrapolation_multiplier * (new_y - old_y), - extrapolation_multiplier * (old_right - new_right), - extrapolation_multiplier * (old_bottom - new_bottom)); - - // Ensure that visible rect is contained in the skewport. - skewport.Union(visible_rect_in_content_space); - - // Clip the skewport to |max_skewport|. This needs to happen after the - // union in case intersecting would have left the empty rect. - skewport.Intersect(max_skewport); - - // Due to limits in int's representation, it is possible that the two - // operations above (union and intersect) result in an empty skewport. To - // avoid any unpleasant situations like that, union the visible rect again to - // ensure that skewport.Contains(visible_rect_in_content_space) is always - // true. - skewport.Union(visible_rect_in_content_space); - - return skewport; -} - -bool PictureLayerTiling::ComputeTilePriorityRects( - const gfx::Rect& viewport_in_layer_space, +void PictureLayerTiling::ComputeTilePriorityRects( + const gfx::Rect& visible_rect_in_layer_space, + const gfx::Rect& skewport_in_layer_space, + const gfx::Rect& soon_border_rect_in_layer_space, + const gfx::Rect& eventually_rect_in_layer_space, 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. @@ -640,87 +549,24 @@ bool PictureLayerTiling::ComputeTilePriorityRects( set_all_tiles_done(false); } - bool invalidated = invalidated_since_last_compute_priority_rects_; - invalidated_since_last_compute_priority_rects_ = 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 invalidated; - } - const float content_to_screen_scale = ideal_contents_scale / contents_scale_; - // We want to compute the visible rect and eventually rect from it in the - // space of the tiling. But the visible rect (viewport) can be arbitrarily - // positioned, so be careful when scaling it since we can exceed integer - // bounds. - gfx::Rect eventually_rect; - gfx::Rect visible_rect_in_content_space; - - // We keep things as floats in here. - { - gfx::RectF visible_rectf_in_content_space = - gfx::ScaleRect(gfx::RectF(viewport_in_layer_space), contents_scale_); - - // Determine if the eventually rect will even touch the tiling, if it's too - // far away just treat it as empty so we don't exceed integer bounds. - const float pad_in_content_space = - tiling_interest_area_padding_ / content_to_screen_scale; - gfx::RectF eventually_rectf = visible_rectf_in_content_space; - // If the visible rect is empty, keep the eventually rect as empty. - if (!eventually_rectf.IsEmpty()) { - eventually_rectf.Inset(-pad_in_content_space, -pad_in_content_space); - - // If the eventually rect will touch the tiling, then we convert back to - // integers and set the visible and eventually rects. - auto bounds = gfx::RectF(gfx::SizeF(tiling_size())); - if (eventually_rectf.Intersects(bounds)) { - visible_rect_in_content_space = - gfx::ToEnclosingRect(visible_rectf_in_content_space); - eventually_rect = gfx::ToEnclosingRect(eventually_rectf); - } - } - } - DCHECK_EQ(visible_rect_in_content_space.IsEmpty(), eventually_rect.IsEmpty()); - - // Now we have an empty visible/eventually rect if it's not useful and a - // non-empty one if it is. We can compute the final eventually rect. - eventually_rect = - tiling_data_.ExpandRectIgnoringBordersToTileBounds(eventually_rect); - - DCHECK(eventually_rect.IsEmpty() || - gfx::Rect(tiling_size()).Contains(eventually_rect)) - << "tiling_size: " << tiling_size().ToString() - << " eventually_rect: " << eventually_rect.ToString(); - - if (tiling_size().IsEmpty()) { - UpdateVisibleRectHistory(current_frame_time_in_seconds, - visible_rect_in_content_space); - last_viewport_in_layer_space_ = viewport_in_layer_space; - return false; + const gfx::Rect* input_rects[] = { + &visible_rect_in_layer_space, &skewport_in_layer_space, + &soon_border_rect_in_layer_space, &eventually_rect_in_layer_space}; + gfx::Rect output_rects[4]; + for (size_t i = 0; i < arraysize(input_rects); ++i) { + output_rects[i] = gfx::ToEnclosingRect( + gfx::ScaleRect(gfx::RectF(*input_rects[i]), contents_scale_)); } + // Make sure the eventually rect is aligned to tile bounds. + output_rects[3] = + tiling_data_.ExpandRectIgnoringBordersToTileBounds(output_rects[3]); - // Calculate the skewport. - gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, - visible_rect_in_content_space); - DCHECK(skewport.Contains(visible_rect_in_content_space)); - - // Calculate the soon border rect. - gfx::Rect soon_border_rect = visible_rect_in_content_space; - float border = CalculateSoonBorderDistance(visible_rect_in_content_space, - content_to_screen_scale); - soon_border_rect.Inset(-border, -border, -border, -border); - - UpdateVisibleRectHistory(current_frame_time_in_seconds, - visible_rect_in_content_space); - last_viewport_in_layer_space_ = viewport_in_layer_space; - - SetTilePriorityRects(content_to_screen_scale, visible_rect_in_content_space, - skewport, soon_border_rect, eventually_rect, + SetTilePriorityRects(content_to_screen_scale, output_rects[0], + output_rects[1], output_rects[2], output_rects[3], occlusion_in_layer_space); - SetLiveTilesRect(eventually_rect); - return true; + SetLiveTilesRect(output_rects[3]); } void PictureLayerTiling::SetTilePriorityRects( diff --git a/chromium/cc/tiles/picture_layer_tiling.h b/chromium/cc/tiles/picture_layer_tiling.h index 816ac8efe59..fcd06ace8cd 100644 --- a/chromium/cc/tiles/picture_layer_tiling.h +++ b/chromium/cc/tiles/picture_layer_tiling.h @@ -9,12 +9,12 @@ #include <stdint.h> #include <map> +#include <memory> #include <unordered_map> #include <utility> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/base/region.h" #include "cc/base/tiling_data.h" @@ -80,22 +80,13 @@ class CC_EXPORT PictureLayerTiling { public: static const int kBorderTexels = 1; - PictureLayerTilingClient* client() const { return client_; } + PictureLayerTiling(WhichTree tree, + float contents_scale, + scoped_refptr<RasterSource> raster_source, + PictureLayerTilingClient* client); ~PictureLayerTiling(); - static float CalculateSoonBorderDistance( - const gfx::Rect& visible_rect_in_content_space, - float content_to_screen_scale); - - // Create a tiling with no tiles. CreateTile() must be called to add some. - static scoped_ptr<PictureLayerTiling> Create( - WhichTree tree, - float contents_scale, - scoped_refptr<RasterSource> raster_source, - PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, - float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content_pixels); + PictureLayerTilingClient* client() const { return client_; } void SetRasterSourceAndResize(scoped_refptr<RasterSource> raster_source); void Invalidate(const Region& layer_invalidation); @@ -236,10 +227,13 @@ class CC_EXPORT PictureLayerTiling { void Reset(); - bool ComputeTilePriorityRects(const gfx::Rect& viewport_in_layer_space, - float ideal_contents_scale, - double current_frame_time_in_seconds, - const Occlusion& occlusion_in_layer_space); + void ComputeTilePriorityRects( + const gfx::Rect& visible_rect_in_layer_space, + const gfx::Rect& skewport_in_layer_space, + const gfx::Rect& soon_border_rect_in_layer_space, + const gfx::Rect& eventually_rect_in_layer_space, + float ideal_contents_scale, + const Occlusion& occlusion_in_layer_space); void GetAllPrioritizedTilesForTracing( std::vector<PrioritizedTile>* prioritized_tiles) const; @@ -268,18 +262,6 @@ class CC_EXPORT PictureLayerTiling { using TileMap = std::unordered_map<TileMapKey, ScopedTilePtr, TileMapKeyHash>; - struct FrameVisibleRect { - gfx::Rect visible_rect_in_content_space; - double frame_time_in_seconds = 0.0; - }; - - PictureLayerTiling(WhichTree tree, - float contents_scale, - scoped_refptr<RasterSource> raster_source, - PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, - float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content_pixels); void SetLiveTilesRect(const gfx::Rect& live_tiles_rect); void VerifyLiveTilesRect(bool is_on_recycle_tree) const; Tile* CreateTile(const Tile::CreateInfo& info); @@ -288,14 +270,6 @@ class CC_EXPORT PictureLayerTiling { bool RemoveTileAt(int i, int j); bool TilingMatchesTileIndices(const PictureLayerTiling* twin) const; - // Computes a skewport. The calculation extrapolates the last visible - // rect and the current visible rect to expand the skewport to where it - // would be in |skewport_target_time| seconds. Note that the skewport - // is guaranteed to contain the current visible rect. - gfx::Rect ComputeSkewport(double current_frame_time_in_seconds, - const gfx::Rect& visible_rect_in_content_space) - const; - // Save the required data for computing tile priorities later. void SetTilePriorityRects(float content_to_screen_scale_, const gfx::Rect& visible_rect_in_content_space, @@ -304,24 +278,6 @@ class CC_EXPORT PictureLayerTiling { const gfx::Rect& eventually_rect, const Occlusion& occlusion_in_layer_space); - bool NeedsUpdateForFrameAtTimeAndViewport( - double frame_time_in_seconds, - const gfx::Rect& viewport_in_layer_space) { - return frame_time_in_seconds != - visible_rect_history_[0].frame_time_in_seconds || - viewport_in_layer_space != last_viewport_in_layer_space_; - } - void UpdateVisibleRectHistory( - double frame_time_in_seconds, - const gfx::Rect& visible_rect_in_content_space) { - visible_rect_history_[1] = visible_rect_history_[0]; - visible_rect_history_[0].frame_time_in_seconds = frame_time_in_seconds; - visible_rect_history_[0].visible_rect_in_content_space = - visible_rect_in_content_space; - // If we don't have a second history item, set it to the most recent one. - if (visible_rect_history_[1].frame_time_in_seconds == 0.0) - visible_rect_history_[1] = visible_rect_history_[0]; - } bool IsTileOccludedOnCurrentTree(const Tile* tile) const; Tile::CreateInfo CreateInfoForTile(int i, int j) const; bool ShouldCreateTileAt(const Tile::CreateInfo& info) const; @@ -361,15 +317,8 @@ class CC_EXPORT PictureLayerTiling { const gfx::Rect& current_eventually_rect() const { return current_eventually_rect_; } - bool has_ever_been_updated() const { - return visible_rect_history_[0].frame_time_in_seconds != 0.0; - } void RemoveTilesInRegion(const Region& layer_region, bool recreate_tiles); - const size_t tiling_interest_area_padding_; - const float skewport_target_time_in_seconds_; - const int skewport_extrapolation_limit_in_content_pixels_; - // Given properties. const float contents_scale_; PictureLayerTilingClient* const client_; @@ -383,10 +332,6 @@ class CC_EXPORT PictureLayerTiling { TileMap tiles_; // It is not legal to have a NULL tile in the tiles_ map. gfx::Rect live_tiles_rect_; - gfx::Rect last_viewport_in_layer_space_; - // State saved for computing velocities based upon finite differences. - FrameVisibleRect visible_rect_history_[2]; - bool can_require_tiles_for_activation_; // Iteration rects in content space. @@ -403,7 +348,6 @@ class CC_EXPORT PictureLayerTiling { bool has_soon_border_rect_tiles_; bool has_eventually_rect_tiles_; bool all_tiles_done_; - bool invalidated_since_last_compute_priority_rects_; private: DISALLOW_COPY_AND_ASSIGN(PictureLayerTiling); diff --git a/chromium/cc/tiles/picture_layer_tiling_perftest.cc b/chromium/cc/tiles/picture_layer_tiling_perftest.cc deleted file mode 100644 index f612f39ca4e..00000000000 --- a/chromium/cc/tiles/picture_layer_tiling_perftest.cc +++ /dev/null @@ -1,170 +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/debug/lap_timer.h" -#include "cc/resources/resource_provider.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_picture_layer_tiling_client.h" -#include "cc/test/fake_raster_source.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" - -namespace cc { - -namespace { - -static const int kTimeLimitMillis = 2000; -static const int kWarmupRuns = 5; -static const int kTimeCheckInterval = 10; - -class PictureLayerTilingPerfTest : public testing::Test { - public: - PictureLayerTilingPerfTest() - : timer_(kWarmupRuns, - base::TimeDelta::FromMilliseconds(kTimeLimitMillis), - kTimeCheckInterval), - context_provider_(TestContextProvider::Create()) { - output_surface_ = FakeOutputSurface::Create3d(context_provider_); - CHECK(output_surface_->BindToClient(&output_surface_client_)); - - shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = FakeResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get()); - } - - void SetUp() override { - LayerTreeSettings defaults; - picture_layer_tiling_client_.SetTileSize(gfx::Size(256, 256)); - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(gfx::Size(256 * 50, 256 * 50)); - picture_layer_tiling_ = PictureLayerTiling::Create( - PENDING_TREE, 1.f, raster_source, &picture_layer_tiling_client_, - defaults.tiling_interest_area_padding, - defaults.skewport_target_time_in_seconds, - defaults.skewport_extrapolation_limit_in_content_pixels); - picture_layer_tiling_->CreateAllTilesForTesting(); - } - - void TearDown() override { picture_layer_tiling_.reset(NULL); } - - void RunInvalidateTest(const std::string& test_name, const Region& region) { - timer_.Reset(); - do { - picture_layer_tiling_->Invalidate(region); - timer_.NextLap(); - } while (!timer_.HasTimeLimitExpired()); - - perf_test::PrintResult( - "invalidation", "", test_name, timer_.LapsPerSecond(), "runs/s", true); - } - - void RunComputeTilePriorityRectsStationaryTest( - const std::string& test_name, - const gfx::Transform& transform) { - gfx::Rect viewport_rect(0, 0, 1024, 768); - - timer_.Reset(); - do { - picture_layer_tiling_->ComputeTilePriorityRects( - viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion()); - timer_.NextLap(); - } while (!timer_.HasTimeLimitExpired()); - - perf_test::PrintResult("compute_tile_priority_rects_stationary", - "", - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); - } - - void RunComputeTilePriorityRectsScrollingTest( - const std::string& test_name, - const gfx::Transform& transform) { - gfx::Size viewport_size(1024, 768); - gfx::Rect viewport_rect(viewport_size); - int xoffsets[] = {10, 0, -10, 0}; - int yoffsets[] = {0, 10, 0, -10}; - int offset_index = 0; - int offset_count = 0; - const int max_offset_count = 1000; - - timer_.Reset(); - do { - picture_layer_tiling_->ComputeTilePriorityRects( - viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion()); - - viewport_rect = gfx::Rect(viewport_rect.x() + xoffsets[offset_index], - viewport_rect.y() + yoffsets[offset_index], - viewport_rect.width(), viewport_rect.height()); - - if (++offset_count > max_offset_count) { - offset_count = 0; - offset_index = (offset_index + 1) % 4; - } - timer_.NextLap(); - } while (!timer_.HasTimeLimitExpired()); - - perf_test::PrintResult("compute_tile_priority_rects_scrolling", - "", - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); - } - - private: - FakePictureLayerTilingClient picture_layer_tiling_client_; - scoped_ptr<PictureLayerTiling> picture_layer_tiling_; - - LapTimer timer_; - - scoped_refptr<ContextProvider> context_provider_; - FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> output_surface_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> resource_provider_; -}; - -TEST_F(PictureLayerTilingPerfTest, Invalidate) { - Region one_tile(gfx::Rect(256, 256)); - RunInvalidateTest("1x1", one_tile); - - Region half_region(gfx::Rect(25 * 256, 50 * 256)); - RunInvalidateTest("25x50", half_region); - - Region full_region(gfx::Rect(50 * 256, 50 * 256)); - RunInvalidateTest("50x50", full_region); -} - -#if defined(OS_ANDROID) -// TODO(vmpstr): Investigate why this is noisy (crbug.com/310220). -TEST_F(PictureLayerTilingPerfTest, DISABLED_ComputeTilePriorityRects) { -#else -TEST_F(PictureLayerTilingPerfTest, ComputeTilePriorityRects) { -#endif // defined(OS_ANDROID) - gfx::Transform transform; - - RunComputeTilePriorityRectsStationaryTest("no_transform", transform); - RunComputeTilePriorityRectsScrollingTest("no_transform", transform); - - transform.Rotate(10); - RunComputeTilePriorityRectsStationaryTest("rotation", transform); - RunComputeTilePriorityRectsScrollingTest("rotation", transform); - - transform.ApplyPerspectiveDepth(10); - RunComputeTilePriorityRectsStationaryTest("perspective", transform); - RunComputeTilePriorityRectsScrollingTest("perspective", transform); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/tiles/picture_layer_tiling_set.cc b/chromium/cc/tiles/picture_layer_tiling_set.cc index 2c8e930df3a..469080f8d85 100644 --- a/chromium/cc/tiles/picture_layer_tiling_set.cc +++ b/chromium/cc/tiles/picture_layer_tiling_set.cc @@ -10,7 +10,9 @@ #include <set> #include <vector> +#include "base/memory/ptr_util.h" #include "cc/playback/raster_source.h" +#include "ui/gfx/geometry/rect_conversions.h" namespace cc { @@ -18,8 +20,8 @@ namespace { class LargestToSmallestScaleFunctor { public: - bool operator()(const scoped_ptr<PictureLayerTiling>& left, - const scoped_ptr<PictureLayerTiling>& right) { + bool operator()(const std::unique_ptr<PictureLayerTiling>& left, + const std::unique_ptr<PictureLayerTiling>& right) { return left->contents_scale() > right->contents_scale(); } }; @@ -30,31 +32,34 @@ inline float LargerRatio(float float1, float float2) { return float1 > float2 ? float1 / float2 : float2 / float1; } +const float kSoonBorderDistanceViewportPercentage = 0.15f; +const float kMaxSoonBorderDistanceInScreenPixels = 312.f; + } // namespace // static -scoped_ptr<PictureLayerTilingSet> PictureLayerTilingSet::Create( +std::unique_ptr<PictureLayerTilingSet> PictureLayerTilingSet::Create( WhichTree tree, PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, + int tiling_interest_area_padding, float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content_pixels) { - return make_scoped_ptr(new PictureLayerTilingSet( - tree, client, tiling_interest_area_padding, - skewport_target_time_in_seconds, - skewport_extrapolation_limit_in_content_pixels)); + int skewport_extrapolation_limit_in_screen_pixels) { + return base::WrapUnique( + new PictureLayerTilingSet(tree, client, tiling_interest_area_padding, + skewport_target_time_in_seconds, + skewport_extrapolation_limit_in_screen_pixels)); } PictureLayerTilingSet::PictureLayerTilingSet( WhichTree tree, PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, + int tiling_interest_area_padding, float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content_pixels) + int skewport_extrapolation_limit_in_screen_pixels) : tiling_interest_area_padding_(tiling_interest_area_padding), skewport_target_time_in_seconds_(skewport_target_time_in_seconds), - skewport_extrapolation_limit_in_content_pixels_( - skewport_extrapolation_limit_in_content_pixels), + skewport_extrapolation_limit_in_screen_pixels_( + skewport_extrapolation_limit_in_screen_pixels), tree_(tree), client_(client) {} @@ -78,13 +83,12 @@ void PictureLayerTilingSet::CopyTilingsAndPropertiesFromPendingTwin( float contents_scale = pending_twin_tiling->contents_scale(); PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale); if (!this_tiling) { - scoped_ptr<PictureLayerTiling> new_tiling = PictureLayerTiling::Create( - tree_, contents_scale, raster_source, client_, - tiling_interest_area_padding_, skewport_target_time_in_seconds_, - skewport_extrapolation_limit_in_content_pixels_); + std::unique_ptr<PictureLayerTiling> new_tiling(new PictureLayerTiling( + tree_, contents_scale, raster_source_, client_)); tilings_.push_back(std::move(new_tiling)); this_tiling = tilings_.back().get(); tiling_sort_required = true; + state_since_last_tile_priority_update_.added_tilings = true; } this_tiling->TakeTilesAndPropertiesFrom(pending_twin_tiling.get(), layer_invalidation); @@ -105,6 +109,8 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation( RemoveTilingsBelowScale(minimum_contents_scale); RemoveTilingsAboveScale(maximum_contents_scale); + raster_source_ = raster_source; + // Copy over tilings that are shared with the |pending_twin_set| tiling set. // Also, copy all of the properties from twin tilings. CopyTilingsAndPropertiesFromPendingTwin(pending_twin_set, raster_source, @@ -118,6 +124,7 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation( tiling->SetRasterSourceAndResize(raster_source); tiling->Invalidate(layer_invalidation); + state_since_last_tile_priority_update_.invalidated = true; // 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. @@ -143,15 +150,19 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit( RemoveTilingsBelowScale(minimum_contents_scale); RemoveTilingsAboveScale(maximum_contents_scale); + raster_source_ = raster_source; + // Invalidate tiles and update them to the new raster source. - for (const scoped_ptr<PictureLayerTiling>& tiling : tilings_) { + for (const std::unique_ptr<PictureLayerTiling>& tiling : tilings_) { DCHECK(tree_ != PENDING_TREE || !tiling->has_tiles()); tiling->SetRasterSourceAndResize(raster_source); // We can commit on either active or pending trees, but only active one can // have tiles at this point. - if (tree_ == ACTIVE_TREE) + if (tree_ == ACTIVE_TREE) { tiling->Invalidate(layer_invalidation); + state_since_last_tile_priority_update_.invalidated = true; + } // 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 @@ -164,9 +175,11 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit( void PictureLayerTilingSet::UpdateRasterSourceDueToLCDChange( scoped_refptr<RasterSource> raster_source, const Region& layer_invalidation) { + raster_source_ = raster_source; for (const auto& tiling : tilings_) { tiling->SetRasterSourceAndResize(raster_source); tiling->Invalidate(layer_invalidation); + state_since_last_tile_priority_update_.invalidated = true; // Since the invalidation changed, we need to create any missing tiles in // the live tiles rect again. tiling->CreateMissingTilesInLiveTilesRect(); @@ -236,7 +249,7 @@ void PictureLayerTilingSet::CleanUpTilings( void PictureLayerTilingSet::RemoveNonIdealTilings() { auto to_remove = std::remove_if(tilings_.begin(), tilings_.end(), - [](const scoped_ptr<PictureLayerTiling>& t) { + [](const std::unique_ptr<PictureLayerTiling>& t) { return t->resolution() == NON_IDEAL_RESOLUTION; }); tilings_.erase(to_remove, tilings_.end()); @@ -250,16 +263,18 @@ void PictureLayerTilingSet::MarkAllTilingsNonIdeal() { PictureLayerTiling* PictureLayerTilingSet::AddTiling( float contents_scale, scoped_refptr<RasterSource> raster_source) { + if (!raster_source_) + raster_source_ = raster_source; + for (size_t i = 0; i < tilings_.size(); ++i) { DCHECK_NE(tilings_[i]->contents_scale(), contents_scale); DCHECK_EQ(tilings_[i]->raster_source(), raster_source.get()); } - tilings_.push_back(PictureLayerTiling::Create( - tree_, contents_scale, raster_source, client_, - tiling_interest_area_padding_, skewport_target_time_in_seconds_, - skewport_extrapolation_limit_in_content_pixels_)); + tilings_.push_back(base::WrapUnique( + new PictureLayerTiling(tree_, contents_scale, raster_source, client_))); PictureLayerTiling* appended = tilings_.back().get(); + state_since_last_tile_priority_update_.added_tilings = true; std::sort(tilings_.begin(), tilings_.end(), LargestToSmallestScaleFunctor()); return appended; @@ -267,7 +282,7 @@ PictureLayerTiling* PictureLayerTilingSet::AddTiling( int PictureLayerTilingSet::NumHighResTilings() const { return std::count_if(tilings_.begin(), tilings_.end(), - [](const scoped_ptr<PictureLayerTiling>& tiling) { + [](const std::unique_ptr<PictureLayerTiling>& tiling) { return tiling->resolution() == HIGH_RESOLUTION; }); } @@ -283,11 +298,11 @@ PictureLayerTiling* PictureLayerTilingSet::FindTilingWithScale( PictureLayerTiling* PictureLayerTilingSet::FindTilingWithResolution( TileResolution resolution) const { - auto iter = - std::find_if(tilings_.begin(), tilings_.end(), - [resolution](const scoped_ptr<PictureLayerTiling>& tiling) { - return tiling->resolution() == resolution; - }); + auto iter = std::find_if( + tilings_.begin(), tilings_.end(), + [resolution](const std::unique_ptr<PictureLayerTiling>& tiling) { + return tiling->resolution() == resolution; + }); if (iter == tilings_.end()) return nullptr; return iter->get(); @@ -296,7 +311,7 @@ PictureLayerTiling* PictureLayerTilingSet::FindTilingWithResolution( void PictureLayerTilingSet::RemoveTilingsBelowScale(float minimum_scale) { auto to_remove = std::remove_if( tilings_.begin(), tilings_.end(), - [minimum_scale](const scoped_ptr<PictureLayerTiling>& tiling) { + [minimum_scale](const std::unique_ptr<PictureLayerTiling>& tiling) { return tiling->contents_scale() < minimum_scale; }); tilings_.erase(to_remove, tilings_.end()); @@ -305,7 +320,7 @@ void PictureLayerTilingSet::RemoveTilingsBelowScale(float minimum_scale) { void PictureLayerTilingSet::RemoveTilingsAboveScale(float maximum_scale) { auto to_remove = std::remove_if( tilings_.begin(), tilings_.end(), - [maximum_scale](const scoped_ptr<PictureLayerTiling>& tiling) { + [maximum_scale](const std::unique_ptr<PictureLayerTiling>& tiling) { return tiling->contents_scale() > maximum_scale; }); tilings_.erase(to_remove, tilings_.end()); @@ -316,11 +331,11 @@ void PictureLayerTilingSet::RemoveAllTilings() { } void PictureLayerTilingSet::Remove(PictureLayerTiling* tiling) { - auto iter = - std::find_if(tilings_.begin(), tilings_.end(), - [tiling](const scoped_ptr<PictureLayerTiling>& candidate) { - return candidate.get() == tiling; - }); + auto iter = std::find_if( + tilings_.begin(), tilings_.end(), + [tiling](const std::unique_ptr<PictureLayerTiling>& candidate) { + return candidate.get() == tiling; + }); if (iter == tilings_.end()) return; tilings_.erase(iter); @@ -355,21 +370,168 @@ float PictureLayerTilingSet::GetMaximumContentsScale() const { return tilings_[0]->contents_scale(); } +bool PictureLayerTilingSet::TilingsNeedUpdate( + const gfx::Rect& visible_rect_in_layer_space, + double current_frame_time_in_seconds) { + // If we don't have any tilings, we don't need an update. + if (num_tilings() == 0) + return false; + + // If we never updated the tiling set, then our history is empty. We should + // update tilings. + if (visible_rect_history_.empty()) + return true; + + // If we've added new tilings since the last update, then we have to update at + // least that one tiling. + if (state_since_last_tile_priority_update_.added_tilings) + return true; + + // Finally, if some state changed (either frame time or visible rect), then we + // need to inform the tilings of the change. + const auto& last_frame = visible_rect_history_.front(); + if (current_frame_time_in_seconds != last_frame.frame_time_in_seconds) + return true; + + if (visible_rect_in_layer_space != last_frame.visible_rect_in_layer_space) + return true; + return false; +} + +gfx::Rect PictureLayerTilingSet::ComputeSkewport( + const gfx::Rect& visible_rect_in_layer_space, + double current_frame_time_in_seconds, + float ideal_contents_scale) { + gfx::Rect skewport = visible_rect_in_layer_space; + if (skewport.IsEmpty() || visible_rect_history_.empty()) + return skewport; + + // Use the oldest recorded history to get a stable skewport. + const auto& historical_frame = visible_rect_history_.back(); + double time_delta = + current_frame_time_in_seconds - historical_frame.frame_time_in_seconds; + if (time_delta == 0.) + return skewport; + + double extrapolation_multiplier = + skewport_target_time_in_seconds_ / time_delta; + int old_x = historical_frame.visible_rect_in_layer_space.x(); + int old_y = historical_frame.visible_rect_in_layer_space.y(); + int old_right = historical_frame.visible_rect_in_layer_space.right(); + int old_bottom = historical_frame.visible_rect_in_layer_space.bottom(); + + int new_x = visible_rect_in_layer_space.x(); + int new_y = visible_rect_in_layer_space.y(); + int new_right = visible_rect_in_layer_space.right(); + int new_bottom = visible_rect_in_layer_space.bottom(); + + int inset_x = (new_x - old_x) * extrapolation_multiplier; + int inset_y = (new_y - old_y) * extrapolation_multiplier; + int inset_right = (old_right - new_right) * extrapolation_multiplier; + int inset_bottom = (old_bottom - new_bottom) * extrapolation_multiplier; + + int skewport_extrapolation_limit_in_layer_pixels = + skewport_extrapolation_limit_in_screen_pixels_ / ideal_contents_scale; + gfx::Rect max_skewport = skewport; + max_skewport.Inset(-skewport_extrapolation_limit_in_layer_pixels, + -skewport_extrapolation_limit_in_layer_pixels); + + skewport.Inset(inset_x, inset_y, inset_right, inset_bottom); + skewport.Union(visible_rect_in_layer_space); + skewport.Intersect(max_skewport); + + // Due to limits in int's representation, it is possible that the two + // operations above (union and intersect) result in an empty skewport. To + // avoid any unpleasant situations like that, union the visible rect again to + // ensure that skewport.Contains(visible_rect_in_layer_space) is always + // true. + skewport.Union(visible_rect_in_layer_space); + skewport.Intersect(eventually_rect_in_layer_space_); + return skewport; +} + +gfx::Rect PictureLayerTilingSet::ComputeSoonBorderRect( + const gfx::Rect& visible_rect, + float ideal_contents_scale) { + int max_dimension = std::max(visible_rect.width(), visible_rect.height()); + int distance = + std::min<int>(kMaxSoonBorderDistanceInScreenPixels * ideal_contents_scale, + max_dimension * kSoonBorderDistanceViewportPercentage); + + gfx::Rect soon_border_rect = visible_rect; + soon_border_rect.Inset(-distance, -distance); + soon_border_rect.Intersect(eventually_rect_in_layer_space_); + return soon_border_rect; +} + +void PictureLayerTilingSet::UpdatePriorityRects( + const gfx::Rect& visible_rect_in_layer_space, + double current_frame_time_in_seconds, + float ideal_contents_scale) { + visible_rect_in_layer_space_ = gfx::Rect(); + eventually_rect_in_layer_space_ = gfx::Rect(); + + // We keep things as floats in here. + if (!visible_rect_in_layer_space.IsEmpty()) { + gfx::RectF eventually_rectf(visible_rect_in_layer_space); + eventually_rectf.Inset( + -tiling_interest_area_padding_ / ideal_contents_scale, + -tiling_interest_area_padding_ / ideal_contents_scale); + if (eventually_rectf.Intersects( + gfx::RectF(gfx::SizeF(raster_source_->GetSize())))) { + visible_rect_in_layer_space_ = visible_rect_in_layer_space; + eventually_rect_in_layer_space_ = gfx::ToEnclosingRect(eventually_rectf); + } + } + + skewport_in_layer_space_ = + ComputeSkewport(visible_rect_in_layer_space_, + current_frame_time_in_seconds, ideal_contents_scale); + DCHECK(skewport_in_layer_space_.Contains(visible_rect_in_layer_space_)); + DCHECK(eventually_rect_in_layer_space_.Contains(skewport_in_layer_space_)); + + soon_border_rect_in_layer_space_ = + ComputeSoonBorderRect(visible_rect_in_layer_space_, ideal_contents_scale); + DCHECK( + soon_border_rect_in_layer_space_.Contains(visible_rect_in_layer_space_)); + DCHECK(eventually_rect_in_layer_space_.Contains( + soon_border_rect_in_layer_space_)); + + // Finally, update our visible rect history. Note that we use the original + // visible rect here, since we want as accurate of a history as possible for + // stable skewports. + visible_rect_history_.push_front(FrameVisibleRect( + visible_rect_in_layer_space_, current_frame_time_in_seconds)); + if (visible_rect_history_.size() > 2) + visible_rect_history_.pop_back(); +} + bool PictureLayerTilingSet::UpdateTilePriorities( - const gfx::Rect& required_rect_in_layer_space, + const gfx::Rect& visible_rect_in_layer_space, float ideal_contents_scale, double current_frame_time_in_seconds, const Occlusion& occlusion_in_layer_space, bool can_require_tiles_for_activation) { - bool updated = false; + StateSinceLastTilePriorityUpdate::AutoClear auto_clear_state( + &state_since_last_tile_priority_update_); + + if (!TilingsNeedUpdate(visible_rect_in_layer_space, + current_frame_time_in_seconds)) { + return state_since_last_tile_priority_update_.invalidated; + } + + UpdatePriorityRects(visible_rect_in_layer_space, + current_frame_time_in_seconds, ideal_contents_scale); + for (const auto& tiling : tilings_) { tiling->set_can_require_tiles_for_activation( can_require_tiles_for_activation); - updated |= tiling->ComputeTilePriorityRects( - required_rect_in_layer_space, ideal_contents_scale, - current_frame_time_in_seconds, occlusion_in_layer_space); + tiling->ComputeTilePriorityRects( + visible_rect_in_layer_space_, skewport_in_layer_space_, + soon_border_rect_in_layer_space_, eventually_rect_in_layer_space_, + ideal_contents_scale, occlusion_in_layer_space); } - return updated; + return true; } void PictureLayerTilingSet::GetAllPrioritizedTilesForTracing( diff --git a/chromium/cc/tiles/picture_layer_tiling_set.h b/chromium/cc/tiles/picture_layer_tiling_set.h index 41a2dad07e9..dfa05926522 100644 --- a/chromium/cc/tiles/picture_layer_tiling_set.h +++ b/chromium/cc/tiles/picture_layer_tiling_set.h @@ -39,12 +39,12 @@ class CC_EXPORT PictureLayerTilingSet { size_t end; }; - static scoped_ptr<PictureLayerTilingSet> Create( + static std::unique_ptr<PictureLayerTilingSet> Create( WhichTree tree, PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, + int tiling_interest_area_padding, float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content); + int skewport_extrapolation_limit_in_screen_pixels); ~PictureLayerTilingSet(); @@ -115,6 +115,7 @@ class CC_EXPORT PictureLayerTilingSet { void RemoveAllTiles(); // Update the rects and priorities for tiles based on the given information. + // Returns true if PrepareTiles is required. bool UpdateTilePriorities(const gfx::Rect& required_rect_in_layer_space, float ideal_contents_scale, double current_frame_time_in_seconds, @@ -172,13 +173,40 @@ class CC_EXPORT PictureLayerTilingSet { TilingRange GetTilingRange(TilingRangeType type) const; - private: + protected: + struct FrameVisibleRect { + FrameVisibleRect(const gfx::Rect& rect, double time_in_seconds) + : visible_rect_in_layer_space(rect), + frame_time_in_seconds(time_in_seconds) {} + + gfx::Rect visible_rect_in_layer_space; + double frame_time_in_seconds; + }; + + struct StateSinceLastTilePriorityUpdate { + class AutoClear { + public: + explicit AutoClear(StateSinceLastTilePriorityUpdate* state_to_clear) + : state_to_clear_(state_to_clear) {} + ~AutoClear() { *state_to_clear_ = StateSinceLastTilePriorityUpdate(); } + + private: + StateSinceLastTilePriorityUpdate* state_to_clear_; + }; + + StateSinceLastTilePriorityUpdate() + : invalidated(false), added_tilings(false) {} + + bool invalidated; + bool added_tilings; + }; + explicit PictureLayerTilingSet( WhichTree tree, PictureLayerTilingClient* client, - size_t tiling_interest_area_padding, + int tiling_interest_area_padding, float skewport_target_time_in_seconds, - int skewport_extrapolation_limit_in_content_pixels); + int skewport_extrapolation_limit_in_screen_pixels); void CopyTilingsAndPropertiesFromPendingTwin( const PictureLayerTilingSet* pending_twin_set, @@ -189,15 +217,39 @@ class CC_EXPORT PictureLayerTilingSet { void Remove(PictureLayerTiling* tiling); void VerifyTilings(const PictureLayerTilingSet* pending_twin_set) const; - std::vector<scoped_ptr<PictureLayerTiling>> tilings_; + bool TilingsNeedUpdate(const gfx::Rect& required_rect_in_layer_space, + double current_frame_time_in_Seconds); + gfx::Rect ComputeSkewport(const gfx::Rect& visible_rect_in_layer_space, + double current_frame_time_in_seconds, + float ideal_contents_scale); + gfx::Rect ComputeSoonBorderRect(const gfx::Rect& visible_rect_in_layer_space, + float ideal_contents_scale); + void UpdatePriorityRects(const gfx::Rect& visible_rect_in_layer_space, + double current_frame_time_in_seconds, + float ideal_contents_scale); + + std::vector<std::unique_ptr<PictureLayerTiling>> tilings_; - const size_t tiling_interest_area_padding_; + const int tiling_interest_area_padding_; const float skewport_target_time_in_seconds_; - const int skewport_extrapolation_limit_in_content_pixels_; + const int skewport_extrapolation_limit_in_screen_pixels_; WhichTree tree_; PictureLayerTilingClient* client_; + // State saved for computing velocities based on finite differences. + // .front() of the list refers to the most recent FrameVisibleRect. + std::list<FrameVisibleRect> visible_rect_history_; + StateSinceLastTilePriorityUpdate state_since_last_tile_priority_update_; + + scoped_refptr<RasterSource> raster_source_; + + gfx::Rect visible_rect_in_layer_space_; + gfx::Rect skewport_in_layer_space_; + gfx::Rect soon_border_rect_in_layer_space_; + gfx::Rect eventually_rect_in_layer_space_; friend class Iterator; + + private: DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingSet); }; diff --git a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc index 477c8f55281..019e5abda63 100644 --- a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc +++ b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc @@ -21,19 +21,43 @@ namespace cc { namespace { -scoped_ptr<PictureLayerTilingSet> CreateTilingSet( +class TestablePictureLayerTilingSet : public PictureLayerTilingSet { + public: + TestablePictureLayerTilingSet( + WhichTree tree, + PictureLayerTilingClient* client, + int tiling_interest_area_padding, + float skewport_target_time_in_seconds, + int skewport_extrapolation_limit_in_screen_pixels) + : PictureLayerTilingSet(tree, + client, + tiling_interest_area_padding, + skewport_target_time_in_seconds, + skewport_extrapolation_limit_in_screen_pixels) {} + + using PictureLayerTilingSet::ComputeSkewport; + using PictureLayerTilingSet::ComputeSoonBorderRect; + using PictureLayerTilingSet::TilingsNeedUpdate; +}; + +std::unique_ptr<TestablePictureLayerTilingSet> CreateTilingSetWithSettings( + PictureLayerTilingClient* client, + const LayerTreeSettings& settings) { + return base::WrapUnique(new TestablePictureLayerTilingSet( + ACTIVE_TREE, client, settings.tiling_interest_area_padding, + settings.skewport_target_time_in_seconds, + settings.skewport_extrapolation_limit_in_screen_pixels)); +} + +std::unique_ptr<TestablePictureLayerTilingSet> CreateTilingSet( PictureLayerTilingClient* client) { - LayerTreeSettings defaults; - return PictureLayerTilingSet::Create( - ACTIVE_TREE, client, defaults.tiling_interest_area_padding, - defaults.skewport_target_time_in_seconds, - defaults.skewport_extrapolation_limit_in_content_pixels); + return CreateTilingSetWithSettings(client, LayerTreeSettings()); } TEST(PictureLayerTilingSetTest, NoResources) { FakePictureLayerTilingClient client; gfx::Size layer_bounds(1000, 800); - scoped_ptr<PictureLayerTilingSet> set = CreateTilingSet(&client); + std::unique_ptr<TestablePictureLayerTilingSet> set = CreateTilingSet(&client); client.SetTileSize(gfx::Size(256, 256)); scoped_refptr<FakeRasterSource> raster_source = @@ -77,7 +101,7 @@ TEST(PictureLayerTilingSetTest, TilingRange) { scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(layer_bounds); - scoped_ptr<PictureLayerTilingSet> set = CreateTilingSet(&client); + std::unique_ptr<TestablePictureLayerTilingSet> set = CreateTilingSet(&client); set->AddTiling(2.0, raster_source); high_res_tiling = set->AddTiling(1.0, raster_source); high_res_tiling->set_resolution(HIGH_RESOLUTION); @@ -109,7 +133,7 @@ TEST(PictureLayerTilingSetTest, TilingRange) { 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 = + std::unique_ptr<TestablePictureLayerTilingSet> set_without_low_res = CreateTilingSet(&client); set_without_low_res->AddTiling(2.0, raster_source); high_res_tiling = set_without_low_res->AddTiling(1.0, raster_source); @@ -140,8 +164,8 @@ TEST(PictureLayerTilingSetTest, TilingRange) { PictureLayerTilingSet::LOWER_THAN_LOW_RES); 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); + std::unique_ptr<TestablePictureLayerTilingSet> + set_with_only_high_and_low_res = CreateTilingSet(&client); high_res_tiling = set_with_only_high_and_low_res->AddTiling(1.0, raster_source); high_res_tiling->set_resolution(HIGH_RESOLUTION); @@ -174,7 +198,7 @@ TEST(PictureLayerTilingSetTest, TilingRange) { PictureLayerTilingSet::LOWER_THAN_LOW_RES); EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start); - scoped_ptr<PictureLayerTilingSet> set_with_only_high_res = + std::unique_ptr<TestablePictureLayerTilingSet> set_with_only_high_res = CreateTilingSet(&client); high_res_tiling = set_with_only_high_res->AddTiling(1.0, raster_source); high_res_tiling->set_resolution(HIGH_RESOLUTION); @@ -211,20 +235,21 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { float ideal_contents_scale, float expected_scale) { FakeOutputSurfaceClient output_surface_client; - scoped_ptr<FakeOutputSurface> output_surface = + std::unique_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<SharedBitmapManager> shared_bitmap_manager( + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = + std::unique_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(output_surface.get(), shared_bitmap_manager.get()); FakePictureLayerTilingClient client(resource_provider.get()); client.SetTileSize(gfx::Size(256, 256)); gfx::Size layer_bounds(1000, 800); - scoped_ptr<PictureLayerTilingSet> set = CreateTilingSet(&client); + std::unique_ptr<TestablePictureLayerTilingSet> set = + CreateTilingSet(&client); scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -299,10 +324,12 @@ TEST_F(PictureLayerTilingSetTestWithResources, ManyTilings_NotEqual) { TEST(PictureLayerTilingSetTest, TileSizeChange) { FakePictureLayerTilingClient pending_client; FakePictureLayerTilingClient active_client; - scoped_ptr<PictureLayerTilingSet> pending_set = PictureLayerTilingSet::Create( - PENDING_TREE, &pending_client, 1000, 1.f, 1000); - scoped_ptr<PictureLayerTilingSet> active_set = PictureLayerTilingSet::Create( - ACTIVE_TREE, &active_client, 1000, 1.f, 1000); + std::unique_ptr<PictureLayerTilingSet> pending_set = + PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 1000, 1.f, + 1000); + std::unique_ptr<PictureLayerTilingSet> active_set = + PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 1000, 1.f, + 1000); gfx::Size layer_bounds(100, 100); scoped_refptr<FakeRasterSource> raster_source = @@ -406,10 +433,12 @@ TEST(PictureLayerTilingSetTest, TileSizeChange) { TEST(PictureLayerTilingSetTest, MaxContentScale) { FakePictureLayerTilingClient pending_client; FakePictureLayerTilingClient active_client; - scoped_ptr<PictureLayerTilingSet> pending_set = PictureLayerTilingSet::Create( - PENDING_TREE, &pending_client, 1000, 1.f, 1000); - scoped_ptr<PictureLayerTilingSet> active_set = PictureLayerTilingSet::Create( - ACTIVE_TREE, &active_client, 1000, 1.f, 1000); + std::unique_ptr<PictureLayerTilingSet> pending_set = + PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 1000, 1.f, + 1000); + std::unique_ptr<PictureLayerTilingSet> active_set = + PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 1000, 1.f, + 1000); gfx::Size layer_bounds(100, 105); scoped_refptr<FakeRasterSource> raster_source = @@ -456,5 +485,504 @@ TEST(PictureLayerTilingSetTest, MaxContentScale) { EXPECT_EQ(2u, active_set->num_tilings()); } +TEST(PictureLayerTilingSetTest, SkewportLimits) { + FakePictureLayerTilingClient client; + + gfx::Rect viewport(0, 0, 100, 100); + gfx::Size layer_bounds(200, 200); + + client.SetTileSize(gfx::Size(100, 100)); + LayerTreeSettings settings; + settings.skewport_extrapolation_limit_in_screen_pixels = 75; + settings.tiling_interest_area_padding = 1000000; + + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(layer_bounds); + std::unique_ptr<TestablePictureLayerTilingSet> tiling_set = + CreateTilingSetWithSettings(&client, settings); + + EXPECT_FALSE(tiling_set->TilingsNeedUpdate(viewport, 1.0)); + tiling_set->AddTiling(1.f, raster_source); + EXPECT_TRUE(tiling_set->TilingsNeedUpdate(viewport, 1.0)); + + tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true); + + // Move viewport down 50 pixels in 0.5 seconds. + gfx::Rect down_skewport = + tiling_set->ComputeSkewport(gfx::Rect(0, 50, 100, 100), 1.5, 1.f); + + EXPECT_EQ(0, down_skewport.x()); + EXPECT_EQ(50, down_skewport.y()); + EXPECT_EQ(100, down_skewport.width()); + EXPECT_EQ(175, down_skewport.height()); + EXPECT_TRUE(down_skewport.Contains(gfx::Rect(0, 50, 100, 100))); + + // Move viewport down 50 and right 10 pixels. + gfx::Rect down_right_skewport = + tiling_set->ComputeSkewport(gfx::Rect(10, 50, 100, 100), 1.5, 1.f); + + EXPECT_EQ(10, down_right_skewport.x()); + EXPECT_EQ(50, down_right_skewport.y()); + EXPECT_EQ(120, down_right_skewport.width()); + EXPECT_EQ(175, down_right_skewport.height()); + EXPECT_TRUE(down_right_skewport.Contains(gfx::Rect(10, 50, 100, 100))); + + // Move viewport left. + gfx::Rect left_skewport = + tiling_set->ComputeSkewport(gfx::Rect(-50, 0, 100, 100), 1.5, 1.f); + + EXPECT_EQ(-125, left_skewport.x()); + EXPECT_EQ(0, left_skewport.y()); + EXPECT_EQ(175, left_skewport.width()); + EXPECT_EQ(100, left_skewport.height()); + EXPECT_TRUE(left_skewport.Contains(gfx::Rect(-50, 0, 100, 100))); + + // Expand viewport. + gfx::Rect expand_skewport = + tiling_set->ComputeSkewport(gfx::Rect(-50, -50, 200, 200), 1.5, 1.f); + + // x and y moved by -75 (-50 - 75 = -125). + // right side and bottom side moved by 75 [(350 - 125) - (200 - 50) = 75]. + EXPECT_EQ(-125, expand_skewport.x()); + EXPECT_EQ(-125, expand_skewport.y()); + EXPECT_EQ(350, expand_skewport.width()); + EXPECT_EQ(350, expand_skewport.height()); + EXPECT_TRUE(expand_skewport.Contains(gfx::Rect(-50, -50, 200, 200))); + + // Expand the viewport past the limit in all directions. + gfx::Rect big_expand_skewport = + tiling_set->ComputeSkewport(gfx::Rect(-500, -500, 1500, 1500), 1.5, 1.f); + + EXPECT_EQ(-575, big_expand_skewport.x()); + EXPECT_EQ(-575, big_expand_skewport.y()); + EXPECT_EQ(1650, big_expand_skewport.width()); + EXPECT_EQ(1650, big_expand_skewport.height()); + EXPECT_TRUE(big_expand_skewport.Contains(gfx::Rect(-500, -500, 1500, 1500))); + + // Shrink the skewport in all directions. + gfx::Rect shrink_viewport = + tiling_set->ComputeSkewport(gfx::Rect(0, 0, 100, 100), 1.5, 1.f); + EXPECT_EQ(0, shrink_viewport.x()); + EXPECT_EQ(0, shrink_viewport.y()); + EXPECT_EQ(100, shrink_viewport.width()); + EXPECT_EQ(100, shrink_viewport.height()); + + // Move the skewport really far in one direction. + gfx::Rect move_skewport_far = + tiling_set->ComputeSkewport(gfx::Rect(0, 5000, 100, 100), 1.5, 1.f); + EXPECT_EQ(0, move_skewport_far.x()); + EXPECT_EQ(5000, move_skewport_far.y()); + EXPECT_EQ(100, move_skewport_far.width()); + EXPECT_EQ(175, move_skewport_far.height()); + EXPECT_TRUE(move_skewport_far.Contains(gfx::Rect(0, 5000, 100, 100))); +} + +TEST(PictureLayerTilingSetTest, ComputeSkewportExtremeCases) { + FakePictureLayerTilingClient client; + + gfx::Size layer_bounds(200, 200); + client.SetTileSize(gfx::Size(100, 100)); + LayerTreeSettings settings; + settings.tiling_interest_area_padding = 1000000000; + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(layer_bounds); + std::unique_ptr<TestablePictureLayerTilingSet> tiling_set = + CreateTilingSetWithSettings(&client, settings); + tiling_set->AddTiling(1.f, raster_source); + + gfx::Rect viewport1(-1918, 255860, 4010, 2356); + gfx::Rect viewport2(-7088, -91738, 14212, 8350); + gfx::Rect viewport3(-12730024, -158883296, 24607540, 14454512); + double time = 1.0; + tiling_set->UpdateTilePriorities(viewport1, 1.f, time, Occlusion(), true); + time += 0.016; + EXPECT_TRUE( + tiling_set->ComputeSkewport(viewport2, time, 1.f).Contains(viewport2)); + tiling_set->UpdateTilePriorities(viewport2, 1.f, time, Occlusion(), true); + time += 0.016; + EXPECT_TRUE( + tiling_set->ComputeSkewport(viewport3, time, 1.f).Contains(viewport3)); + + // Use a tiling with a large scale, so the viewport times the scale no longer + // fits into integers, and the viewport is not anywhere close to the tiling. + PictureLayerTiling* tiling = tiling_set->AddTiling(1000.f, raster_source); + EXPECT_TRUE(tiling_set->TilingsNeedUpdate(viewport3, time)); + tiling_set->UpdateTilePriorities(viewport3, 1.f, time, Occlusion(), true); + EXPECT_TRUE(tiling->GetCurrentVisibleRectForTesting().IsEmpty()); +} + +TEST(PictureLayerTilingSetTest, ComputeSkewport) { + FakePictureLayerTilingClient client; + + gfx::Rect viewport(0, 0, 100, 100); + gfx::Size layer_bounds(200, 200); + + client.SetTileSize(gfx::Size(100, 100)); + + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(layer_bounds); + std::unique_ptr<TestablePictureLayerTilingSet> tiling_set = + CreateTilingSet(&client); + tiling_set->AddTiling(1.f, raster_source); + + tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true); + + // Move viewport down 50 pixels in 0.5 seconds. + gfx::Rect down_skewport = + tiling_set->ComputeSkewport(gfx::Rect(0, 50, 100, 100), 1.5, 1.f); + + EXPECT_EQ(0, down_skewport.x()); + EXPECT_EQ(50, down_skewport.y()); + EXPECT_EQ(100, down_skewport.width()); + EXPECT_EQ(200, down_skewport.height()); + + // Shrink viewport. + gfx::Rect shrink_skewport = + tiling_set->ComputeSkewport(gfx::Rect(25, 25, 50, 50), 1.5, 1.f); + + EXPECT_EQ(25, shrink_skewport.x()); + EXPECT_EQ(25, shrink_skewport.y()); + EXPECT_EQ(50, shrink_skewport.width()); + EXPECT_EQ(50, shrink_skewport.height()); + + // Move viewport down 50 and right 10 pixels. + gfx::Rect down_right_skewport = + tiling_set->ComputeSkewport(gfx::Rect(10, 50, 100, 100), 1.5, 1.f); + + EXPECT_EQ(10, down_right_skewport.x()); + EXPECT_EQ(50, down_right_skewport.y()); + EXPECT_EQ(120, down_right_skewport.width()); + EXPECT_EQ(200, down_right_skewport.height()); + + // Move viewport left. + gfx::Rect left_skewport = + tiling_set->ComputeSkewport(gfx::Rect(-20, 0, 100, 100), 1.5, 1.f); + + EXPECT_EQ(-60, left_skewport.x()); + EXPECT_EQ(0, left_skewport.y()); + EXPECT_EQ(140, left_skewport.width()); + EXPECT_EQ(100, left_skewport.height()); + + // Expand viewport in 0.2 seconds. + gfx::Rect expanded_skewport = + tiling_set->ComputeSkewport(gfx::Rect(-5, -5, 110, 110), 1.2, 1.f); + + EXPECT_EQ(-30, expanded_skewport.x()); + EXPECT_EQ(-30, expanded_skewport.y()); + EXPECT_EQ(160, expanded_skewport.width()); + EXPECT_EQ(160, expanded_skewport.height()); +} + +TEST(PictureLayerTilingSetTest, SkewportThroughUpdateTilePriorities) { + FakePictureLayerTilingClient client; + + gfx::Rect viewport(0, 0, 100, 100); + gfx::Size layer_bounds(200, 200); + + client.SetTileSize(gfx::Size(100, 100)); + + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(layer_bounds); + std::unique_ptr<TestablePictureLayerTilingSet> tiling_set = + CreateTilingSet(&client); + tiling_set->AddTiling(1.f, raster_source); + + tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true); + + // Move viewport down 50 pixels in 0.5 seconds. + gfx::Rect viewport_50 = gfx::Rect(0, 50, 100, 100); + gfx::Rect skewport_50 = tiling_set->ComputeSkewport(viewport_50, 1.5, 1.f); + + EXPECT_EQ(gfx::Rect(0, 50, 100, 200), skewport_50); + tiling_set->UpdateTilePriorities(viewport_50, 1.f, 1.5, Occlusion(), true); + + gfx::Rect viewport_100 = gfx::Rect(0, 100, 100, 100); + gfx::Rect skewport_100 = tiling_set->ComputeSkewport(viewport_100, 2.0, 1.f); + + EXPECT_EQ(gfx::Rect(0, 100, 100, 200), skewport_100); + tiling_set->UpdateTilePriorities(viewport_100, 1.f, 2.0, Occlusion(), true); + + // Advance time, but not the viewport. + gfx::Rect result = tiling_set->ComputeSkewport(viewport_100, 2.5, 1.f); + // Since the history did advance, we should still get a skewport but a smaller + // one. + EXPECT_EQ(gfx::Rect(0, 100, 100, 150), result); + tiling_set->UpdateTilePriorities(viewport_100, 1.f, 2.5, Occlusion(), true); + + // Advance time again. + result = tiling_set->ComputeSkewport(viewport_100, 3.0, 1.f); + EXPECT_EQ(viewport_100, result); + tiling_set->UpdateTilePriorities(viewport_100, 1.f, 3.0, Occlusion(), true); + + // Ensure we have a skewport. + gfx::Rect viewport_150 = gfx::Rect(0, 150, 100, 100); + gfx::Rect skewport_150 = tiling_set->ComputeSkewport(viewport_150, 3.5, 1.f); + EXPECT_EQ(gfx::Rect(0, 150, 100, 150), skewport_150); + tiling_set->UpdateTilePriorities(viewport_150, 1.f, 3.5, Occlusion(), true); + + // Advance the viewport, but not the time. + gfx::Rect viewport_200 = gfx::Rect(0, 200, 100, 100); + gfx::Rect skewport_200 = tiling_set->ComputeSkewport(viewport_200, 3.5, 1.f); + EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200); + + // Ensure that continued calls with the same value, produce the same skewport. + tiling_set->UpdateTilePriorities(viewport_150, 1.f, 3.5, Occlusion(), true); + EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200); + tiling_set->UpdateTilePriorities(viewport_150, 1.f, 3.5, Occlusion(), true); + EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200); + + tiling_set->UpdateTilePriorities(viewport_200, 1.f, 3.5, Occlusion(), true); + + // This should never happen, but advance the viewport yet again keeping the + // time the same. + gfx::Rect viewport_250 = gfx::Rect(0, 250, 100, 100); + gfx::Rect skewport_250 = tiling_set->ComputeSkewport(viewport_250, 3.5, 1.f); + EXPECT_EQ(viewport_250, skewport_250); + tiling_set->UpdateTilePriorities(viewport_250, 1.f, 3.5, Occlusion(), true); +} + +TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { + FakePictureLayerTilingClient client; + + gfx::Rect viewport(0, 0, 100, 100); + gfx::Size layer_bounds(1500, 1500); + + client.SetTileSize(gfx::Size(10, 10)); + LayerTreeSettings settings; + + // Tiling at 0.25 scale: this should create 47x47 tiles of size 10x10. + // The reason is that each tile has a one pixel border, so tile at (1, 2) + // for instance begins at (8, 16) pixels. So tile at (46, 46) will begin at + // (368, 368) and extend to the end of 1500 * 0.25 = 375 edge of the + // tiling. + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(layer_bounds); + std::unique_ptr<TestablePictureLayerTilingSet> tiling_set = + CreateTilingSet(&client); + auto* tiling = tiling_set->AddTiling(0.25f, raster_source); + tiling->set_resolution(HIGH_RESOLUTION); + gfx::Rect viewport_in_content_space = + gfx::ScaleToEnclosedRect(viewport, 0.25f); + + tiling_set->UpdateTilePriorities(viewport, 1.f, 1.0, Occlusion(), true); + auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); + + // Compute the soon border. + gfx::Rect soon_border_rect_in_content_space = + tiling_set->ComputeSoonBorderRect(viewport, 1.f); + soon_border_rect_in_content_space = + gfx::ScaleToEnclosedRect(soon_border_rect_in_content_space, 0.25f); + + // Sanity checks. + for (int i = 0; i < 47; ++i) { + for (int j = 0; j < 47; ++j) { + EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j; + } + } + for (int i = 0; i < 47; ++i) { + EXPECT_FALSE(tiling->TileAt(i, 47)) << "i: " << i; + EXPECT_FALSE(tiling->TileAt(47, i)) << "i: " << i; + } + + // No movement in the viewport implies that tiles will either be NOW + // or EVENTUALLY, with the exception of tiles that are between 0 and 312 + // pixels away from the viewport, which will be in the SOON bin. + bool have_now = false; + bool have_eventually = false; + bool have_soon = false; + for (int i = 0; i < 47; ++i) { + for (int j = 0; j < 47; ++j) { + Tile* tile = tiling->TileAt(i, j); + PrioritizedTile prioritized_tile = prioritized_tiles[tile]; + TilePriority priority = prioritized_tile.priority(); + + gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j); + if (viewport_in_content_space.Intersects(tile_rect)) { + EXPECT_EQ(TilePriority::NOW, priority.priority_bin); + EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); + have_now = true; + } else if (soon_border_rect_in_content_space.Intersects(tile_rect)) { + EXPECT_EQ(TilePriority::SOON, priority.priority_bin); + have_soon = true; + } else { + EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin); + EXPECT_GT(priority.distance_to_visible, 0.f); + have_eventually = true; + } + } + } + + EXPECT_TRUE(have_now); + EXPECT_TRUE(have_soon); + EXPECT_TRUE(have_eventually); + + // Spot check some distances. + // Tile at 5, 1 should begin at 41x9 in content space (without borders), + // so the distance to a viewport that ends at 25x25 in content space + // should be 17 (41 - 25 + 1). In layer space, then that should be + // 17 / 0.25 = 68 pixels. + + // We can verify that the content rect (with borders) is one pixel off + // 41,9 8x8 on all sides. + EXPECT_EQ(tiling->TileAt(5, 1)->content_rect().ToString(), "40,8 10x10"); + + TilePriority priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); + EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); + EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); + EXPECT_FLOAT_EQ(40.f, priority.distance_to_visible); + + // Move the viewport down 40 pixels. + viewport = gfx::Rect(0, 40, 100, 100); + viewport_in_content_space = gfx::ScaleToEnclosedRect(viewport, 0.25f); + gfx::Rect skewport_in_content_space = + tiling_set->ComputeSkewport(viewport, 2.0, 1.f); + skewport_in_content_space = + gfx::ScaleToEnclosedRect(skewport_in_content_space, 0.25f); + + // Compute the soon border. + soon_border_rect_in_content_space = + tiling_set->ComputeSoonBorderRect(viewport, 1.f); + soon_border_rect_in_content_space = + gfx::ScaleToEnclosedRect(soon_border_rect_in_content_space, 0.25f); + + EXPECT_EQ(0, skewport_in_content_space.x()); + EXPECT_EQ(10, skewport_in_content_space.y()); + EXPECT_EQ(25, skewport_in_content_space.width()); + EXPECT_EQ(35, skewport_in_content_space.height()); + + EXPECT_TRUE(tiling_set->TilingsNeedUpdate(viewport, 2.0)); + tiling_set->UpdateTilePriorities(viewport, 1.f, 2.0, Occlusion(), true); + prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); + + have_now = false; + have_eventually = false; + have_soon = false; + + // Viewport moved, so we expect to find some NOW tiles, some SOON tiles and + // some EVENTUALLY tiles. + for (int i = 0; i < 47; ++i) { + for (int j = 0; j < 47; ++j) { + Tile* tile = tiling->TileAt(i, j); + TilePriority priority = prioritized_tiles[tile].priority(); + + gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j); + if (viewport_in_content_space.Intersects(tile_rect)) { + EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i + << " j: " << j; + EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i + << " j: " << j; + have_now = true; + } else if (skewport_in_content_space.Intersects(tile_rect) || + soon_border_rect_in_content_space.Intersects(tile_rect)) { + EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i + << " j: " << j; + EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i + << " j: " << j; + have_soon = true; + } else { + EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin) + << "i: " << i << " j: " << j; + EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i + << " j: " << j; + have_eventually = true; + } + } + } + + EXPECT_TRUE(have_now); + EXPECT_TRUE(have_soon); + EXPECT_TRUE(have_eventually); + + priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); + EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); + EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); + EXPECT_FLOAT_EQ(4.f, priority.distance_to_visible); + + // Change the underlying layer scale. + tiling_set->UpdateTilePriorities(viewport, 2.0f, 3.0, Occlusion(), true); + prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); + + priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); + EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); + EXPECT_FLOAT_EQ(56.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); + EXPECT_FLOAT_EQ(8.f, priority.distance_to_visible); + + // Test additional scales. + tiling = tiling_set->AddTiling(0.2f, raster_source); + tiling->set_resolution(HIGH_RESOLUTION); + tiling_set->UpdateTilePriorities(viewport, 1.0f, 4.0, Occlusion(), true); + prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); + + priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); + EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); + EXPECT_FLOAT_EQ(70.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); + EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible); + + tiling_set->UpdateTilePriorities(viewport, 0.5f, 5.0, Occlusion(), true); + prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); + + priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); + EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); + EXPECT_FLOAT_EQ(35.f, priority.distance_to_visible); + + priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); + EXPECT_FLOAT_EQ(30.f, priority.distance_to_visible); +} + +TEST(PictureLayerTilingTest, InvalidateAfterComputeTilePriorityRects) { + FakePictureLayerTilingClient pending_client; + pending_client.SetTileSize(gfx::Size(100, 100)); + + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(gfx::Size(100, 100)); + std::unique_ptr<TestablePictureLayerTilingSet> tiling_set = + CreateTilingSet(&pending_client); + auto* pending_tiling = tiling_set->AddTiling(1.f, raster_source); + pending_tiling->set_resolution(HIGH_RESOLUTION); + + // Ensure that we can compute tile priority rects, invalidate, and compute the + // rects again. It is important that the second compute tile priority rects + // return true, indicating that things have changed (since invalidation has + // changed things). This causes PrepareTiles to be properly scheduled. If the + // second ComputeTilePriorityRects returns false, then we assume that + // PrepareTiles isn't needed and we signal that we're ready to draw + // immediately, which can cause visual glitches. + // + // This can happen we if we process an impl frame deadline before processing a + // commit. That is, when we draw we ComputeTilePriorityRects. If we process + // the commit afterwards, it would use the same timestamp and sometimes would + // use the same viewport to compute tile priority rects again. + double time = 1.; + gfx::Rect viewport(0, 0, 100, 100); + EXPECT_TRUE( + tiling_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true)); + EXPECT_FALSE( + tiling_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true)); + + // This will invalidate tilings. + tiling_set->UpdateRasterSourceDueToLCDChange(raster_source, Region()); + + EXPECT_TRUE( + tiling_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true)); +} + } // namespace } // namespace cc diff --git a/chromium/cc/tiles/picture_layer_tiling_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_unittest.cc index bb4de4e6fec..19e5f27896b 100644 --- a/chromium/cc/tiles/picture_layer_tiling_unittest.cc +++ b/chromium/cc/tiles/picture_layer_tiling_unittest.cc @@ -2,12 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/tiles/picture_layer_tiling.h" + #include <stddef.h> #include <limits> #include <set> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/base/math_util.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" @@ -15,7 +18,6 @@ #include "cc/test/fake_raster_source.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/tiles/picture_layer_tiling_set.h" #include "cc/trees/layer_tree_settings.h" #include "testing/gtest/include/gtest/gtest.h" @@ -43,22 +45,21 @@ class TestablePictureLayerTiling : public PictureLayerTiling { using PictureLayerTiling::SetLiveTilesRect; using PictureLayerTiling::TileAt; - static scoped_ptr<TestablePictureLayerTiling> Create( + static std::unique_ptr<TestablePictureLayerTiling> Create( WhichTree tree, float contents_scale, scoped_refptr<RasterSource> raster_source, PictureLayerTilingClient* client, const LayerTreeSettings& settings) { - return make_scoped_ptr(new TestablePictureLayerTiling( + return base::WrapUnique(new TestablePictureLayerTiling( tree, contents_scale, raster_source, client, settings.tiling_interest_area_padding, settings.skewport_target_time_in_seconds, - settings.skewport_extrapolation_limit_in_content_pixels)); + settings.skewport_extrapolation_limit_in_screen_pixels)); } gfx::Rect live_tiles_rect() const { return live_tiles_rect_; } - using PictureLayerTiling::ComputeSkewport; using PictureLayerTiling::RemoveTileAt; using PictureLayerTiling::RemoveTilesInRegion; @@ -70,13 +71,7 @@ class TestablePictureLayerTiling : public PictureLayerTiling { size_t tiling_interest_area_padding, float skewport_target_time, int skewport_extrapolation_limit) - : PictureLayerTiling(tree, - contents_scale, - raster_source, - client, - tiling_interest_area_padding, - skewport_target_time, - skewport_extrapolation_limit) {} + : PictureLayerTiling(tree, contents_scale, raster_source, client) {} }; class PictureLayerTilingIteratorTest : public testing::Test { @@ -197,7 +192,7 @@ class PictureLayerTilingIteratorTest : public testing::Test { protected: FakePictureLayerTilingClient client_; - scoped_ptr<TestablePictureLayerTiling> tiling_; + std::unique_ptr<TestablePictureLayerTiling> tiling_; private: DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest); @@ -470,6 +465,46 @@ TEST_F(PictureLayerTilingIteratorTest, RemoveOutsideLayerKeepsTiles) { EXPECT_TRUE(tiling_->TileAt(0, 0)); } +TEST_F(PictureLayerTilingIteratorTest, CreateTileJustCoverBorderUp) { + float content_scale = 1.2000000476837158f; + gfx::Size tile_size(512, 512); + gfx::Size layer_size(1440, 4560); + FakePictureLayerTilingClient active_client; + + active_client.SetTileSize(tile_size); + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(layer_size); + std::unique_ptr<TestablePictureLayerTiling> active_tiling = + TestablePictureLayerTiling::Create(ACTIVE_TREE, content_scale, + raster_source, &active_client, + LayerTreeSettings()); + active_tiling->set_resolution(HIGH_RESOLUTION); + + gfx::Rect invalid_rect(0, 750, 220, 100); + Initialize(tile_size, content_scale, layer_size); + client_.set_twin_tiling(active_tiling.get()); + client_.set_invalidation(invalid_rect); + SetLiveRectAndVerifyTiles(gfx::Rect(layer_size)); + // When it creates a tile in pending tree, verify that tiles are invalidated + // even if only their border pixels intersect the invalidation rect + EXPECT_TRUE(tiling_->TileAt(0, 1)); + gfx::Rect scaled_invalid_rect = + gfx::ScaleToEnclosingRect(invalid_rect, content_scale); + EXPECT_FALSE(scaled_invalid_rect.Intersects( + tiling_->TilingDataForTesting().TileBounds(0, 2))); + EXPECT_TRUE(scaled_invalid_rect.Intersects( + tiling_->TilingDataForTesting().TileBoundsWithBorder(0, 2))); + EXPECT_TRUE(tiling_->TileAt(0, 2)); + + bool recreate_tiles = false; + active_tiling->RemoveTilesInRegion(invalid_rect, recreate_tiles); + // Even though a tile just touch border area of invalid region, verify that + // RemoveTilesInRegion behaves the same as SetLiveRectAndVerifyTiles with + // respect to the tiles that it invalidates + EXPECT_FALSE(active_tiling->TileAt(0, 1)); + EXPECT_FALSE(active_tiling->TileAt(0, 2)); +} + TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) { Initialize(gfx::Size(100, 100), 1.f, gfx::Size(1099, 801)); SetLiveRectAndVerifyTiles(gfx::Rect(100, 100)); @@ -571,458 +606,6 @@ TEST_F(PictureLayerTilingIteratorTest, NonContainedDestRect) { VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, 100, 2000, 100)); } -TEST(PictureLayerTilingTest, SkewportLimits) { - FakePictureLayerTilingClient client; - - gfx::Rect viewport(0, 0, 100, 100); - gfx::Size layer_bounds(200, 200); - - client.SetTileSize(gfx::Size(100, 100)); - LayerTreeSettings settings; - settings.skewport_extrapolation_limit_in_content_pixels = 75; - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, settings); - - tiling->ComputeTilePriorityRects(viewport, 1.f, 1.0, Occlusion()); - - // Move viewport down 50 pixels in 0.5 seconds. - gfx::Rect down_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100)); - - EXPECT_EQ(0, down_skewport.x()); - EXPECT_EQ(50, down_skewport.y()); - EXPECT_EQ(100, down_skewport.width()); - EXPECT_EQ(175, down_skewport.height()); - EXPECT_TRUE(down_skewport.Contains(gfx::Rect(0, 50, 100, 100))); - - // Move viewport down 50 and right 10 pixels. - gfx::Rect down_right_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100)); - - EXPECT_EQ(10, down_right_skewport.x()); - EXPECT_EQ(50, down_right_skewport.y()); - EXPECT_EQ(120, down_right_skewport.width()); - EXPECT_EQ(175, down_right_skewport.height()); - EXPECT_TRUE(down_right_skewport.Contains(gfx::Rect(10, 50, 100, 100))); - - // Move viewport left. - gfx::Rect left_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(-50, 0, 100, 100)); - - EXPECT_EQ(-125, left_skewport.x()); - EXPECT_EQ(0, left_skewport.y()); - EXPECT_EQ(175, left_skewport.width()); - EXPECT_EQ(100, left_skewport.height()); - EXPECT_TRUE(left_skewport.Contains(gfx::Rect(-50, 0, 100, 100))); - - // Expand viewport. - gfx::Rect expand_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(-50, -50, 200, 200)); - - // x and y moved by -75 (-50 - 75 = -125). - // right side and bottom side moved by 75 [(350 - 125) - (200 - 50) = 75]. - EXPECT_EQ(-125, expand_skewport.x()); - EXPECT_EQ(-125, expand_skewport.y()); - EXPECT_EQ(350, expand_skewport.width()); - EXPECT_EQ(350, expand_skewport.height()); - EXPECT_TRUE(expand_skewport.Contains(gfx::Rect(-50, -50, 200, 200))); - - // Expand the viewport past the limit in all directions. - gfx::Rect big_expand_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(-500, -500, 1500, 1500)); - - EXPECT_EQ(-575, big_expand_skewport.x()); - EXPECT_EQ(-575, big_expand_skewport.y()); - EXPECT_EQ(1650, big_expand_skewport.width()); - EXPECT_EQ(1650, big_expand_skewport.height()); - EXPECT_TRUE(big_expand_skewport.Contains(gfx::Rect(-500, -500, 1500, 1500))); - - // Shrink the skewport in all directions. - gfx::Rect shrink_viewport = - tiling->ComputeSkewport(1.5, gfx::Rect(0, 0, 100, 100)); - EXPECT_EQ(0, shrink_viewport.x()); - EXPECT_EQ(0, shrink_viewport.y()); - EXPECT_EQ(100, shrink_viewport.width()); - EXPECT_EQ(100, shrink_viewport.height()); - - // Move the skewport really far in one direction. - gfx::Rect move_skewport_far = - tiling->ComputeSkewport(1.5, gfx::Rect(0, 5000, 100, 100)); - EXPECT_EQ(0, move_skewport_far.x()); - EXPECT_EQ(5000, move_skewport_far.y()); - EXPECT_EQ(100, move_skewport_far.width()); - EXPECT_EQ(175, move_skewport_far.height()); - EXPECT_TRUE(move_skewport_far.Contains(gfx::Rect(0, 5000, 100, 100))); -} - -TEST(PictureLayerTilingTest, ComputeSkewportExtremeCases) { - FakePictureLayerTilingClient client; - - gfx::Size layer_bounds(200, 200); - client.SetTileSize(gfx::Size(100, 100)); - LayerTreeSettings settings; - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, settings); - - gfx::Rect viewport1(-1918, 255860, 4010, 2356); - gfx::Rect viewport2(-7088, -91738, 14212, 8350); - gfx::Rect viewport3(-12730024, -158883296, 24607540, 14454512); - double time = 1.0; - tiling->ComputeTilePriorityRects(viewport1, 1.f, time, Occlusion()); - time += 0.016; - EXPECT_TRUE(tiling->ComputeSkewport(time, viewport2).Contains(viewport2)); - tiling->ComputeTilePriorityRects(viewport2, 1.f, time, Occlusion()); - time += 0.016; - EXPECT_TRUE(tiling->ComputeSkewport(time, viewport3).Contains(viewport3)); - - // Use a tiling with a large scale, so the viewport times the scale no longer - // fits into integers, and the viewport is not anywhere close to the tiling. - tiling = TestablePictureLayerTiling::Create(ACTIVE_TREE, 1000.0f, - raster_source, &client, settings); - tiling->ComputeTilePriorityRects(viewport3, 1.f, time, Occlusion()); - EXPECT_EQ(gfx::Rect(), tiling->GetCurrentVisibleRectForTesting()); -} - -TEST(PictureLayerTilingTest, ComputeSkewport) { - FakePictureLayerTilingClient client; - - gfx::Rect viewport(0, 0, 100, 100); - gfx::Size layer_bounds(200, 200); - - client.SetTileSize(gfx::Size(100, 100)); - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, LayerTreeSettings()); - - tiling->ComputeTilePriorityRects(viewport, 1.f, 1.0, Occlusion()); - - // Move viewport down 50 pixels in 0.5 seconds. - gfx::Rect down_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100)); - - EXPECT_EQ(0, down_skewport.x()); - EXPECT_EQ(50, down_skewport.y()); - EXPECT_EQ(100, down_skewport.width()); - EXPECT_EQ(200, down_skewport.height()); - - // Shrink viewport. - gfx::Rect shrink_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(25, 25, 50, 50)); - - EXPECT_EQ(25, shrink_skewport.x()); - EXPECT_EQ(25, shrink_skewport.y()); - EXPECT_EQ(50, shrink_skewport.width()); - EXPECT_EQ(50, shrink_skewport.height()); - - // Move viewport down 50 and right 10 pixels. - gfx::Rect down_right_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100)); - - EXPECT_EQ(10, down_right_skewport.x()); - EXPECT_EQ(50, down_right_skewport.y()); - EXPECT_EQ(120, down_right_skewport.width()); - EXPECT_EQ(200, down_right_skewport.height()); - - // Move viewport left. - gfx::Rect left_skewport = - tiling->ComputeSkewport(1.5, gfx::Rect(-20, 0, 100, 100)); - - EXPECT_EQ(-60, left_skewport.x()); - EXPECT_EQ(0, left_skewport.y()); - EXPECT_EQ(140, left_skewport.width()); - EXPECT_EQ(100, left_skewport.height()); - - // Expand viewport in 0.2 seconds. - gfx::Rect expanded_skewport = - tiling->ComputeSkewport(1.2, gfx::Rect(-5, -5, 110, 110)); - - EXPECT_EQ(-30, expanded_skewport.x()); - EXPECT_EQ(-30, expanded_skewport.y()); - EXPECT_EQ(160, expanded_skewport.width()); - EXPECT_EQ(160, expanded_skewport.height()); -} - -TEST(PictureLayerTilingTest, SkewportThroughUpdateTilePriorities) { - FakePictureLayerTilingClient client; - - gfx::Rect viewport(0, 0, 100, 100); - gfx::Size layer_bounds(200, 200); - - client.SetTileSize(gfx::Size(100, 100)); - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, LayerTreeSettings()); - - tiling->ComputeTilePriorityRects(viewport, 1.f, 1.0, Occlusion()); - - // Move viewport down 50 pixels in 0.5 seconds. - gfx::Rect viewport_50 = gfx::Rect(0, 50, 100, 100); - gfx::Rect skewport_50 = tiling->ComputeSkewport(1.5, viewport_50); - - EXPECT_EQ(gfx::Rect(0, 50, 100, 200), skewport_50); - tiling->ComputeTilePriorityRects(viewport_50, 1.f, 1.5, Occlusion()); - - gfx::Rect viewport_100 = gfx::Rect(0, 100, 100, 100); - gfx::Rect skewport_100 = tiling->ComputeSkewport(2.0, viewport_100); - - EXPECT_EQ(gfx::Rect(0, 100, 100, 200), skewport_100); - tiling->ComputeTilePriorityRects(viewport_100, 1.f, 2.0, Occlusion()); - - // Advance time, but not the viewport. - gfx::Rect result = tiling->ComputeSkewport(2.5, viewport_100); - // Since the history did advance, we should still get a skewport but a smaller - // one. - EXPECT_EQ(gfx::Rect(0, 100, 100, 150), result); - tiling->ComputeTilePriorityRects(viewport_100, 1.f, 2.5, Occlusion()); - - // Advance time again. - result = tiling->ComputeSkewport(3.0, viewport_100); - EXPECT_EQ(viewport_100, result); - tiling->ComputeTilePriorityRects(viewport_100, 1.f, 3.0, Occlusion()); - - // Ensure we have a skewport. - gfx::Rect viewport_150 = gfx::Rect(0, 150, 100, 100); - gfx::Rect skewport_150 = tiling->ComputeSkewport(3.5, viewport_150); - EXPECT_EQ(gfx::Rect(0, 150, 100, 150), skewport_150); - tiling->ComputeTilePriorityRects(viewport_150, 1.f, 3.5, Occlusion()); - - // Advance the viewport, but not the time. - gfx::Rect viewport_200 = gfx::Rect(0, 200, 100, 100); - gfx::Rect skewport_200 = tiling->ComputeSkewport(3.5, viewport_200); - EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200); - - // Ensure that continued calls with the same value, produce the same skewport. - tiling->ComputeTilePriorityRects(viewport_150, 1.f, 3.5, Occlusion()); - EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200); - tiling->ComputeTilePriorityRects(viewport_150, 1.f, 3.5, Occlusion()); - EXPECT_EQ(gfx::Rect(0, 200, 100, 300), skewport_200); - - tiling->ComputeTilePriorityRects(viewport_200, 1.f, 3.5, Occlusion()); - - // This should never happen, but advance the viewport yet again keeping the - // time the same. - gfx::Rect viewport_250 = gfx::Rect(0, 250, 100, 100); - gfx::Rect skewport_250 = tiling->ComputeSkewport(3.5, viewport_250); - EXPECT_EQ(viewport_250, skewport_250); - tiling->ComputeTilePriorityRects(viewport_250, 1.f, 3.5, Occlusion()); -} - -TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { - FakePictureLayerTilingClient client; - - gfx::Rect viewport(0, 0, 100, 100); - gfx::Size layer_bounds(1500, 1500); - - client.SetTileSize(gfx::Size(10, 10)); - LayerTreeSettings settings; - - // Tiling at 0.25 scale: this should create 47x47 tiles of size 10x10. - // The reason is that each tile has a one pixel border, so tile at (1, 2) - // for instance begins at (8, 16) pixels. So tile at (46, 46) will begin at - // (368, 368) and extend to the end of 1500 * 0.25 = 375 edge of the - // tiling. - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 0.25f, raster_source, - &client, settings); - tiling->set_resolution(HIGH_RESOLUTION); - gfx::Rect viewport_in_content_space = - gfx::ScaleToEnclosedRect(viewport, 0.25f); - - tiling->ComputeTilePriorityRects(viewport, 1.f, 1.0, Occlusion()); - auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - // Compute the soon border. - float inset = PictureLayerTiling::CalculateSoonBorderDistance( - viewport_in_content_space, 1.0f / 0.25f); - gfx::Rect soon_rect_in_content_space = viewport_in_content_space; - soon_rect_in_content_space.Inset(-inset, -inset); - - // Sanity checks. - for (int i = 0; i < 47; ++i) { - for (int j = 0; j < 47; ++j) { - EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j; - } - } - for (int i = 0; i < 47; ++i) { - EXPECT_FALSE(tiling->TileAt(i, 47)) << "i: " << i; - EXPECT_FALSE(tiling->TileAt(47, i)) << "i: " << i; - } - - // No movement in the viewport implies that tiles will either be NOW - // or EVENTUALLY, with the exception of tiles that are between 0 and 312 - // pixels away from the viewport, which will be in the SOON bin. - bool have_now = false; - bool have_eventually = false; - bool have_soon = false; - for (int i = 0; i < 47; ++i) { - for (int j = 0; j < 47; ++j) { - Tile* tile = tiling->TileAt(i, j); - PrioritizedTile prioritized_tile = prioritized_tiles[tile]; - TilePriority priority = prioritized_tile.priority(); - - gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j); - if (viewport_in_content_space.Intersects(tile_rect)) { - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); - have_now = true; - } else if (soon_rect_in_content_space.Intersects(tile_rect)) { - EXPECT_EQ(TilePriority::SOON, priority.priority_bin); - have_soon = true; - } else { - EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin); - EXPECT_GT(priority.distance_to_visible, 0.f); - have_eventually = true; - } - } - } - - EXPECT_TRUE(have_now); - EXPECT_TRUE(have_soon); - EXPECT_TRUE(have_eventually); - - // Spot check some distances. - // Tile at 5, 1 should begin at 41x9 in content space (without borders), - // so the distance to a viewport that ends at 25x25 in content space - // should be 17 (41 - 25 + 1). In layer space, then that should be - // 17 / 0.25 = 68 pixels. - - // We can verify that the content rect (with borders) is one pixel off - // 41,9 8x8 on all sides. - EXPECT_EQ(tiling->TileAt(5, 1)->content_rect().ToString(), "40,8 10x10"); - - TilePriority priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); - EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); - EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); - EXPECT_FLOAT_EQ(40.f, priority.distance_to_visible); - - // Move the viewport down 40 pixels. - viewport = gfx::Rect(0, 40, 100, 100); - viewport_in_content_space = gfx::ScaleToEnclosedRect(viewport, 0.25f); - gfx::Rect skewport = tiling->ComputeSkewport(2.0, viewport_in_content_space); - - // Compute the soon border. - inset = PictureLayerTiling::CalculateSoonBorderDistance( - viewport_in_content_space, 1.0f / 0.25f); - soon_rect_in_content_space = viewport_in_content_space; - soon_rect_in_content_space.Inset(-inset, -inset); - - EXPECT_EQ(0, skewport.x()); - EXPECT_EQ(10, skewport.y()); - EXPECT_EQ(25, skewport.width()); - EXPECT_EQ(35, skewport.height()); - - tiling->ComputeTilePriorityRects(viewport, 1.f, 2.0, Occlusion()); - prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - have_now = false; - have_eventually = false; - have_soon = false; - - // Viewport moved, so we expect to find some NOW tiles, some SOON tiles and - // some EVENTUALLY tiles. - for (int i = 0; i < 47; ++i) { - for (int j = 0; j < 47; ++j) { - Tile* tile = tiling->TileAt(i, j); - TilePriority priority = prioritized_tiles[tile].priority(); - - gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j); - if (viewport_in_content_space.Intersects(tile_rect)) { - EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i - << " j: " << j; - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i - << " j: " << j; - have_now = true; - } else if (skewport.Intersects(tile_rect) || - soon_rect_in_content_space.Intersects(tile_rect)) { - EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i - << " j: " << j; - EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i - << " j: " << j; - have_soon = true; - } else { - EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin) - << "i: " << i << " j: " << j; - EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i - << " j: " << j; - have_eventually = true; - } - } - } - - EXPECT_TRUE(have_now); - EXPECT_TRUE(have_soon); - EXPECT_TRUE(have_eventually); - - priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); - EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); - EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); - EXPECT_FLOAT_EQ(4.f, priority.distance_to_visible); - - // Change the underlying layer scale. - tiling->ComputeTilePriorityRects(viewport, 2.0f, 3.0, Occlusion()); - prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); - EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); - EXPECT_FLOAT_EQ(56.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); - EXPECT_FLOAT_EQ(8.f, priority.distance_to_visible); - - // Test additional scales. - tiling = TestablePictureLayerTiling::Create(ACTIVE_TREE, 0.2f, raster_source, - &client, LayerTreeSettings()); - tiling->set_resolution(HIGH_RESOLUTION); - tiling->ComputeTilePriorityRects(viewport, 1.0f, 4.0, Occlusion()); - prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); - EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); - EXPECT_FLOAT_EQ(70.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); - EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible); - - tiling->ComputeTilePriorityRects(viewport, 0.5f, 5.0, Occlusion()); - prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - priority = prioritized_tiles[tiling->TileAt(5, 1)].priority(); - EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(2, 5)].priority(); - EXPECT_FLOAT_EQ(35.f, priority.distance_to_visible); - - priority = prioritized_tiles[tiling->TileAt(3, 4)].priority(); - EXPECT_FLOAT_EQ(30.f, priority.distance_to_visible); -} - static void TileExists(bool exists, Tile* tile, const gfx::Rect& geometry_rect) { EXPECT_EQ(exists, tile != NULL) << geometry_rect.ToString(); @@ -1035,17 +618,17 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) { VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); tiling_->ComputeTilePriorityRects( - gfx::Rect(layer_bounds), // visible content rect + gfx::Rect(layer_bounds), // visible rect + gfx::Rect(layer_bounds), // skewport + gfx::Rect(layer_bounds), // soon border rect + gfx::Rect(layer_bounds), // eventually rect 1.f, // current contents scale - 1.0, // current frame time Occlusion()); VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); // Make the viewport rect empty. All tiles are killed and become zombies. - tiling_->ComputeTilePriorityRects(gfx::Rect(), // visible content rect - 1.f, // current contents scale - 2.0, // current frame time - Occlusion()); + tiling_->ComputeTilePriorityRects(gfx::Rect(), gfx::Rect(), gfx::Rect(), + gfx::Rect(), 1.f, Occlusion()); VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); } @@ -1058,17 +641,17 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) { gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000); tiling_->ComputeTilePriorityRects( - gfx::Rect(layer_bounds), // visible content rect + gfx::Rect(layer_bounds), // visible rect + gfx::Rect(layer_bounds), // skewport + gfx::Rect(layer_bounds), // soon border rect + gfx::Rect(layer_bounds), // eventually rect 1.f, // current contents scale - 1.0, // current frame time Occlusion()); VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); - // If the visible content rect is empty, it should still have live tiles. - tiling_->ComputeTilePriorityRects(giant_rect, // visible content rect - 1.f, // current contents scale - 2.0, // current frame time - Occlusion()); + // If the visible content rect is huge, we should still have live tiles. + tiling_->ComputeTilePriorityRects(giant_rect, giant_rect, giant_rect, + giant_rect, 1.f, Occlusion()); VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); } @@ -1083,10 +666,12 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) { gfx::Rect viewport_rect(1100, 0, 1000, 1000); EXPECT_FALSE(viewport_rect.Intersects(gfx::Rect(layer_bounds))); - tiling_->ComputeTilePriorityRects(viewport_rect, // visible content rect - 1.f, // current contents scale - 1.0, // current frame time - Occlusion()); + LayerTreeSettings settings; + gfx::Rect eventually_rect = viewport_rect; + eventually_rect.Inset(-settings.tiling_interest_area_padding, + -settings.tiling_interest_area_padding); + tiling_->ComputeTilePriorityRects(viewport_rect, viewport_rect, viewport_rect, + eventually_rect, 1.f, Occlusion()); VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true)); } @@ -1118,9 +703,11 @@ TEST_F(PictureLayerTilingIteratorTest, gfx::Rect visible_rect(8000, 8000, 50, 50); - tiling_->ComputeTilePriorityRects(visible_rect, // visible content rect + tiling_->ComputeTilePriorityRects(visible_rect, // visible rect + visible_rect, // skewport + visible_rect, // soon border rect + visible_rect, // eventually rect 1.f, // current contents scale - 1.0, // current frame time Occlusion()); VerifyTiles(1.f, gfx::Rect(layer_bounds), @@ -1137,7 +724,6 @@ TEST(ComputeTilePriorityRectsTest, VisibleTiles) { gfx::Size current_layer_bounds(200, 200); float current_layer_contents_scale = 1.f; gfx::Transform current_screen_transform; - double current_frame_time_in_seconds = 1.0; gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( current_screen_transform, device_viewport); @@ -1146,14 +732,18 @@ TEST(ComputeTilePriorityRectsTest, VisibleTiles) { scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(current_layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = + std::unique_ptr<TestablePictureLayerTiling> tiling = TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, &client, LayerTreeSettings()); tiling->set_resolution(HIGH_RESOLUTION); - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); + LayerTreeSettings settings; + gfx::Rect eventually_rect = viewport_in_layer_space; + eventually_rect.Inset(-settings.tiling_interest_area_padding, + -settings.tiling_interest_area_padding); + tiling->ComputeTilePriorityRects( + viewport_in_layer_space, viewport_in_layer_space, viewport_in_layer_space, + eventually_rect, current_layer_contents_scale, Occlusion()); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); ASSERT_TRUE(tiling->TileAt(0, 0)); @@ -1189,7 +779,6 @@ TEST(ComputeTilePriorityRectsTest, OffscreenTiles) { float current_layer_contents_scale = 1.f; gfx::Transform last_screen_transform; gfx::Transform current_screen_transform; - double current_frame_time_in_seconds = 1.0; current_screen_transform.Translate(850, 0); last_screen_transform = current_screen_transform; @@ -1201,14 +790,18 @@ TEST(ComputeTilePriorityRectsTest, OffscreenTiles) { scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(current_layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = + std::unique_ptr<TestablePictureLayerTiling> tiling = TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, &client, LayerTreeSettings()); tiling->set_resolution(HIGH_RESOLUTION); - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); + LayerTreeSettings settings; + gfx::Rect eventually_rect = viewport_in_layer_space; + eventually_rect.Inset(-settings.tiling_interest_area_padding, + -settings.tiling_interest_area_padding); + tiling->ComputeTilePriorityRects( + viewport_in_layer_space, viewport_in_layer_space, viewport_in_layer_space, + eventually_rect, current_layer_contents_scale, Occlusion()); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); ASSERT_TRUE(tiling->TileAt(0, 0)); @@ -1254,7 +847,6 @@ TEST(ComputeTilePriorityRectsTest, PartiallyOffscreenLayer) { float current_layer_contents_scale = 1.f; gfx::Transform last_screen_transform; gfx::Transform current_screen_transform; - double current_frame_time_in_seconds = 1.0; current_screen_transform.Translate(705, 505); last_screen_transform = current_screen_transform; @@ -1266,251 +858,18 @@ TEST(ComputeTilePriorityRectsTest, PartiallyOffscreenLayer) { scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(current_layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, LayerTreeSettings()); - tiling->set_resolution(HIGH_RESOLUTION); - - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); - auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - ASSERT_TRUE(tiling->TileAt(0, 0)); - ASSERT_TRUE(tiling->TileAt(0, 1)); - ASSERT_TRUE(tiling->TileAt(1, 0)); - ASSERT_TRUE(tiling->TileAt(1, 1)); - - TilePriority priority = prioritized_tiles[tiling->TileAt(0, 0)].priority(); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); - EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(0, 1)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 0)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 1)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); -} - -TEST(ComputeTilePriorityRectsTest, PartiallyOffscreenRotatedLayer) { - // Each tile of a layer may be affected differently by a transform; Check - // that ComputeTilePriorityRects correctly accounts for the transform between - // layer space and screen space. - FakePictureLayerTilingClient client; - - gfx::Size device_viewport(800, 600); - gfx::Size last_layer_bounds(200, 200); - gfx::Size current_layer_bounds(200, 200); - float current_layer_contents_scale = 1.f; - gfx::Transform last_screen_transform; - gfx::Transform current_screen_transform; - double current_frame_time_in_seconds = 1.0; - - // A diagonally rotated layer that is partially off the bottom of the screen. - // In this configuration, only the top-left tile would be visible. - current_screen_transform.Translate(600, 750); - current_screen_transform.RotateAboutZAxis(45); - last_screen_transform = current_screen_transform; - - gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( - current_screen_transform, device_viewport); - - client.SetTileSize(gfx::Size(100, 100)); - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(current_layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, LayerTreeSettings()); - tiling->set_resolution(HIGH_RESOLUTION); - - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); - auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - ASSERT_TRUE(tiling->TileAt(0, 0)); - ASSERT_TRUE(tiling->TileAt(0, 1)); - ASSERT_TRUE(tiling->TileAt(1, 0)); - ASSERT_TRUE(tiling->TileAt(1, 1)); - - TilePriority priority = prioritized_tiles[tiling->TileAt(0, 0)].priority(); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(0, 1)].priority(); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 0)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 1)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - // Furthermore, in this scenario the bottom-right tile should have the larger - // distance to visible. - TilePriority top_left = prioritized_tiles[tiling->TileAt(0, 0)].priority(); - TilePriority top_right = prioritized_tiles[tiling->TileAt(1, 0)].priority(); - TilePriority bottom_right = - prioritized_tiles[tiling->TileAt(1, 1)].priority(); - EXPECT_GT(top_right.distance_to_visible, top_left.distance_to_visible); - - EXPECT_EQ(bottom_right.distance_to_visible, top_right.distance_to_visible); -} - -TEST(ComputeTilePriorityRectsTest, PerspectiveLayer) { - // Perspective transforms need to take a different code path. - // This test checks tile priorities of a perspective layer. - FakePictureLayerTilingClient client; - - gfx::Size device_viewport(800, 600); - gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen. - gfx::Size last_layer_bounds(200, 200); - gfx::Size current_layer_bounds(200, 200); - float current_layer_contents_scale = 1.f; - gfx::Transform last_screen_transform; - gfx::Transform current_screen_transform; - double current_frame_time_in_seconds = 1.0; - - // A 3d perspective layer rotated about its Y axis, translated to almost - // fully offscreen. The left side will appear closer (i.e. larger in 2d) than - // the right side, so the top-left tile will technically be closer than the - // top-right. - - // Translate layer to offscreen - current_screen_transform.Translate(400.0, 630.0); - // Apply perspective about the center of the layer - current_screen_transform.Translate(100.0, 100.0); - current_screen_transform.ApplyPerspectiveDepth(100.0); - current_screen_transform.RotateAboutYAxis(10.0); - current_screen_transform.Translate(-100.0, -100.0); - last_screen_transform = current_screen_transform; - - // Sanity check that this transform wouldn't cause w<0 clipping. - bool clipped; - MathUtil::MapQuad(current_screen_transform, - gfx::QuadF(gfx::RectF(0, 0, 200, 200)), - &clipped); - ASSERT_FALSE(clipped); - - gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( - current_screen_transform, device_viewport); - - client.SetTileSize(gfx::Size(100, 100)); - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(current_layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = + std::unique_ptr<TestablePictureLayerTiling> tiling = TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, &client, LayerTreeSettings()); tiling->set_resolution(HIGH_RESOLUTION); - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); - auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - ASSERT_TRUE(tiling->TileAt(0, 0)); - ASSERT_TRUE(tiling->TileAt(0, 1)); - ASSERT_TRUE(tiling->TileAt(1, 0)); - ASSERT_TRUE(tiling->TileAt(1, 1)); - - // All tiles will have a positive distance_to_visible - // and an infinite time_to_visible. - TilePriority priority = prioritized_tiles[tiling->TileAt(0, 0)].priority(); - EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(0, 1)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 0)].priority(); - EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 1)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - // Furthermore, in this scenario the top-left distance_to_visible - // will be smallest, followed by top-right. The bottom layers - // will of course be further than the top layers. - TilePriority top_left = prioritized_tiles[tiling->TileAt(0, 0)].priority(); - TilePriority top_right = prioritized_tiles[tiling->TileAt(1, 0)].priority(); - TilePriority bottom_left = prioritized_tiles[tiling->TileAt(0, 1)].priority(); - TilePriority bottom_right = - prioritized_tiles[tiling->TileAt(1, 1)].priority(); - - EXPECT_GT(bottom_right.distance_to_visible, top_right.distance_to_visible); - - EXPECT_GT(bottom_left.distance_to_visible, top_left.distance_to_visible); -} - -TEST(ComputeTilePriorityRectsTest, PerspectiveLayerClippedByW) { - // Perspective transforms need to take a different code path. - // This test checks tile priorities of a perspective layer. - FakePictureLayerTilingClient client; - - gfx::Size device_viewport(800, 600); - gfx::Size last_layer_bounds(200, 200); - gfx::Size current_layer_bounds(200, 200); - float current_layer_contents_scale = 1.f; - gfx::Transform last_screen_transform; - gfx::Transform current_screen_transform; - double current_frame_time_in_seconds = 1.0; - - // A 3d perspective layer rotated about its Y axis, translated to almost - // fully offscreen. The left side will appear closer (i.e. larger in 2d) than - // the right side, so the top-left tile will technically be closer than the - // top-right. - - // Translate layer to offscreen - current_screen_transform.Translate(400.0, 970.0); - // Apply perspective and rotation about the center of the layer - current_screen_transform.Translate(100.0, 100.0); - current_screen_transform.ApplyPerspectiveDepth(10.0); - current_screen_transform.RotateAboutYAxis(10.0); - current_screen_transform.Translate(-100.0, -100.0); - last_screen_transform = current_screen_transform; - - // Sanity check that this transform does cause w<0 clipping for the left side - // of the layer, but not the right side. - bool clipped; - MathUtil::MapQuad(current_screen_transform, - gfx::QuadF(gfx::RectF(0, 0, 100, 200)), - &clipped); - ASSERT_TRUE(clipped); - - MathUtil::MapQuad(current_screen_transform, - gfx::QuadF(gfx::RectF(100, 0, 100, 200)), - &clipped); - ASSERT_FALSE(clipped); - - gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( - current_screen_transform, device_viewport); - - client.SetTileSize(gfx::Size(100, 100)); - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(current_layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, LayerTreeSettings()); - tiling->set_resolution(HIGH_RESOLUTION); - - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); + LayerTreeSettings settings; + gfx::Rect eventually_rect = viewport_in_layer_space; + eventually_rect.Inset(-settings.tiling_interest_area_padding, + -settings.tiling_interest_area_padding); + tiling->ComputeTilePriorityRects( + viewport_in_layer_space, viewport_in_layer_space, viewport_in_layer_space, + eventually_rect, current_layer_contents_scale, Occlusion()); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); ASSERT_TRUE(tiling->TileAt(0, 0)); @@ -1518,8 +877,6 @@ TEST(ComputeTilePriorityRectsTest, PerspectiveLayerClippedByW) { ASSERT_TRUE(tiling->TileAt(1, 0)); ASSERT_TRUE(tiling->TileAt(1, 1)); - // Left-side tiles will be clipped by the transform, so we have to assume - // they are visible just in case. TilePriority priority = prioritized_tiles[tiling->TileAt(0, 0)].priority(); EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin); @@ -1528,76 +885,6 @@ TEST(ComputeTilePriorityRectsTest, PerspectiveLayerClippedByW) { EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); - // Right-side tiles will have a positive distance_to_visible - // and an infinite time_to_visible. - priority = prioritized_tiles[tiling->TileAt(1, 0)].priority(); - EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 1)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); -} - -TEST(ComputeTilePriorityRectsTest, BasicMotion) { - // Test that time_to_visible is computed correctly when - // there is some motion. - FakePictureLayerTilingClient client; - - gfx::Size device_viewport(800, 600); - gfx::Rect visible_layer_rect(0, 0, 0, 0); - gfx::Size last_layer_bounds(200, 200); - gfx::Size current_layer_bounds(200, 200); - float last_layer_contents_scale = 1.f; - float current_layer_contents_scale = 1.f; - gfx::Transform last_screen_transform; - gfx::Transform current_screen_transform; - double last_frame_time_in_seconds = 1.0; - double current_frame_time_in_seconds = 2.0; - - // Offscreen layer is coming closer to viewport at 1000 pixels per second. - current_screen_transform.Translate(1800, 0); - last_screen_transform.Translate(2800, 0); - - gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( - current_screen_transform, device_viewport); - - client.SetTileSize(gfx::Size(100, 100)); - LayerTreeSettings settings; - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(current_layer_bounds); - scoped_ptr<TestablePictureLayerTiling> tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, settings); - tiling->set_resolution(HIGH_RESOLUTION); - - // previous ("last") frame - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - last_layer_contents_scale, - last_frame_time_in_seconds, Occlusion()); - - // current frame - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); - auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - ASSERT_TRUE(tiling->TileAt(0, 0)); - ASSERT_TRUE(tiling->TileAt(0, 1)); - ASSERT_TRUE(tiling->TileAt(1, 0)); - ASSERT_TRUE(tiling->TileAt(1, 1)); - - TilePriority priority = prioritized_tiles[tiling->TileAt(0, 0)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(0, 1)].priority(); - EXPECT_GT(priority.distance_to_visible, 0.f); - EXPECT_NE(TilePriority::NOW, priority.priority_bin); - - // time_to_visible for the right hand side layers needs an extra 0.099 - // seconds because this tile is 99 pixels further away. priority = prioritized_tiles[tiling->TileAt(1, 0)].priority(); EXPECT_GT(priority.distance_to_visible, 0.f); EXPECT_NE(TilePriority::NOW, priority.priority_bin); @@ -1607,153 +894,20 @@ TEST(ComputeTilePriorityRectsTest, BasicMotion) { EXPECT_NE(TilePriority::NOW, priority.priority_bin); } -TEST(ComputeTilePriorityRectsTest, RotationMotion) { - // Each tile of a layer may be affected differently by a transform; Check - // that ComputeTilePriorityRects correctly accounts for the transform between - // layer space and screen space. - - FakePictureLayerTilingClient client; - scoped_ptr<TestablePictureLayerTiling> tiling; - - gfx::Size device_viewport(800, 600); - gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscren. - gfx::Size last_layer_bounds(200, 200); - gfx::Size current_layer_bounds(200, 200); - float last_layer_contents_scale = 1.f; - float current_layer_contents_scale = 1.f; - gfx::Transform last_screen_transform; - gfx::Transform current_screen_transform; - double last_frame_time_in_seconds = 1.0; - double current_frame_time_in_seconds = 2.0; - - // Rotation motion is set up specifically so that: - // - rotation occurs about the center of the layer - // - the top-left tile becomes visible on rotation - // - the top-right tile will have an infinite time_to_visible - // because it is rotating away from viewport. - // - bottom-left layer will have a positive non-zero time_to_visible - // because it is rotating toward the viewport. - current_screen_transform.Translate(400, 550); - current_screen_transform.RotateAboutZAxis(45); - - last_screen_transform.Translate(400, 550); - - gfx::Rect viewport_in_layer_space = ViewportInLayerSpace( - current_screen_transform, device_viewport); - - client.SetTileSize(gfx::Size(100, 100)); - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(current_layer_bounds); - tiling = TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &client, LayerTreeSettings()); - tiling->set_resolution(HIGH_RESOLUTION); - - // previous ("last") frame - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - last_layer_contents_scale, - last_frame_time_in_seconds, Occlusion()); - - // current frame - tiling->ComputeTilePriorityRects(viewport_in_layer_space, - current_layer_contents_scale, - current_frame_time_in_seconds, Occlusion()); - auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); - - ASSERT_TRUE(tiling->TileAt(0, 0)); - ASSERT_TRUE(tiling->TileAt(0, 1)); - ASSERT_TRUE(tiling->TileAt(1, 0)); - ASSERT_TRUE(tiling->TileAt(1, 1)); - - TilePriority priority = prioritized_tiles[tiling->TileAt(0, 0)].priority(); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(0, 1)].priority(); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - - priority = prioritized_tiles[tiling->TileAt(1, 0)].priority(); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); -} - -TEST(PictureLayerTilingTest, RecycledTilesCleared) { - // This test performs the following: - // Setup: - // - Two tilings, one active one recycled with all tiles shared. - // Procedure: - // - Viewport moves somewhere far away and active tiling clears tiles. - // - Viewport moves back and a new active tiling tile is created. - // Result: - // - Recycle tiling does _not_ have the tile in the same location (thus it - // will be shared next time a pending tiling is created). - - FakePictureLayerTilingClient active_client; - - active_client.SetTileSize(gfx::Size(100, 100)); - LayerTreeSettings settings; - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(gfx::Size(10000, 10000)); - scoped_ptr<TestablePictureLayerTiling> active_tiling = - TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, - &active_client, settings); - active_tiling->set_resolution(HIGH_RESOLUTION); - // Create all tiles on this tiling. - active_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, - Occlusion()); - - FakePictureLayerTilingClient recycle_client; - recycle_client.SetTileSize(gfx::Size(100, 100)); - recycle_client.set_twin_tiling(active_tiling.get()); - - raster_source = FakeRasterSource::CreateFilled(gfx::Size(10000, 10000)); - scoped_ptr<TestablePictureLayerTiling> recycle_tiling = - TestablePictureLayerTiling::Create(PENDING_TREE, 1.0f, raster_source, - &recycle_client, settings); - recycle_tiling->set_resolution(HIGH_RESOLUTION); - - // Create all tiles on the second tiling. All tiles should be shared. - recycle_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, - 1.0f, Occlusion()); - - // Set the second tiling as recycled. - active_client.set_twin_tiling(NULL); - recycle_client.set_twin_tiling(NULL); - - EXPECT_TRUE(active_tiling->TileAt(0, 0)); - EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); - - // Move the viewport far away from the (0, 0) tile. - active_tiling->ComputeTilePriorityRects(gfx::Rect(9000, 9000, 100, 100), 1.0f, - 2.0, Occlusion()); - // Ensure the tile was deleted. - EXPECT_FALSE(active_tiling->TileAt(0, 0)); - EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); - - // Move the viewport back to (0, 0) tile. - active_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, 3.0, - Occlusion()); - - // Ensure that we now have a tile here on both active. - EXPECT_TRUE(active_tiling->TileAt(0, 0)); - EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); -} - TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) { FakePictureLayerTilingClient active_client; active_client.SetTileSize(gfx::Size(100, 100)); scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(gfx::Size(100, 100)); - scoped_ptr<TestablePictureLayerTiling> active_tiling = + std::unique_ptr<TestablePictureLayerTiling> active_tiling = TestablePictureLayerTiling::Create(ACTIVE_TREE, 1.0f, raster_source, &active_client, LayerTreeSettings()); active_tiling->set_resolution(HIGH_RESOLUTION); // Create all tiles on this tiling. - active_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, - Occlusion()); + gfx::Rect visible_rect = gfx::Rect(0, 0, 100, 100); + active_tiling->ComputeTilePriorityRects( + visible_rect, visible_rect, visible_rect, visible_rect, 1.f, Occlusion()); FakePictureLayerTilingClient recycle_client; recycle_client.SetTileSize(gfx::Size(100, 100)); @@ -1762,14 +916,15 @@ TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) { LayerTreeSettings settings; raster_source = FakeRasterSource::CreateFilled(gfx::Size(100, 100)); - scoped_ptr<TestablePictureLayerTiling> recycle_tiling = + std::unique_ptr<TestablePictureLayerTiling> recycle_tiling = TestablePictureLayerTiling::Create(PENDING_TREE, 1.0f, raster_source, &recycle_client, settings); recycle_tiling->set_resolution(HIGH_RESOLUTION); - // Create all tiles on the recycle tiling. All tiles should be shared. - recycle_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, - 1.0f, Occlusion()); + // Create all tiles on the recycle tiling. + recycle_tiling->ComputeTilePriorityRects(visible_rect, visible_rect, + visible_rect, visible_rect, 1.0f, + Occlusion()); // Set the second tiling as recycled. active_client.set_twin_tiling(NULL); @@ -1784,38 +939,6 @@ TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) { EXPECT_FALSE(recycle_tiling->TileAt(0, 0)); } -TEST(PictureLayerTilingTest, InvalidateAfterComputeTilePriorityRects) { - FakePictureLayerTilingClient pending_client; - pending_client.SetTileSize(gfx::Size(100, 100)); - - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFilled(gfx::Size(100, 100)); - scoped_ptr<TestablePictureLayerTiling> pending_tiling = - TestablePictureLayerTiling::Create(PENDING_TREE, 1.0f, raster_source, - &pending_client, LayerTreeSettings()); - pending_tiling->set_resolution(HIGH_RESOLUTION); - - // Ensure that we can compute tile priority rects, invalidate, and compute the - // rects again. It is important that the second compute tile priority rects - // return true, indicating that things have changed (since invalidation has - // changed things). This causes PrepareTiles to be properly scheduled. If the - // second ComputeTilePriorityRects returns false, then we assume that - // PrepareTiles isn't needed and we signal that we're ready to draw - // immediately, which can cause visual glitches. - // - // This can happen we if we process an impl frame deadline before processing a - // commit. That is, when we draw we ComputeTilePriorityRects. If we process - // the commit afterwards, it would use the same timestamp and sometimes would - // use the same viewport to compute tile priority rects again. - double time = 1.; - gfx::Rect viewport(0, 0, 100, 100); - EXPECT_TRUE(pending_tiling->ComputeTilePriorityRects(viewport, 1.0f, time, - Occlusion())); - pending_tiling->Invalidate(viewport); - EXPECT_TRUE(pending_tiling->ComputeTilePriorityRects(viewport, 1.0f, time, - Occlusion())); -} - TEST_F(PictureLayerTilingIteratorTest, ResizeTilesAndUpdateToCurrent) { // The tiling has four rows and three columns. Initialize(gfx::Size(150, 100), 1.f, gfx::Size(250, 150)); diff --git a/chromium/cc/tiles/raster_tile_priority_queue.cc b/chromium/cc/tiles/raster_tile_priority_queue.cc index 0b47407411f..2c010df0ae5 100644 --- a/chromium/cc/tiles/raster_tile_priority_queue.cc +++ b/chromium/cc/tiles/raster_tile_priority_queue.cc @@ -10,21 +10,21 @@ namespace cc { // static -scoped_ptr<RasterTilePriorityQueue> RasterTilePriorityQueue::Create( +std::unique_ptr<RasterTilePriorityQueue> RasterTilePriorityQueue::Create( const std::vector<PictureLayerImpl*>& active_layers, const std::vector<PictureLayerImpl*>& pending_layers, TreePriority tree_priority, Type type) { switch (type) { case Type::ALL: { - scoped_ptr<RasterTilePriorityQueueAll> queue( + std::unique_ptr<RasterTilePriorityQueueAll> queue( new RasterTilePriorityQueueAll); queue->Build(active_layers, pending_layers, tree_priority); return std::move(queue); } case Type::REQUIRED_FOR_ACTIVATION: case Type::REQUIRED_FOR_DRAW: { - scoped_ptr<RasterTilePriorityQueueRequired> queue( + std::unique_ptr<RasterTilePriorityQueueRequired> queue( new RasterTilePriorityQueueRequired); queue->Build(active_layers, pending_layers, type); return std::move(queue); diff --git a/chromium/cc/tiles/raster_tile_priority_queue.h b/chromium/cc/tiles/raster_tile_priority_queue.h index 828f3cf9810..5a41827f69c 100644 --- a/chromium/cc/tiles/raster_tile_priority_queue.h +++ b/chromium/cc/tiles/raster_tile_priority_queue.h @@ -19,7 +19,7 @@ class CC_EXPORT RasterTilePriorityQueue { public: enum class Type { ALL, REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW }; - static scoped_ptr<RasterTilePriorityQueue> Create( + static std::unique_ptr<RasterTilePriorityQueue> Create( const std::vector<PictureLayerImpl*>& active_layers, const std::vector<PictureLayerImpl*>& pending_layers, TreePriority tree_priority, diff --git a/chromium/cc/tiles/raster_tile_priority_queue_all.cc b/chromium/cc/tiles/raster_tile_priority_queue_all.cc index 09c5c78c3d0..d0c95807d63 100644 --- a/chromium/cc/tiles/raster_tile_priority_queue_all.cc +++ b/chromium/cc/tiles/raster_tile_priority_queue_all.cc @@ -4,6 +4,7 @@ #include "cc/tiles/raster_tile_priority_queue_all.h" +#include "base/memory/ptr_util.h" #include "cc/tiles/tiling_set_raster_queue_all.h" namespace cc { @@ -15,8 +16,9 @@ class RasterOrderComparator { explicit RasterOrderComparator(TreePriority tree_priority) : tree_priority_(tree_priority) {} - bool operator()(const scoped_ptr<TilingSetRasterQueueAll>& a_queue, - const scoped_ptr<TilingSetRasterQueueAll>& b_queue) const { + bool operator()( + const std::unique_ptr<TilingSetRasterQueueAll>& a_queue, + const std::unique_ptr<TilingSetRasterQueueAll>& b_queue) const { // Note that in this function, we have to return true if and only if // a is strictly lower priority than b. const TilePriority& a_priority = a_queue->Top().priority(); @@ -51,7 +53,7 @@ class RasterOrderComparator { void CreateTilingSetRasterQueues( const std::vector<PictureLayerImpl*>& layers, TreePriority tree_priority, - std::vector<scoped_ptr<TilingSetRasterQueueAll>>* queues) { + std::vector<std::unique_ptr<TilingSetRasterQueueAll>>* queues) { DCHECK(queues->empty()); for (auto* layer : layers) { @@ -60,8 +62,9 @@ void CreateTilingSetRasterQueues( PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set(); bool prioritize_low_res = tree_priority == SMOOTHNESS_TAKES_PRIORITY; - scoped_ptr<TilingSetRasterQueueAll> tiling_set_queue = make_scoped_ptr( - new TilingSetRasterQueueAll(tiling_set, prioritize_low_res)); + std::unique_ptr<TilingSetRasterQueueAll> tiling_set_queue = + base::WrapUnique( + new TilingSetRasterQueueAll(tiling_set, prioritize_low_res)); // Queues will only contain non empty tiling sets. if (!tiling_set_queue->IsEmpty()) queues->push_back(std::move(tiling_set_queue)); @@ -116,15 +119,15 @@ void RasterTilePriorityQueueAll::Pop() { } } -std::vector<scoped_ptr<TilingSetRasterQueueAll>>& +std::vector<std::unique_ptr<TilingSetRasterQueueAll>>& RasterTilePriorityQueueAll::GetNextQueues() { const auto* const_this = static_cast<const RasterTilePriorityQueueAll*>(this); const auto& const_queues = const_this->GetNextQueues(); - return const_cast<std::vector<scoped_ptr<TilingSetRasterQueueAll>>&>( + return const_cast<std::vector<std::unique_ptr<TilingSetRasterQueueAll>>&>( const_queues); } -const std::vector<scoped_ptr<TilingSetRasterQueueAll>>& +const std::vector<std::unique_ptr<TilingSetRasterQueueAll>>& RasterTilePriorityQueueAll::GetNextQueues() const { DCHECK(!IsEmpty()); diff --git a/chromium/cc/tiles/raster_tile_priority_queue_all.h b/chromium/cc/tiles/raster_tile_priority_queue_all.h index 275a73183bd..af4983ae51b 100644 --- a/chromium/cc/tiles/raster_tile_priority_queue_all.h +++ b/chromium/cc/tiles/raster_tile_priority_queue_all.h @@ -34,11 +34,12 @@ class CC_EXPORT RasterTilePriorityQueueAll : public RasterTilePriorityQueue { const std::vector<PictureLayerImpl*>& pending_layers, TreePriority tree_priority); - std::vector<scoped_ptr<TilingSetRasterQueueAll>>& GetNextQueues(); - const std::vector<scoped_ptr<TilingSetRasterQueueAll>>& GetNextQueues() const; + std::vector<std::unique_ptr<TilingSetRasterQueueAll>>& GetNextQueues(); + const std::vector<std::unique_ptr<TilingSetRasterQueueAll>>& GetNextQueues() + const; - std::vector<scoped_ptr<TilingSetRasterQueueAll>> active_queues_; - std::vector<scoped_ptr<TilingSetRasterQueueAll>> pending_queues_; + std::vector<std::unique_ptr<TilingSetRasterQueueAll>> active_queues_; + std::vector<std::unique_ptr<TilingSetRasterQueueAll>> pending_queues_; TreePriority tree_priority_; DISALLOW_COPY_AND_ASSIGN(RasterTilePriorityQueueAll); diff --git a/chromium/cc/tiles/raster_tile_priority_queue_required.cc b/chromium/cc/tiles/raster_tile_priority_queue_required.cc index 24d978937ca..c5969b94258 100644 --- a/chromium/cc/tiles/raster_tile_priority_queue_required.cc +++ b/chromium/cc/tiles/raster_tile_priority_queue_required.cc @@ -12,12 +12,12 @@ namespace { void AppendTilingSetRequiredQueues( const std::vector<PictureLayerImpl*>& layers, - std::vector<scoped_ptr<TilingSetRasterQueueRequired>>* queues) { + std::vector<std::unique_ptr<TilingSetRasterQueueRequired>>* queues) { for (auto* layer : layers) { if (!layer->HasValidTilePriorities()) continue; - scoped_ptr<TilingSetRasterQueueRequired> tiling_set_queue( + std::unique_ptr<TilingSetRasterQueueRequired> tiling_set_queue( new TilingSetRasterQueueRequired( layer->picture_layer_tiling_set(), RasterTilePriorityQueueRequired::Type::REQUIRED_FOR_ACTIVATION)); @@ -51,7 +51,7 @@ void RasterTilePriorityQueueRequired::BuildRequiredForDraw( if (!layer->HasValidTilePriorities()) continue; - scoped_ptr<TilingSetRasterQueueRequired> tiling_set_queue( + std::unique_ptr<TilingSetRasterQueueRequired> tiling_set_queue( new TilingSetRasterQueueRequired(layer->picture_layer_tiling_set(), Type::REQUIRED_FOR_DRAW)); if (!tiling_set_queue->IsEmpty()) diff --git a/chromium/cc/tiles/raster_tile_priority_queue_required.h b/chromium/cc/tiles/raster_tile_priority_queue_required.h index f88993fd6cb..a45a4baf878 100644 --- a/chromium/cc/tiles/raster_tile_priority_queue_required.h +++ b/chromium/cc/tiles/raster_tile_priority_queue_required.h @@ -36,7 +36,7 @@ class RasterTilePriorityQueueRequired : public RasterTilePriorityQueue { const std::vector<PictureLayerImpl*>& active_layers, const std::vector<PictureLayerImpl*>& pending_layers); - std::vector<scoped_ptr<TilingSetRasterQueueRequired>> tiling_set_queues_; + std::vector<std::unique_ptr<TilingSetRasterQueueRequired>> tiling_set_queues_; DISALLOW_COPY_AND_ASSIGN(RasterTilePriorityQueueRequired); }; diff --git a/chromium/cc/tiles/software_image_decode_controller.cc b/chromium/cc/tiles/software_image_decode_controller.cc index d2a73e9ef87..e3c188d9439 100644 --- a/chromium/cc/tiles/software_image_decode_controller.cc +++ b/chromium/cc/tiles/software_image_decode_controller.cc @@ -6,18 +6,22 @@ #include <stdint.h> +#include <algorithm> #include <functional> #include "base/format_macros.h" #include "base/macros.h" #include "base/memory/discardable_memory.h" +#include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "cc/debug/devtools_instrumentation.h" -#include "cc/raster/tile_task_runner.h" +#include "cc/raster/tile_task.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/core/SkPixmap.h" #include "ui/gfx/skia_util.h" namespace cc { @@ -40,7 +44,7 @@ class AutoRemoveKeyFromTaskMap { public: AutoRemoveKeyFromTaskMap( std::unordered_map<SoftwareImageDecodeController::ImageKey, - scoped_refptr<ImageDecodeTask>, + scoped_refptr<TileTask>, SoftwareImageDecodeController::ImageKeyHash>* task_map, const SoftwareImageDecodeController::ImageKey& key) : task_map_(task_map), key_(key) {} @@ -48,36 +52,36 @@ class AutoRemoveKeyFromTaskMap { private: std::unordered_map<SoftwareImageDecodeController::ImageKey, - scoped_refptr<ImageDecodeTask>, + scoped_refptr<TileTask>, SoftwareImageDecodeController::ImageKeyHash>* task_map_; SoftwareImageDecodeController::ImageKey key_; }; -class ImageDecodeTaskImpl : public ImageDecodeTask { +class ImageDecodeTaskImpl : public TileTask { public: ImageDecodeTaskImpl(SoftwareImageDecodeController* controller, const SoftwareImageDecodeController::ImageKey& image_key, const DrawImage& image, - uint64_t source_prepare_tiles_id) - : controller_(controller), + const ImageDecodeController::TracingInfo& tracing_info) + : TileTask(true), + controller_(controller), image_key_(image_key), image_(image), - image_ref_(skia::SharePtr(image.image())), - source_prepare_tiles_id_(source_prepare_tiles_id) {} + tracing_info_(tracing_info) {} // Overridden from Task: void RunOnWorkerThread() override { TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "software", "source_prepare_tiles_id", - source_prepare_tiles_id_); + tracing_info_.prepare_tiles_id); devtools_instrumentation::ScopedImageDecodeTask image_decode_task( - image_ref_.get()); + image_.image().get()); controller_->DecodeImage(image_key_, image_); } // Overridden from TileTask: - void ScheduleOnOriginThread(TileTaskClient* client) override {} - void CompleteOnOriginThread(TileTaskClient* client) override { + void ScheduleOnOriginThread(RasterBufferProvider* provider) override {} + void CompleteOnOriginThread(RasterBufferProvider* provider) override { controller_->RemovePendingTask(image_key_); } @@ -88,59 +92,96 @@ class ImageDecodeTaskImpl : public ImageDecodeTask { SoftwareImageDecodeController* controller_; SoftwareImageDecodeController::ImageKey image_key_; DrawImage image_; - skia::RefPtr<const SkImage> image_ref_; - uint64_t source_prepare_tiles_id_; + const ImageDecodeController::TracingInfo tracing_info_; DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); }; +// Most images are scaled from the source image's size to the target size. +// But in the case of mipmaps, we are scaling from the mip level which is +// larger than we need. +// This function gets the scale of the mip level which will be used. +SkSize GetMipMapScaleAdjustment(const gfx::Size& src_size, + const gfx::Size& target_size) { + int src_height = src_size.height(); + int src_width = src_size.width(); + int target_height = target_size.height(); + int target_width = target_size.width(); + if (target_height == 0 || target_width == 0) + return SkSize::Make(-1.f, -1.f); + + int next_mip_height = src_height; + int next_mip_width = src_width; + for (int current_mip_level = 0;; current_mip_level++) { + int mip_height = next_mip_height; + int mip_width = next_mip_width; + + next_mip_height = std::max(1, src_height / (1 << (current_mip_level + 1))); + next_mip_width = std::max(1, src_width / (1 << (current_mip_level + 1))); + + // Check if an axis on the next mip level would be smaller than the target. + // If so, use the current mip level. + // This effectively always uses the larger image and always scales down. + if (next_mip_height < target_height || next_mip_width < target_width) { + SkScalar y_scale = static_cast<float>(mip_height) / src_height; + SkScalar x_scale = static_cast<float>(mip_width) / src_width; + + return SkSize::Make(x_scale, y_scale); + } + + if (mip_height == 1 && mip_width == 1) { + // We have reached the final mip level + SkScalar y_scale = static_cast<float>(mip_height) / src_height; + SkScalar x_scale = static_cast<float>(mip_width) / src_width; + + return SkSize::Make(x_scale, y_scale); + } + } +} + SkSize GetScaleAdjustment(const ImageDecodeControllerKey& key) { // If the requested filter quality did not require scale, then the adjustment // is identity. - if (key.can_use_original_decode()) + if (key.can_use_original_decode()) { return SkSize::Make(1.f, 1.f); - - float x_scale = - key.target_size().width() / static_cast<float>(key.src_rect().width()); - float y_scale = - key.target_size().height() / static_cast<float>(key.src_rect().height()); - return SkSize::Make(x_scale, y_scale); + } else if (key.filter_quality() == kMedium_SkFilterQuality) { + return GetMipMapScaleAdjustment(key.src_rect().size(), key.target_size()); + } else { + float x_scale = + key.target_size().width() / static_cast<float>(key.src_rect().width()); + float y_scale = key.target_size().height() / + static_cast<float>(key.src_rect().height()); + return SkSize::Make(x_scale, y_scale); + } } SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) { return std::min(key.filter_quality(), kLow_SkFilterQuality); } -SkColorType SkColorTypeForDecoding(ResourceFormat format) { - // Use kN32_SkColorType if there is no corresponding SkColorType. - switch (format) { - case RGBA_4444: - return kARGB_4444_SkColorType; - case RGBA_8888: - case BGRA_8888: - return kN32_SkColorType; - case ALPHA_8: - return kAlpha_8_SkColorType; - case RGB_565: - return kRGB_565_SkColorType; - case LUMINANCE_8: - return kGray_8_SkColorType; - case ETC1: - case RED_8: - case LUMINANCE_F16: - return kN32_SkColorType; - } - NOTREACHED(); - return kN32_SkColorType; -} - SkImageInfo CreateImageInfo(size_t width, size_t height, ResourceFormat format) { - return SkImageInfo::Make(width, height, SkColorTypeForDecoding(format), + return SkImageInfo::Make(width, height, + ResourceFormatToClosestSkColorType(format), kPremul_SkAlphaType); } +void RecordLockExistingCachedImageHistogram(TilePriority::PriorityBin bin, + bool success) { + switch (bin) { + case TilePriority::NOW: + UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.NOW", + success); + case TilePriority::SOON: + UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.SOON", + success); + case TilePriority::EVENTUALLY: + UMA_HISTOGRAM_BOOLEAN( + "Renderer4.LockExistingCachedImage.Software.EVENTUALLY", success); + } +} + } // namespace SoftwareImageDecodeController::SoftwareImageDecodeController( @@ -172,8 +213,8 @@ SoftwareImageDecodeController::~SoftwareImageDecodeController() { bool SoftwareImageDecodeController::GetTaskForImageAndRef( const DrawImage& image, - uint64_t prepare_tiles_id, - scoped_refptr<ImageDecodeTask>* task) { + const TracingInfo& tracing_info, + scoped_refptr<TileTask>* task) { // If the image already exists or if we're going to create a task for it, then // we'll likely need to ref this image (the exception is if we're prerolling // the image only). That means the image is or will be in the cache. When the @@ -193,25 +234,6 @@ bool SoftwareImageDecodeController::GetTaskForImageAndRef( return false; } - // If we're not going to do a scale, we will just create a task to preroll the - // image the first time we see it. This doesn't need to account for memory. - // TODO(vmpstr): We can also lock the original sized image, in which case it - // does require memory bookkeeping. - if (!CanHandleImage(key)) { - base::AutoLock lock(lock_); - if (prerolled_images_.count(key.image_id()) == 0) { - scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; - if (!existing_task) { - existing_task = make_scoped_refptr( - new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); - } - *task = existing_task; - } else { - *task = nullptr; - } - return false; - } - base::AutoLock lock(lock_); // If we already have the image in cache, then we can return it. @@ -219,21 +241,32 @@ bool SoftwareImageDecodeController::GetTaskForImageAndRef( bool new_image_fits_in_memory = locked_images_budget_.AvailableMemoryBytes() >= key.locked_bytes(); if (decoded_it != decoded_images_.end()) { - if (decoded_it->second->is_locked() || + bool image_was_locked = decoded_it->second->is_locked(); + if (image_was_locked || (new_image_fits_in_memory && decoded_it->second->Lock())) { RefImage(key); *task = nullptr; SanityCheckState(__LINE__, true); + + // If the image wasn't locked, then we just succeeded in locking it. + if (!image_was_locked) { + RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin, + true); + } return true; } + // If the image fits in memory, then we at least tried to lock it and // failed. This means that it's not valid anymore. - if (new_image_fits_in_memory) + if (new_image_fits_in_memory) { + RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin, + false); decoded_images_.Erase(decoded_it); + } } // If the task exists, return it. - scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; + scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key]; if (existing_task) { RefImage(key); *task = existing_task; @@ -257,7 +290,7 @@ bool SoftwareImageDecodeController::GetTaskForImageAndRef( // ref. RefImage(key); existing_task = make_scoped_refptr( - new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); + new ImageDecodeTaskImpl(this, key, image, tracing_info)); *task = existing_task; SanityCheckState(__LINE__, true); return true; @@ -283,7 +316,6 @@ void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) { // it yet (or failed to decode it). // 2b. Unlock the image but keep it in list. const ImageKey& key = ImageKey::FromDrawImage(image); - DCHECK(CanHandleImage(key)) << key.ToString(); TRACE_EVENT1("disabled-by-default-cc.debug", "SoftwareImageDecodeController::UnrefImage", "key", key.ToString()); @@ -314,20 +346,6 @@ void SoftwareImageDecodeController::DecodeImage(const ImageKey& key, const DrawImage& image) { TRACE_EVENT1("cc", "SoftwareImageDecodeController::DecodeImage", "key", key.ToString()); - if (!CanHandleImage(key)) { - image.image()->preroll(); - - base::AutoLock lock(lock_); - prerolled_images_.insert(key.image_id()); - // Erase the pending task from the queue, since the task won't be doing - // anything useful after this function terminates. Since we don't preroll - // images twice, this is actually not necessary but it behaves similar to - // the other code path: when this function finishes, the task isn't in the - // pending_image_tasks_ list. - pending_image_tasks_.erase(key); - return; - } - base::AutoLock lock(lock_); AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key); @@ -347,7 +365,7 @@ void SoftwareImageDecodeController::DecodeImage(const ImageKey& key, decoded_images_.Erase(image_it); } - scoped_ptr<DecodedImage> decoded_image; + std::unique_ptr<DecodedImage> decoded_image; { base::AutoUnlock unlock(lock_); decoded_image = DecodeImageInternal(key, image); @@ -383,124 +401,28 @@ void SoftwareImageDecodeController::DecodeImage(const ImageKey& key, SanityCheckState(__LINE__, true); } -scoped_ptr<SoftwareImageDecodeController::DecodedImage> +std::unique_ptr<SoftwareImageDecodeController::DecodedImage> SoftwareImageDecodeController::DecodeImageInternal( const ImageKey& key, const DrawImage& draw_image) { TRACE_EVENT1("disabled-by-default-cc.debug", "SoftwareImageDecodeController::DecodeImageInternal", "key", key.ToString()); - const SkImage* image = draw_image.image(); - - // If we can use the original decode, then we don't need to do scaling. We can - // just read pixels into the final memory. - if (key.can_use_original_decode()) { - SkImageInfo decoded_info = - CreateImageInfo(image->width(), image->height(), format_); - scoped_ptr<base::DiscardableMemory> decoded_pixels; - { - TRACE_EVENT0( - "disabled-by-default-cc.debug", - "SoftwareImageDecodeController::DecodeImageInternal - allocate " - "decoded pixels"); - decoded_pixels = - base::DiscardableMemoryAllocator::GetInstance() - ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * - decoded_info.height()); - } - { - TRACE_EVENT0( - "disabled-by-default-cc.debug", - "SoftwareImageDecodeController::DecodeImageInternal - read pixels"); - bool result = image->readPixels(decoded_info, decoded_pixels->data(), - decoded_info.minRowBytes(), 0, 0, - SkImage::kDisallow_CachingHint); - - if (!result) { - decoded_pixels->Unlock(); - return nullptr; - } - } - - return make_scoped_ptr( - new DecodedImage(decoded_info, std::move(decoded_pixels), - SkSize::Make(0, 0), next_tracing_id_.GetNext())); - } - - // If we get here, that means we couldn't use the original sized decode for - // whatever reason. However, in all cases we do need an original decode to - // either do a scale or to extract a subrect from the image. So, what we can - // do is construct a key that would require a full sized decode, then get that - // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This - // ensures that if the original sized decode is already available in any of - // the caches, we reuse that. We also ensure that all the proper locking takes - // place. If, on the other hand, the decode was not available, - // GetDecodedImageForDrawInternal() would decode the image, and unreffing it - // later ensures that we will store the discardable memory unlocked in the - // cache to be used by future requests. - gfx::Rect full_image_rect(image->width(), image->height()); - DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect), - kNone_SkFilterQuality, SkMatrix::I()); - ImageKey original_size_key = - ImageKey::FromDrawImage(original_size_draw_image); - // Sanity checks. - DCHECK(original_size_key.can_use_original_decode()) - << original_size_key.ToString(); - DCHECK(full_image_rect.size() == original_size_key.target_size()); - - auto decoded_draw_image = GetDecodedImageForDrawInternal( - original_size_key, original_size_draw_image); - if (!decoded_draw_image.image()) { - DrawWithImageFinished(original_size_draw_image, decoded_draw_image); + sk_sp<const SkImage> image = draw_image.image(); + if (!image) return nullptr; - } - SkPixmap decoded_pixmap; - bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); - DCHECK(result) << key.ToString(); - if (key.src_rect() != full_image_rect) { - result = decoded_pixmap.extractSubset(&decoded_pixmap, - gfx::RectToSkIRect(key.src_rect())); - DCHECK(result) << key.ToString(); - } - - // Now we have a decoded_pixmap which represents the src_rect at the - // original scale. All we need to do is scale it. - DCHECK(!key.target_size().IsEmpty()); - SkImageInfo scaled_info = CreateImageInfo( - key.target_size().width(), key.target_size().height(), format_); - scoped_ptr<base::DiscardableMemory> scaled_pixels; - { - TRACE_EVENT0( - "disabled-by-default-cc.debug", - "SoftwareImageDecodeController::DecodeImageInternal - allocate " - "scaled pixels"); - scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() - ->AllocateLockedDiscardableMemory( - scaled_info.minRowBytes() * scaled_info.height()); - } - SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), - scaled_info.minRowBytes()); - // TODO(vmpstr): Start handling more than just high filter quality. - DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); - { - TRACE_EVENT0( - "disabled-by-default-cc.debug", - "SoftwareImageDecodeController::DecodeImageInternal - scale pixels"); - bool result = - decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); - DCHECK(result) << key.ToString(); + switch (key.filter_quality()) { + case kNone_SkFilterQuality: + case kLow_SkFilterQuality: + return GetOriginalImageDecode(key, std::move(image)); + case kMedium_SkFilterQuality: + case kHigh_SkFilterQuality: + return GetScaledImageDecode(key, std::move(image)); + default: + NOTREACHED(); + return nullptr; } - - // Release the original sized decode. Any other intermediate result to release - // would be the subrect memory. However, that's in a scoped_ptr and will be - // deleted automatically when we return. - DrawWithImageFinished(original_size_draw_image, decoded_draw_image); - - return make_scoped_ptr( - new DecodedImage(scaled_info, std::move(scaled_pixels), - SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), - next_tracing_id_.GetNext())); } DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( @@ -513,9 +435,6 @@ DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( if (key.target_size().IsEmpty()) return DecodedDrawImage(nullptr, kNone_SkFilterQuality); - if (!CanHandleImage(key)) - return DecodedDrawImage(draw_image.image(), draw_image.filter_quality()); - return GetDecodedImageForDrawInternal(key, draw_image); } @@ -529,7 +448,7 @@ DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( auto decoded_images_it = decoded_images_.Get(key); // If we found the image and it's locked, then return it. If it's not locked, // erase it from the cache since it might be put into the at-raster cache. - scoped_ptr<DecodedImage> scoped_decoded_image; + std::unique_ptr<DecodedImage> scoped_decoded_image; DecodedImage* decoded_image = nullptr; if (decoded_images_it != decoded_images_.end()) { decoded_image = decoded_images_it->second.get(); @@ -612,6 +531,108 @@ DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( return decoded_draw_image; } +std::unique_ptr<SoftwareImageDecodeController::DecodedImage> +SoftwareImageDecodeController::GetOriginalImageDecode( + const ImageKey& key, + sk_sp<const SkImage> image) { + SkImageInfo decoded_info = + CreateImageInfo(image->width(), image->height(), format_); + std::unique_ptr<base::DiscardableMemory> decoded_pixels; + { + TRACE_EVENT0("disabled-by-default-cc.debug", + "SoftwareImageDecodeController::GetOriginalImageDecode - " + "allocate decoded pixels"); + decoded_pixels = + base::DiscardableMemoryAllocator::GetInstance() + ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * + decoded_info.height()); + } + { + TRACE_EVENT0("disabled-by-default-cc.debug", + "SoftwareImageDecodeController::GetOriginalImageDecode - " + "read pixels"); + bool result = image->readPixels(decoded_info, decoded_pixels->data(), + decoded_info.minRowBytes(), 0, 0, + SkImage::kDisallow_CachingHint); + + if (!result) { + decoded_pixels->Unlock(); + return nullptr; + } + } + return base::WrapUnique( + new DecodedImage(decoded_info, std::move(decoded_pixels), + SkSize::Make(0, 0), next_tracing_id_.GetNext())); +} + +std::unique_ptr<SoftwareImageDecodeController::DecodedImage> +SoftwareImageDecodeController::GetScaledImageDecode( + const ImageKey& key, + sk_sp<const SkImage> image) { + // Construct a key to use in GetDecodedImageForDrawInternal(). + // This allows us to reuse an image in any cache if available. + gfx::Rect full_image_rect(image->width(), image->height()); + DrawImage original_size_draw_image(std::move(image), + gfx::RectToSkIRect(full_image_rect), + kNone_SkFilterQuality, SkMatrix::I()); + ImageKey original_size_key = + ImageKey::FromDrawImage(original_size_draw_image); + // Sanity checks. + DCHECK(original_size_key.can_use_original_decode()) + << original_size_key.ToString(); + DCHECK(full_image_rect.size() == original_size_key.target_size()); + + auto decoded_draw_image = GetDecodedImageForDrawInternal( + original_size_key, original_size_draw_image); + if (!decoded_draw_image.image()) { + DrawWithImageFinished(original_size_draw_image, decoded_draw_image); + return nullptr; + } + + SkPixmap decoded_pixmap; + bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap); + DCHECK(result) << key.ToString(); + if (key.src_rect() != full_image_rect) { + result = decoded_pixmap.extractSubset(&decoded_pixmap, + gfx::RectToSkIRect(key.src_rect())); + DCHECK(result) << key.ToString(); + } + + DCHECK(!key.target_size().IsEmpty()); + SkImageInfo scaled_info = CreateImageInfo( + key.target_size().width(), key.target_size().height(), format_); + std::unique_ptr<base::DiscardableMemory> scaled_pixels; + { + TRACE_EVENT0( + "disabled-by-default-cc.debug", + "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels"); + scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() + ->AllocateLockedDiscardableMemory( + scaled_info.minRowBytes() * scaled_info.height()); + } + SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), + scaled_info.minRowBytes()); + DCHECK(key.filter_quality() == kHigh_SkFilterQuality || + key.filter_quality() == kMedium_SkFilterQuality); + { + TRACE_EVENT0("disabled-by-default-cc.debug", + "SoftwareImageDecodeController::ScaleImage - scale pixels"); + bool result = + decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); + DCHECK(result) << key.ToString(); + } + + // Release the original sized decode. Any other intermediate result to release + // would be the subrect memory. However, that's in a scoped_ptr and will be + // deleted automatically when we return. + DrawWithImageFinished(original_size_draw_image, decoded_draw_image); + + return base::WrapUnique( + new DecodedImage(scaled_info, std::move(scaled_pixels), + SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), + next_tracing_id_.GetNext())); +} + void SoftwareImageDecodeController::DrawWithImageFinished( const DrawImage& image, const DecodedDrawImage& decoded_image) { @@ -619,7 +640,7 @@ void SoftwareImageDecodeController::DrawWithImageFinished( "SoftwareImageDecodeController::DrawWithImageFinished", "key", ImageKey::FromDrawImage(image).ToString()); ImageKey key = ImageKey::FromDrawImage(image); - if (!decoded_image.image() || !CanHandleImage(key)) + if (!decoded_image.image()) return; if (decoded_image.is_at_raster_decode()) @@ -686,11 +707,6 @@ void SoftwareImageDecodeController::UnrefAtRasterImage(const ImageKey& key) { } } -bool SoftwareImageDecodeController::CanHandleImage(const ImageKey& key) { - // TODO(vmpstr): Start handling medium filter quality as well. - return key.filter_quality() != kMedium_SkFilterQuality; -} - void SoftwareImageDecodeController::ReduceCacheUsage() { TRACE_EVENT0("cc", "SoftwareImageDecodeController::ReduceCacheUsage"); base::AutoLock lock(lock_); @@ -842,6 +858,14 @@ ImageDecodeControllerKey ImageDecodeControllerKey::FromDrawImage( if (can_use_original_decode && !target_size.IsEmpty()) target_size = gfx::Size(image.image()->width(), image.image()->height()); + if (quality == kMedium_SkFilterQuality && !target_size.IsEmpty()) { + SkSize mip_target_size = + GetMipMapScaleAdjustment(src_rect.size(), target_size); + DCHECK(mip_target_size.width() != -1.f && mip_target_size.height() != -1.f); + target_size.set_width(src_rect.width() * mip_target_size.width()); + target_size.set_height(src_rect.height() * mip_target_size.height()); + } + return ImageDecodeControllerKey(image.image()->uniqueID(), src_rect, target_size, quality, can_use_original_decode); @@ -893,7 +917,7 @@ std::string ImageDecodeControllerKey::ToString() const { // DecodedImage SoftwareImageDecodeController::DecodedImage::DecodedImage( const SkImageInfo& info, - scoped_ptr<base::DiscardableMemory> memory, + std::unique_ptr<base::DiscardableMemory> memory, const SkSize& src_rect_offset, uint64_t tracing_id) : locked_(true), @@ -901,9 +925,9 @@ SoftwareImageDecodeController::DecodedImage::DecodedImage( memory_(std::move(memory)), src_rect_offset_(src_rect_offset), tracing_id_(tracing_id) { - image_ = skia::AdoptRef(SkImage::NewFromRaster( - image_info_, memory_->data(), image_info_.minRowBytes(), - [](const void* pixels, void* context) {}, nullptr)); + SkPixmap pixmap(image_info_, memory_->data(), image_info_.minRowBytes()); + image_ = SkImage::MakeFromRaster( + pixmap, [](const void* pixels, void* context) {}, nullptr); } SoftwareImageDecodeController::DecodedImage::~DecodedImage() { diff --git a/chromium/cc/tiles/software_image_decode_controller.h b/chromium/cc/tiles/software_image_decode_controller.h index baf99f0a6d0..14632aad610 100644 --- a/chromium/cc/tiles/software_image_decode_controller.h +++ b/chromium/cc/tiles/software_image_decode_controller.h @@ -7,6 +7,7 @@ #include <stdint.h> +#include <memory> #include <unordered_map> #include <unordered_set> @@ -21,9 +22,9 @@ #include "cc/base/cc_export.h" #include "cc/playback/decoded_draw_image.h" #include "cc/playback/draw_image.h" -#include "cc/raster/tile_task_runner.h" +#include "cc/resources/resource_format.h" #include "cc/tiles/image_decode_controller.h" -#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkRefCnt.h" namespace cc { @@ -108,13 +109,16 @@ class CC_EXPORT SoftwareImageDecodeController // ImageDecodeController overrides. bool GetTaskForImageAndRef(const DrawImage& image, - uint64_t prepare_tiles_id, - scoped_refptr<ImageDecodeTask>* task) override; + const TracingInfo& tracing_info, + scoped_refptr<TileTask>* task) override; void UnrefImage(const DrawImage& image) override; DecodedDrawImage GetDecodedImageForDraw(const DrawImage& image) override; void DrawWithImageFinished(const DrawImage& image, const DecodedDrawImage& decoded_image) override; void ReduceCacheUsage() override; + // Software doesn't keep outstanding images pinned, so this is a no-op. + void SetShouldAggressivelyFreeResources( + bool aggressively_free_resources) override {} // Decode the given image and store it in the cache. This is only called by an // image decode task from a worker thread. @@ -132,14 +136,14 @@ class CC_EXPORT SoftwareImageDecodeController class DecodedImage { public: DecodedImage(const SkImageInfo& info, - scoped_ptr<base::DiscardableMemory> memory, + std::unique_ptr<base::DiscardableMemory> memory, const SkSize& src_rect_offset, uint64_t tracing_id); ~DecodedImage(); - SkImage* image() const { + const sk_sp<SkImage>& image() const { DCHECK(locked_); - return image_.get(); + return image_; } const SkSize& src_rect_offset() const { return src_rect_offset_; } @@ -157,8 +161,8 @@ class CC_EXPORT SoftwareImageDecodeController private: bool locked_; SkImageInfo image_info_; - scoped_ptr<base::DiscardableMemory> memory_; - skia::RefPtr<SkImage> image_; + std::unique_ptr<base::DiscardableMemory> memory_; + sk_sp<SkImage> image_; SkSize src_rect_offset_; uint64_t tracing_id_; }; @@ -181,8 +185,9 @@ class CC_EXPORT SoftwareImageDecodeController base::CheckedNumeric<size_t> current_usage_bytes_; }; - using ImageMRUCache = - base::HashingMRUCache<ImageKey, scoped_ptr<DecodedImage>, ImageKeyHash>; + using ImageMRUCache = base::HashingMRUCache<ImageKey, + std::unique_ptr<DecodedImage>, + ImageKeyHash>; // Looks for the key in the cache and returns true if it was found and was // successfully locked (or if it was already locked). Note that if this @@ -192,8 +197,9 @@ class CC_EXPORT SoftwareImageDecodeController // Actually decode the image. Note that this function can (and should) be // called with no lock acquired, since it can do a lot of work. Note that it // can also return nullptr to indicate the decode failed. - scoped_ptr<DecodedImage> DecodeImageInternal(const ImageKey& key, - const DrawImage& draw_image); + std::unique_ptr<DecodedImage> DecodeImageInternal( + const ImageKey& key, + const DrawImage& draw_image); // Get the decoded draw image for the given key and draw_image. Note that this // function has to be called with no lock acquired, since it will acquire its @@ -205,24 +211,32 @@ class CC_EXPORT SoftwareImageDecodeController DecodedDrawImage GetDecodedImageForDrawInternal(const ImageKey& key, const DrawImage& draw_image); + // GetOriginalImageDecode is called by DecodeImageInternal when the quality + // does not scale the image. Like DecodeImageInternal, it should be called + // with no lock acquired and it returns nullptr if the decoding failed. + std::unique_ptr<DecodedImage> GetOriginalImageDecode( + const ImageKey& key, + sk_sp<const SkImage> image); + + // GetScaledImageDecode is called by DecodeImageInternal when the quality + // requires the image be scaled. Like DecodeImageInternal, it should be + // called with no lock acquired and it returns nullptr if the decoding or + // scaling failed. + std::unique_ptr<DecodedImage> GetScaledImageDecode( + const ImageKey& key, + sk_sp<const SkImage> image); + void SanityCheckState(int line, bool lock_acquired); void RefImage(const ImageKey& key); void RefAtRasterImage(const ImageKey& key); void UnrefAtRasterImage(const ImageKey& key); - // These functions indicate whether the images can be handled and cached by - // ImageDecodeController or whether they will fall through to Skia (with - // exception of possibly prerolling them). Over time these should return - // "false" in less cases, as the ImageDecodeController should start handling - // more of them. - bool CanHandleImage(const ImageKey& key); - // Helper function which dumps all images in a specific ImageMRUCache. void DumpImageMemoryForCache(const ImageMRUCache& cache, const char* cache_name, base::trace_event::ProcessMemoryDump* pmd) const; - std::unordered_map<ImageKey, scoped_refptr<ImageDecodeTask>, ImageKeyHash> + std::unordered_map<ImageKey, scoped_refptr<TileTask>, ImageKeyHash> pending_image_tasks_; // The members below this comment can only be accessed if the lock is held to @@ -240,11 +254,6 @@ class CC_EXPORT SoftwareImageDecodeController MemoryBudget locked_images_budget_; - // Note that this is used for cases where the only thing we do is preroll the - // image the first time we see it. This mimics the previous behavior and - // should over time change as the compositor starts to handle more cases. - std::unordered_set<uint32_t> prerolled_images_; - ResourceFormat format_; // Used to uniquely identify DecodedImages for memory traces. diff --git a/chromium/cc/tiles/software_image_decode_controller_unittest.cc b/chromium/cc/tiles/software_image_decode_controller_unittest.cc index 38246b38398..6a5d55044db 100644 --- a/chromium/cc/tiles/software_image_decode_controller_unittest.cc +++ b/chromium/cc/tiles/software_image_decode_controller_unittest.cc @@ -5,16 +5,17 @@ #include "cc/tiles/software_image_decode_controller.h" #include "cc/playback/draw_image.h" +#include "cc/raster/tile_task.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkRefCnt.h" namespace cc { namespace { -skia::RefPtr<SkImage> CreateImage(int width, int height) { - SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); +sk_sp<SkImage> CreateImage(int width, int height) { SkBitmap bitmap; - bitmap.allocPixels(info); - return skia::AdoptRef(SkImage::NewFromBitmap(bitmap)); + bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); + return SkImage::MakeFromBitmap(bitmap); } SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) { @@ -30,12 +31,12 @@ SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) { } TEST(SoftwareImageDecodeControllerTest, ImageKeyLowQuality) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality qualities[] = {kNone_SkFilterQuality, kLow_SkFilterQuality}; for (auto quality : qualities) { DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); @@ -51,32 +52,32 @@ TEST(SoftwareImageDecodeControllerTest, ImageKeyLowQuality) { } TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQuality) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kMedium_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); EXPECT_EQ(quality, key.filter_quality()); - EXPECT_EQ(50, key.target_size().width()); - EXPECT_EQ(150, key.target_size().height()); + EXPECT_EQ(100, key.target_size().width()); + EXPECT_EQ(100, key.target_size().height()); EXPECT_FALSE(key.can_use_original_decode()); - EXPECT_EQ(50u * 150u * 4u, key.locked_bytes()); + EXPECT_EQ(100u * 100u * 4u, key.locked_bytes()); } TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityDropToLowIfEnlarging) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kMedium_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); @@ -89,13 +90,13 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityDropToLowIfIdentity) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kMedium_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); @@ -108,12 +109,12 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityDropToLowIfNearlyIdentity) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kMedium_SkFilterQuality; DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); @@ -127,12 +128,12 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityDropToLowIfNearlyIdentity2) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kMedium_SkFilterQuality; DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); @@ -146,13 +147,13 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityDropToLowIfNotDecomposable) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = false; SkFilterQuality quality = kMedium_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); @@ -163,14 +164,140 @@ TEST(SoftwareImageDecodeControllerTest, EXPECT_EQ(100u * 100u * 4u, key.locked_bytes()); } +TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityAt1_5Scale) { + sk_sp<SkImage> image = CreateImage(500, 200); + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable)); + + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); + EXPECT_EQ(image->uniqueID(), key.image_id()); + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality()); + EXPECT_EQ(500, key.target_size().width()); + EXPECT_EQ(200, key.target_size().height()); + EXPECT_TRUE(key.can_use_original_decode()); + EXPECT_EQ(500u * 200u * 4u, key.locked_bytes()); +} + +TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityAt1_0cale) { + sk_sp<SkImage> image = CreateImage(500, 200); + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); + EXPECT_EQ(image->uniqueID(), key.image_id()); + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality()); + EXPECT_EQ(500, key.target_size().width()); + EXPECT_EQ(200, key.target_size().height()); + EXPECT_TRUE(key.can_use_original_decode()); + EXPECT_EQ(500u * 200u * 4u, key.locked_bytes()); +} + +TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityAt0_75Scale) { + sk_sp<SkImage> image = CreateImage(500, 200); + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + DrawImage draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable)); + + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); + EXPECT_EQ(image->uniqueID(), key.image_id()); + EXPECT_EQ(quality, key.filter_quality()); + EXPECT_EQ(500, key.target_size().width()); + EXPECT_EQ(200, key.target_size().height()); + EXPECT_FALSE(key.can_use_original_decode()); + EXPECT_EQ(500u * 200u * 4u, key.locked_bytes()); +} + +TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityAt0_5Scale) { + sk_sp<SkImage> image = CreateImage(500, 200); + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); + EXPECT_EQ(image->uniqueID(), key.image_id()); + EXPECT_EQ(quality, key.filter_quality()); + EXPECT_EQ(250, key.target_size().width()); + EXPECT_EQ(100, key.target_size().height()); + EXPECT_FALSE(key.can_use_original_decode()); + EXPECT_EQ(250u * 100u * 4u, key.locked_bytes()); +} + +TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityAt0_49Scale) { + sk_sp<SkImage> image = CreateImage(500, 200); + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + DrawImage draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable)); + + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); + EXPECT_EQ(image->uniqueID(), key.image_id()); + EXPECT_EQ(quality, key.filter_quality()); + EXPECT_EQ(250, key.target_size().width()); + EXPECT_EQ(100, key.target_size().height()); + EXPECT_FALSE(key.can_use_original_decode()); + EXPECT_EQ(250u * 100u * 4u, key.locked_bytes()); +} + +TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityAt0_1Scale) { + sk_sp<SkImage> image = CreateImage(500, 200); + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable)); + + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); + EXPECT_EQ(image->uniqueID(), key.image_id()); + EXPECT_EQ(quality, key.filter_quality()); + EXPECT_EQ(62, key.target_size().width()); + EXPECT_EQ(25, key.target_size().height()); + EXPECT_FALSE(key.can_use_original_decode()); + EXPECT_EQ(62u * 25u * 4u, key.locked_bytes()); +} + +TEST(SoftwareImageDecodeControllerTest, ImageKeyMediumQualityAt0_01Scale) { + sk_sp<SkImage> image = CreateImage(500, 200); + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + DrawImage draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable)); + + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); + EXPECT_EQ(image->uniqueID(), key.image_id()); + EXPECT_EQ(quality, key.filter_quality()); + EXPECT_EQ(7, key.target_size().width()); + EXPECT_EQ(3, key.target_size().height()); + EXPECT_FALSE(key.can_use_original_decode()); + EXPECT_EQ(7u * 3u * 4u, key.locked_bytes()); +} + TEST(SoftwareImageDecodeControllerTest, ImageKeyHighQuality) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); @@ -184,34 +311,34 @@ TEST(SoftwareImageDecodeControllerTest, ImageKeyHighQuality) { TEST(SoftwareImageDecodeControllerTest, ImageKeyHighQualityDropToMediumIfTooLarge) { // Just over 64MB when scaled. - skia::RefPtr<SkImage> image = CreateImage(4555, 2048); + sk_sp<SkImage> image = CreateImage(4555, 2048); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; // At least one dimension should scale down, so that medium quality doesn't // become low. - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.9f, 2.f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.9f, 2.f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); EXPECT_EQ(kMedium_SkFilterQuality, key.filter_quality()); - EXPECT_EQ(4100, key.target_size().width()); - EXPECT_EQ(4096, key.target_size().height()); + EXPECT_EQ(4555, key.target_size().width()); + EXPECT_EQ(2048, key.target_size().height()); EXPECT_FALSE(key.can_use_original_decode()); - EXPECT_EQ(4100u * 4096u * 4u, key.locked_bytes()); + EXPECT_EQ(4555u * 2048u * 4u, key.locked_bytes()); } TEST(SoftwareImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfNotDecomposable) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = false; SkFilterQuality quality = kHigh_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); @@ -224,13 +351,13 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfIdentity) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); @@ -243,12 +370,12 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfNearlyIdentity) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); @@ -262,12 +389,12 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfNearlyIdentity2) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); @@ -280,13 +407,13 @@ TEST(SoftwareImageDecodeControllerTest, } TEST(SoftwareImageDecodeControllerTest, OriginalDecodesAreEqual) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kLow_SkFilterQuality; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5), is_decomposable)); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); EXPECT_EQ(image->uniqueID(), key.image_id()); @@ -297,7 +424,7 @@ TEST(SoftwareImageDecodeControllerTest, OriginalDecodesAreEqual) { EXPECT_EQ(100u * 100u * 4u, key.locked_bytes()); DrawImage another_draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(1.5f, 1.5), is_decomposable)); auto another_key = @@ -313,12 +440,12 @@ TEST(SoftwareImageDecodeControllerTest, OriginalDecodesAreEqual) { } TEST(SoftwareImageDecodeControllerTest, ImageRectDoesNotContainSrcRect) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image( - image.get(), SkIRect::MakeXYWH(25, 35, image->width(), image->height()), + image, SkIRect::MakeXYWH(25, 35, image->width(), image->height()), quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); @@ -332,12 +459,12 @@ TEST(SoftwareImageDecodeControllerTest, ImageRectDoesNotContainSrcRect) { TEST(SoftwareImageDecodeControllerTest, ImageRectDoesNotContainSrcRectWithScale) { - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image( - image.get(), SkIRect::MakeXYWH(20, 30, image->width(), image->height()), + image, SkIRect::MakeXYWH(20, 30, image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); auto key = ImageDecodeControllerKey::FromDrawImage(draw_image); @@ -351,26 +478,25 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, GetTaskForImageSameImage) { SoftwareImageDecodeController controller; - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - uint64_t prepare_tiles_id = 1; - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); DrawImage another_draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> another_task; + scoped_refptr<TileTask> another_task; need_unref = controller.GetTaskForImageAndRef( - another_draw_image, prepare_tiles_id, &another_task); + another_draw_image, ImageDecodeController::TracingInfo(), &another_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task.get() == another_task.get()); @@ -381,72 +507,73 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageSameImage) { TEST(SoftwareImageDecodeControllerTest, GetTaskForImageSameImageDifferentQuality) { SoftwareImageDecodeController controller; - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; DrawImage high_quality_draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), + image, SkIRect::MakeWH(image->width(), image->height()), kHigh_SkFilterQuality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> high_quality_task; + scoped_refptr<TileTask> high_quality_task; bool need_unref = controller.GetTaskForImageAndRef( - high_quality_draw_image, prepare_tiles_id, &high_quality_task); + high_quality_draw_image, ImageDecodeController::TracingInfo(), + &high_quality_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(high_quality_task); DrawImage medium_quality_draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), + image, SkIRect::MakeWH(image->width(), image->height()), kMedium_SkFilterQuality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> medium_quality_task; + scoped_refptr<TileTask> medium_quality_task; need_unref = controller.GetTaskForImageAndRef( - medium_quality_draw_image, prepare_tiles_id, &medium_quality_task); - // Medium quality isn't handled by the controller, so it won't ref it. Note - // that this will change when medium quality is handled and will need to be - // updated. - EXPECT_FALSE(need_unref); + medium_quality_draw_image, ImageDecodeController::TracingInfo(), + &medium_quality_task); + EXPECT_TRUE(need_unref); EXPECT_TRUE(medium_quality_task); EXPECT_TRUE(high_quality_task.get() != medium_quality_task.get()); DrawImage low_quality_draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), + image, SkIRect::MakeWH(image->width(), image->height()), kLow_SkFilterQuality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> low_quality_task; + scoped_refptr<TileTask> low_quality_task; need_unref = controller.GetTaskForImageAndRef( - low_quality_draw_image, prepare_tiles_id, &low_quality_task); + low_quality_draw_image, ImageDecodeController::TracingInfo(), + &low_quality_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(low_quality_task); EXPECT_TRUE(high_quality_task.get() != low_quality_task.get()); EXPECT_TRUE(medium_quality_task.get() != low_quality_task.get()); controller.UnrefImage(high_quality_draw_image); + controller.UnrefImage(medium_quality_draw_image); controller.UnrefImage(low_quality_draw_image); } TEST(SoftwareImageDecodeControllerTest, GetTaskForImageSameImageDifferentSize) { SoftwareImageDecodeController controller; - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage half_size_draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> half_size_task; + scoped_refptr<TileTask> half_size_task; bool need_unref = controller.GetTaskForImageAndRef( - half_size_draw_image, prepare_tiles_id, &half_size_task); + half_size_draw_image, ImageDecodeController::TracingInfo(), + &half_size_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(half_size_task); DrawImage quarter_size_draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, + image, SkIRect::MakeWH(image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable)); - scoped_refptr<ImageDecodeTask> quarter_size_task; + scoped_refptr<TileTask> quarter_size_task; need_unref = controller.GetTaskForImageAndRef( - quarter_size_draw_image, prepare_tiles_id, &quarter_size_task); + quarter_size_draw_image, ImageDecodeController::TracingInfo(), + &quarter_size_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(quarter_size_task); EXPECT_TRUE(half_size_task.get() != quarter_size_task.get()); @@ -458,28 +585,26 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageSameImageDifferentSize) { TEST(SoftwareImageDecodeControllerTest, GetTaskForImageDifferentImage) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> first_image = CreateImage(100, 100); + sk_sp<SkImage> first_image = CreateImage(100, 100); DrawImage first_draw_image( - first_image.get(), - SkIRect::MakeWH(first_image->width(), first_image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> first_task; + first_image, SkIRect::MakeWH(first_image->width(), first_image->height()), + quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> first_task; bool need_unref = controller.GetTaskForImageAndRef( - first_draw_image, prepare_tiles_id, &first_task); + first_draw_image, ImageDecodeController::TracingInfo(), &first_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(first_task); - skia::RefPtr<SkImage> second_image = CreateImage(100, 100); + sk_sp<SkImage> second_image = CreateImage(100, 100); DrawImage second_draw_image( - second_image.get(), + second_image, SkIRect::MakeWH(second_image->width(), second_image->height()), quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable)); - scoped_refptr<ImageDecodeTask> second_task; - need_unref = controller.GetTaskForImageAndRef(second_draw_image, - prepare_tiles_id, &second_task); + scoped_refptr<TileTask> second_task; + need_unref = controller.GetTaskForImageAndRef( + second_draw_image, ImageDecodeController::TracingInfo(), &second_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(second_task); EXPECT_TRUE(first_task.get() != second_task.get()); @@ -491,16 +616,15 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageDifferentImage) { TEST(SoftwareImageDecodeControllerTest, GetTaskForImageAlreadyDecoded) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -509,9 +633,9 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageAlreadyDecoded) { task->DidSchedule(); task->RunOnWorkerThread(); - scoped_refptr<ImageDecodeTask> another_task; - need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, - &another_task); + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); EXPECT_TRUE(need_unref); EXPECT_FALSE(another_task); @@ -526,16 +650,15 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageAlreadyDecoded) { TEST(SoftwareImageDecodeControllerTest, GetTaskForImageAlreadyPrerolled) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kLow_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -544,9 +667,9 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageAlreadyPrerolled) { task->DidSchedule(); task->RunOnWorkerThread(); - scoped_refptr<ImageDecodeTask> another_task; - need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, - &another_task); + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); EXPECT_TRUE(need_unref); EXPECT_FALSE(another_task); @@ -554,9 +677,9 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageAlreadyPrerolled) { task->CompleteOnOriginThread(nullptr); task->DidComplete(); - scoped_refptr<ImageDecodeTask> third_task; - need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, - &third_task); + scoped_refptr<TileTask> third_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &third_task); EXPECT_TRUE(need_unref); EXPECT_FALSE(third_task); @@ -568,16 +691,15 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageAlreadyPrerolled) { TEST(SoftwareImageDecodeControllerTest, GetTaskForImageCanceledGetsNewTask) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -585,9 +707,9 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageCanceledGetsNewTask) { task->ScheduleOnOriginThread(nullptr); task->DidSchedule(); - scoped_refptr<ImageDecodeTask> another_task; - need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, - &another_task); + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(another_task.get() == task.get()); @@ -601,9 +723,9 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageCanceledGetsNewTask) { controller.UnrefImage(draw_image); // Here a new task is created. - scoped_refptr<ImageDecodeTask> third_task; - need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, - &third_task); + scoped_refptr<TileTask> third_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &third_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(third_task); EXPECT_FALSE(third_task.get() == task.get()); @@ -615,16 +737,15 @@ TEST(SoftwareImageDecodeControllerTest, GetTaskForImageCanceledWhileReffedGetsNewTask) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -632,9 +753,9 @@ TEST(SoftwareImageDecodeControllerTest, task->ScheduleOnOriginThread(nullptr); task->DidSchedule(); - scoped_refptr<ImageDecodeTask> another_task; - need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, - &another_task); + scoped_refptr<TileTask> another_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &another_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(another_task.get() == task.get()); @@ -645,9 +766,9 @@ TEST(SoftwareImageDecodeControllerTest, // Note that here, everything is reffed, but a new task is created. This is // possible with repeated schedule/cancel operations. - scoped_refptr<ImageDecodeTask> third_task; - need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, - &third_task); + scoped_refptr<TileTask> third_task; + need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &third_task); EXPECT_TRUE(need_unref); EXPECT_TRUE(third_task); EXPECT_FALSE(third_task.get() == task.get()); @@ -661,16 +782,15 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, GetDecodedImageForDraw) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -703,16 +823,15 @@ TEST(SoftwareImageDecodeControllerTest, GetDecodedImageForDrawWithNonContainedSrcRect) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); DrawImage draw_image( - image.get(), SkIRect::MakeXYWH(20, 30, image->width(), image->height()), + image, SkIRect::MakeXYWH(20, 30, image->width(), image->height()), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -746,10 +865,10 @@ TEST(SoftwareImageDecodeControllerTest, GetDecodedImageForDrawAtRasterDecode) { bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); DecodedDrawImage decoded_draw_image = controller.GetDecodedImageForDraw(draw_image); @@ -771,10 +890,10 @@ TEST(SoftwareImageDecodeControllerTest, bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); DecodedDrawImage decoded_draw_image = controller.GetDecodedImageForDraw(draw_image); @@ -800,13 +919,12 @@ TEST(SoftwareImageDecodeControllerTest, GetDecodedImageForDrawAtRasterDecodeDoesNotPreventTasks) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); DecodedDrawImage decoded_draw_image = controller.GetDecodedImageForDraw(draw_image); @@ -819,9 +937,9 @@ TEST(SoftwareImageDecodeControllerTest, EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity()); EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -854,13 +972,12 @@ TEST(SoftwareImageDecodeControllerTest, GetDecodedImageForDrawAtRasterDecodeIsUsedForLockedCache) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); DecodedDrawImage decoded_draw_image = controller.GetDecodedImageForDraw(draw_image); @@ -873,9 +990,9 @@ TEST(SoftwareImageDecodeControllerTest, EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity()); EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(need_unref); EXPECT_TRUE(task); @@ -908,17 +1025,16 @@ TEST(SoftwareImageDecodeControllerTest, TEST(SoftwareImageDecodeControllerTest, ZeroSizedImagesAreSkipped) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable)); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_FALSE(task); EXPECT_FALSE(need_unref); @@ -932,17 +1048,16 @@ TEST(SoftwareImageDecodeControllerTest, ZeroSizedImagesAreSkipped) { TEST(SoftwareImageDecodeControllerTest, NonOverlappingSrcRectImagesAreSkipped) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kHigh_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); + sk_sp<SkImage> image = CreateImage(100, 100); DrawImage draw_image( - image.get(), SkIRect::MakeXYWH(150, 150, image->width(), image->height()), + image, SkIRect::MakeXYWH(150, 150, image->width(), image->height()), quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_FALSE(task); EXPECT_FALSE(need_unref); @@ -956,17 +1071,16 @@ TEST(SoftwareImageDecodeControllerTest, NonOverlappingSrcRectImagesAreSkipped) { TEST(SoftwareImageDecodeControllerTest, LowQualityFilterIsHandled) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kLow_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image( - image.get(), SkIRect::MakeWH(image->width(), image->height()), quality, - CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(task); EXPECT_TRUE(need_unref); @@ -975,7 +1089,7 @@ TEST(SoftwareImageDecodeControllerTest, LowQualityFilterIsHandled) { EXPECT_TRUE(decoded_draw_image.image()); // If we decoded the image and cached it, it would be stored in a different // SkImage object. - EXPECT_TRUE(decoded_draw_image.image() != image.get()); + EXPECT_TRUE(decoded_draw_image.image() != image); controller.DrawWithImageFinished(draw_image, decoded_draw_image); controller.UnrefImage(draw_image); @@ -984,16 +1098,15 @@ TEST(SoftwareImageDecodeControllerTest, LowQualityFilterIsHandled) { TEST(SoftwareImageDecodeControllerTest, LowQualityScaledSubrectIsHandled) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kLow_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image(image.get(), SkIRect::MakeXYWH(10, 10, 80, 80), quality, + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeXYWH(10, 10, 80, 80), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(task); EXPECT_TRUE(need_unref); @@ -1002,7 +1115,7 @@ TEST(SoftwareImageDecodeControllerTest, LowQualityScaledSubrectIsHandled) { EXPECT_TRUE(decoded_draw_image.image()); // If we decoded the image and cached it, it would be stored in a different // SkImage object. - EXPECT_TRUE(decoded_draw_image.image() != image.get()); + EXPECT_TRUE(decoded_draw_image.image() != image); EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); EXPECT_TRUE(decoded_draw_image.is_scale_adjustment_identity()); @@ -1013,16 +1126,15 @@ TEST(SoftwareImageDecodeControllerTest, LowQualityScaledSubrectIsHandled) { TEST(SoftwareImageDecodeControllerTest, NoneQualityScaledSubrectIsHandled) { SoftwareImageDecodeController controller; bool is_decomposable = true; - uint64_t prepare_tiles_id = 1; SkFilterQuality quality = kNone_SkFilterQuality; - skia::RefPtr<SkImage> image = CreateImage(100, 100); - DrawImage draw_image(image.get(), SkIRect::MakeXYWH(10, 10, 80, 80), quality, + sk_sp<SkImage> image = CreateImage(100, 100); + DrawImage draw_image(image, SkIRect::MakeXYWH(10, 10, 80, 80), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); - scoped_refptr<ImageDecodeTask> task; - bool need_unref = - controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task); + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); EXPECT_TRUE(task); EXPECT_TRUE(need_unref); @@ -1031,12 +1143,296 @@ TEST(SoftwareImageDecodeControllerTest, NoneQualityScaledSubrectIsHandled) { EXPECT_TRUE(decoded_draw_image.image()); // If we decoded the image and cached it, it would be stored in a different // SkImage object. - EXPECT_TRUE(decoded_draw_image.image() != image.get()); + EXPECT_TRUE(decoded_draw_image.image() != image); EXPECT_EQ(kNone_SkFilterQuality, decoded_draw_image.filter_quality()); EXPECT_TRUE(decoded_draw_image.is_scale_adjustment_identity()); controller.DrawWithImageFinished(draw_image, decoded_draw_image); controller.UnrefImage(draw_image); } + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt01_5ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); + EXPECT_EQ(500, decoded_draw_image.image()->width()); + EXPECT_EQ(200, decoded_draw_image.image()->height()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt1_0ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); + EXPECT_EQ(500, decoded_draw_image.image()->width()); + EXPECT_EQ(200, decoded_draw_image.image()->height()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt0_75ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); + EXPECT_EQ(500, decoded_draw_image.image()->width()); + EXPECT_EQ(200, decoded_draw_image.image()->height()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt0_5ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); + EXPECT_EQ(250, decoded_draw_image.image()->width()); + EXPECT_EQ(100, decoded_draw_image.image()->height()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt0_49ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); + EXPECT_EQ(250, decoded_draw_image.image()->width()); + EXPECT_EQ(100, decoded_draw_image.image()->height()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt0_1ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), + quality, + CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); + EXPECT_EQ(62, decoded_draw_image.image()->width()); + EXPECT_EQ(25, decoded_draw_image.image()->height()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt0_01ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_TRUE(task); + EXPECT_TRUE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_TRUE(decoded_draw_image.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality()); + EXPECT_EQ(7, decoded_draw_image.image()->width()); + EXPECT_EQ(3, decoded_draw_image.image()->height()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); + controller.UnrefImage(draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, MediumQualityAt0_001ScaleIsHandled) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.001f, 0.001f), is_decomposable)); + + scoped_refptr<TileTask> task; + bool need_unref = controller.GetTaskForImageAndRef( + draw_image, ImageDecodeController::TracingInfo(), &task); + EXPECT_FALSE(task); + EXPECT_FALSE(need_unref); + + DecodedDrawImage decoded_draw_image = + controller.GetDecodedImageForDraw(draw_image); + EXPECT_FALSE(decoded_draw_image.image()); + + controller.DrawWithImageFinished(draw_image, decoded_draw_image); +} + +TEST(SoftwareImageDecodeControllerTest, + MediumQualityImagesAreTheSameAt0_5And0_49Scale) { + SoftwareImageDecodeController controller; + bool is_decomposable = true; + SkFilterQuality quality = kMedium_SkFilterQuality; + + sk_sp<SkImage> image = CreateImage(500, 200); + DrawImage draw_image_50( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); + DrawImage draw_image_49( + image, SkIRect::MakeWH(image->width(), image->height()), quality, + CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable)); + + scoped_refptr<TileTask> task_50; + bool need_unref_50 = controller.GetTaskForImageAndRef( + draw_image_50, ImageDecodeController::TracingInfo(), &task_50); + EXPECT_TRUE(task_50); + EXPECT_TRUE(need_unref_50); + scoped_refptr<TileTask> task_49; + bool need_unref_49 = controller.GetTaskForImageAndRef( + draw_image_49, ImageDecodeController::TracingInfo(), &task_49); + EXPECT_TRUE(task_49); + EXPECT_TRUE(need_unref_49); + + DecodedDrawImage decoded_draw_image_50 = + controller.GetDecodedImageForDraw(draw_image_50); + EXPECT_TRUE(decoded_draw_image_50.image()); + DecodedDrawImage decoded_draw_image_49 = + controller.GetDecodedImageForDraw(draw_image_49); + EXPECT_TRUE(decoded_draw_image_49.image()); + // If we decoded the image and cached it, it would be stored in a different + // SkImageObject. + EXPECT_TRUE(decoded_draw_image_50.image() != image); + EXPECT_TRUE(decoded_draw_image_49.image() != image); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image_50.filter_quality()); + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image_49.filter_quality()); + EXPECT_EQ(250, decoded_draw_image_50.image()->width()); + EXPECT_EQ(250, decoded_draw_image_49.image()->width()); + EXPECT_EQ(100, decoded_draw_image_50.image()->height()); + EXPECT_EQ(100, decoded_draw_image_49.image()->height()); + + EXPECT_EQ(decoded_draw_image_50.image(), decoded_draw_image_49.image()); + + controller.DrawWithImageFinished(draw_image_50, decoded_draw_image_50); + controller.UnrefImage(draw_image_50); + controller.DrawWithImageFinished(draw_image_49, decoded_draw_image_49); + controller.UnrefImage(draw_image_49); +} + } // namespace } // namespace cc diff --git a/chromium/cc/tiles/tile.h b/chromium/cc/tiles/tile.h index 99497f3ad20..76142e86699 100644 --- a/chromium/cc/tiles/tile.h +++ b/chromium/cc/tiles/tile.h @@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "cc/raster/tile_task.h" #include "cc/tiles/tile_draw_info.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -144,12 +145,12 @@ class CC_EXPORT Tile { unsigned scheduled_priority_; - scoped_refptr<RasterTask> raster_task_; + scoped_refptr<TileTask> raster_task_; DISALLOW_COPY_AND_ASSIGN(Tile); }; -using ScopedTilePtr = scoped_ptr<Tile, Tile::Deleter>; +using ScopedTilePtr = std::unique_ptr<Tile, Tile::Deleter>; } // namespace cc diff --git a/chromium/cc/tiles/tile_draw_info.h b/chromium/cc/tiles/tile_draw_info.h index 6d694ebf1e2..084f4378d87 100644 --- a/chromium/cc/tiles/tile_draw_info.h +++ b/chromium/cc/tiles/tile_draw_info.h @@ -5,9 +5,9 @@ #ifndef CC_TILES_TILE_DRAW_INFO_H_ #define CC_TILES_TILE_DRAW_INFO_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "base/trace_event/trace_event_argument.h" -#include "cc/raster/tile_task_runner.h" #include "cc/resources/platform_color.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_resource.h" diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc index 68408e4ded0..58fc640d8dd 100644 --- a/chromium/cc/tiles/tile_manager.cc +++ b/chromium/cc/tiles/tile_manager.cc @@ -15,6 +15,7 @@ #include "base/json/json_writer.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" #include "base/numerics/safe_conversions.h" #include "base/trace_event/trace_event_argument.h" @@ -25,7 +26,6 @@ #include "cc/layers/picture_layer_impl.h" #include "cc/raster/raster_buffer.h" #include "cc/raster/task_category.h" -#include "cc/raster/tile_task_runner.h" #include "cc/tiles/tile.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -41,7 +41,7 @@ DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER( "Compositing.%s.RasterTask.RasterUs", "Compositing.%s.RasterTask.RasterPixelsPerMs"); -class RasterTaskImpl : public RasterTask { +class RasterTaskImpl : public TileTask { public: RasterTaskImpl(const Resource* resource, scoped_refptr<RasterSource> raster_source, @@ -58,8 +58,9 @@ class RasterTaskImpl : public RasterTask { uint64_t resource_content_id, int source_frame_number, const base::Callback<void(bool)>& reply, - ImageDecodeTask::Vector* dependencies) - : RasterTask(dependencies), + TileTask::Vector* dependencies, + bool supports_concurrent_execution) + : TileTask(supports_concurrent_execution, dependencies), resource_(resource), raster_source_(std::move(raster_source)), content_rect_(content_rect), @@ -97,14 +98,14 @@ class RasterTaskImpl : public RasterTask { } // Overridden from TileTask: - void ScheduleOnOriginThread(TileTaskClient* client) override { + void ScheduleOnOriginThread(RasterBufferProvider* provider) override { DCHECK(!raster_buffer_); - raster_buffer_ = client->AcquireBufferForRaster( + raster_buffer_ = provider->AcquireBufferForRaster( resource_, resource_content_id_, previous_content_id_); } - void CompleteOnOriginThread(TileTaskClient* client) override { - client->ReleaseBufferForRaster(std::move(raster_buffer_)); - reply_.Run(!HasFinishedRunning()); + void CompleteOnOriginThread(RasterBufferProvider* provider) override { + provider->ReleaseBufferForRaster(std::move(raster_buffer_)); + reply_.Run(!state().IsFinished()); } protected: @@ -126,11 +127,36 @@ class RasterTaskImpl : public RasterTask { uint64_t resource_content_id_; int source_frame_number_; const base::Callback<void(bool)> reply_; - scoped_ptr<RasterBuffer> raster_buffer_; + std::unique_ptr<RasterBuffer> raster_buffer_; DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); }; +TaskCategory TaskCategoryForTileTask(TileTask* task, + bool use_foreground_category) { + if (!task->supports_concurrent_execution()) + return TASK_CATEGORY_NONCONCURRENT_FOREGROUND; + + if (use_foreground_category) + return TASK_CATEGORY_FOREGROUND; + + return TASK_CATEGORY_BACKGROUND; +} + +bool IsForegroundCategory(uint16_t category) { + TaskCategory enum_category = static_cast<TaskCategory>(category); + switch (enum_category) { + case TASK_CATEGORY_NONCONCURRENT_FOREGROUND: + case TASK_CATEGORY_FOREGROUND: + return true; + case TASK_CATEGORY_BACKGROUND: + return false; + } + + DCHECK(false); + return false; +} + // Task priorities that make sure that the task set done tasks run before any // other remaining tasks. const size_t kRequiredForActivationDoneTaskPriority = 1u; @@ -154,35 +180,37 @@ void InsertNodeForTask(TaskGraph* graph, TaskGraph::Node(task, category, priority, dependencies)); } +void InsertNodeForDecodeTask(TaskGraph* graph, + TileTask* task, + bool use_foreground_category, + uint16_t priority) { + uint32_t dependency_count = 0u; + if (task->dependencies().size()) { + DCHECK_EQ(task->dependencies().size(), 1u); + auto* dependency = task->dependencies()[0].get(); + if (!dependency->HasCompleted()) { + InsertNodeForDecodeTask(graph, dependency, use_foreground_category, + priority); + graph->edges.push_back(TaskGraph::Edge(dependency, task)); + dependency_count = 1u; + } + } + InsertNodeForTask(graph, task, + TaskCategoryForTileTask(task, use_foreground_category), + priority, dependency_count); +} + void InsertNodesForRasterTask(TaskGraph* graph, - RasterTask* raster_task, - const ImageDecodeTask::Vector& decode_tasks, + TileTask* raster_task, + const TileTask::Vector& decode_tasks, size_t priority, - bool use_gpu_rasterization, - bool high_priority) { + bool use_foreground_category) { size_t dependencies = 0u; - // Determine the TaskCategory for raster tasks - if a task uses GPU, it - // cannot run concurrently and is assigned - // TASK_CATEGORY_NONCONCURRENT_FOREGROUND, regardless of its priority. - // Otherwise its category is based on its priority. - TaskCategory raster_task_category; - if (use_gpu_rasterization) { - raster_task_category = TASK_CATEGORY_NONCONCURRENT_FOREGROUND; - } else { - raster_task_category = - high_priority ? TASK_CATEGORY_FOREGROUND : TASK_CATEGORY_BACKGROUND; - } - - // Determine the TaskCategory for decode tasks. This category is based on - // the priority of the raster task which depends on it. - TaskCategory decode_task_category = - high_priority ? TASK_CATEGORY_FOREGROUND : TASK_CATEGORY_BACKGROUND; - // Insert image decode tasks. - for (ImageDecodeTask::Vector::const_iterator it = decode_tasks.begin(); + for (TileTask::Vector::const_iterator it = decode_tasks.begin(); it != decode_tasks.end(); ++it) { - ImageDecodeTask* decode_task = it->get(); + TileTask* decode_task = it->get(); // Skip if already decoded. if (decode_task->HasCompleted()) @@ -190,32 +218,37 @@ void InsertNodesForRasterTask(TaskGraph* graph, dependencies++; - // Add decode task if it doesn't already exists in graph. + // Add decode task if it doesn't already exist in graph. TaskGraph::Node::Vector::iterator decode_it = std::find_if(graph->nodes.begin(), graph->nodes.end(), [decode_task](const TaskGraph::Node& node) { return node.task == decode_task; }); - // In rare circumstances, a low priority task may come in before a high - // priority task. In these cases, upgrade any low-priority dependencies of - // the current task. + // In rare circumstances, a background category task may come in before a + // foreground category task. In these cases, upgrade any background category + // dependencies of the current task. // TODO(ericrk): Task iterators should be updated to avoid this. // crbug.com/594851 - if (decode_it != graph->nodes.end() && high_priority && - decode_it->category != decode_task_category) { - decode_it->category = decode_task_category; + // TODO(ericrk): This should handle dependencies recursively. + // crbug.com/605234 + if (decode_it != graph->nodes.end() && use_foreground_category && + !IsForegroundCategory(decode_it->category)) { + decode_it->category = TASK_CATEGORY_FOREGROUND; } if (decode_it == graph->nodes.end()) { - InsertNodeForTask(graph, decode_task, decode_task_category, priority, 0u); + InsertNodeForDecodeTask(graph, decode_task, use_foreground_category, + priority); } graph->edges.push_back(TaskGraph::Edge(decode_task, raster_task)); } - InsertNodeForTask(graph, raster_task, raster_task_category, priority, - dependencies); + InsertNodeForTask( + graph, raster_task, + TaskCategoryForTileTask(raster_task, use_foreground_category), priority, + dependencies); } class TaskSetFinishedTaskImpl : public TileTask { @@ -223,7 +256,8 @@ class TaskSetFinishedTaskImpl : public TileTask { explicit TaskSetFinishedTaskImpl( base::SequencedTaskRunner* task_runner, const base::Closure& on_task_set_finished_callback) - : task_runner_(task_runner), + : TileTask(true), + task_runner_(task_runner), on_task_set_finished_callback_(on_task_set_finished_callback) {} // Overridden from Task: @@ -233,8 +267,8 @@ class TaskSetFinishedTaskImpl : public TileTask { } // Overridden from TileTask: - void ScheduleOnOriginThread(TileTaskClient* client) override {} - void CompleteOnOriginThread(TileTaskClient* client) override {} + void ScheduleOnOriginThread(RasterBufferProvider* provider) override {} + void CompleteOnOriginThread(RasterBufferProvider* provider) override {} protected: ~TaskSetFinishedTaskImpl() override {} @@ -255,9 +289,9 @@ class TaskSetFinishedTaskImpl : public TileTask { RasterTaskCompletionStats::RasterTaskCompletionStats() : completed_count(0u), canceled_count(0u) {} -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); state->SetInteger("completed_count", base::saturated_cast<int>(stats.completed_count)); @@ -267,7 +301,7 @@ RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { } // static -scoped_ptr<TileManager> TileManager::Create( +std::unique_ptr<TileManager> TileManager::Create( TileManagerClient* client, base::SequencedTaskRunner* task_runner, size_t scheduled_raster_task_limit, @@ -275,7 +309,7 @@ scoped_ptr<TileManager> TileManager::Create( // TODO(vmpstr): |task_runner| is a raw pointer that is implicitly converted // into a scoped_refptr. Figure out whether to plumb a ref pointer or whether // tile manager can have a non-owning pointer and fix. - return make_scoped_ptr(new TileManager( + return base::WrapUnique(new TileManager( client, task_runner, scheduled_raster_task_limit, use_partial_raster)); } @@ -286,7 +320,7 @@ TileManager::TileManager(TileManagerClient* client, : client_(client), task_runner_(std::move(task_runner)), resource_pool_(nullptr), - tile_task_runner_(nullptr), + tile_task_manager_(nullptr), scheduled_raster_task_limit_(scheduled_raster_task_limit), use_partial_raster_(use_partial_raster), use_gpu_rasterization_(false), @@ -310,25 +344,25 @@ TileManager::~TileManager() { } void TileManager::FinishTasksAndCleanUp() { - if (!tile_task_runner_) + if (!tile_task_manager_) return; global_state_ = GlobalStateThatImpactsTilePriority(); // This cancels tasks if possible, finishes pending tasks, and release any // uninitialized resources. - tile_task_runner_->Shutdown(); + tile_task_manager_->Shutdown(); // Now that all tasks have been finished, we can clear any // |orphan_tasks_|. orphan_tasks_.clear(); - tile_task_runner_->CheckForCompletedTasks(); + tile_task_manager_->CheckForCompletedTasks(); FreeResourcesForReleasedTiles(); CleanUpReleasedTiles(); - tile_task_runner_ = nullptr; + tile_task_manager_ = nullptr; resource_pool_ = nullptr; more_tiles_need_prepare_check_notifier_.Cancel(); signals_check_notifier_.Cancel(); @@ -336,18 +370,18 @@ void TileManager::FinishTasksAndCleanUp() { } void TileManager::SetResources(ResourcePool* resource_pool, - TileTaskRunner* tile_task_runner, ImageDecodeController* image_decode_controller, + TileTaskManager* tile_task_manager, size_t scheduled_raster_task_limit, bool use_gpu_rasterization) { - DCHECK(!tile_task_runner_); - DCHECK(tile_task_runner); + DCHECK(!tile_task_manager_); + DCHECK(tile_task_manager); use_gpu_rasterization_ = use_gpu_rasterization; scheduled_raster_task_limit_ = scheduled_raster_task_limit; resource_pool_ = resource_pool; - tile_task_runner_ = tile_task_runner; image_decode_controller_ = image_decode_controller; + tile_task_manager_ = tile_task_manager; } void TileManager::Release(Tile* tile) { @@ -397,7 +431,7 @@ void TileManager::DidFinishRunningAllTileTasks() { TRACE_EVENT0("cc", "TileManager::DidFinishRunningAllTileTasks"); TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); DCHECK(resource_pool_); - DCHECK(tile_task_runner_); + DCHECK(tile_task_manager_); has_scheduled_tile_tasks_ = false; @@ -424,7 +458,7 @@ bool TileManager::PrepareTiles( TRACE_EVENT1("cc", "TileManager::PrepareTiles", "prepare_tiles_id", prepare_tiles_count_); - if (!tile_task_runner_) { + if (!tile_task_manager_) { TRACE_EVENT_INSTANT0("cc", "PrepareTiles aborted", TRACE_EVENT_SCOPE_THREAD); return false; @@ -436,7 +470,7 @@ bool TileManager::PrepareTiles( // We need to call CheckForCompletedTasks() once in-between each call // to ScheduleTasks() to prevent canceled tasks from being scheduled. if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { - tile_task_runner_->CheckForCompletedTasks(); + tile_task_manager_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; } @@ -444,7 +478,7 @@ bool TileManager::PrepareTiles( CleanUpReleasedTiles(); PrioritizedTileVector tiles_that_need_to_be_rasterized; - scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( + std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( client_->BuildRasterQueue(global_state_.tree_priority, RasterTilePriorityQueue::Type::ALL)); AssignGpuMemoryToTiles(raster_priority_queue.get(), @@ -468,12 +502,12 @@ bool TileManager::PrepareTiles( void TileManager::Flush() { TRACE_EVENT0("cc", "TileManager::Flush"); - if (!tile_task_runner_) { + if (!tile_task_manager_) { TRACE_EVENT_INSTANT0("cc", "Flush aborted", TRACE_EVENT_SCOPE_THREAD); return; } - tile_task_runner_->CheckForCompletedTasks(); + tile_task_manager_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; @@ -482,9 +516,9 @@ void TileManager::Flush() { flush_stats_ = RasterTaskCompletionStats(); } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TileManager::BasicStateAsValue() const { - scoped_ptr<base::trace_event::TracedValue> value( + std::unique_ptr<base::trace_event::TracedValue> value( new base::trace_event::TracedValue()); BasicStateAsValueInto(value.get()); return std::move(value); @@ -499,9 +533,9 @@ void TileManager::BasicStateAsValueInto( state->EndDictionary(); } -scoped_ptr<EvictionTilePriorityQueue> +std::unique_ptr<EvictionTilePriorityQueue> TileManager::FreeTileResourcesUntilUsageIsWithinLimit( - scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, + std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue, const MemoryUsage& limit, MemoryUsage* usage) { while (usage->Exceeds(limit)) { @@ -520,9 +554,9 @@ TileManager::FreeTileResourcesUntilUsageIsWithinLimit( return eviction_priority_queue; } -scoped_ptr<EvictionTilePriorityQueue> +std::unique_ptr<EvictionTilePriorityQueue> TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( - scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, + std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue, const MemoryUsage& limit, const TilePriority& other_priority, MemoryUsage* usage) { @@ -570,7 +604,7 @@ void TileManager::AssignGpuMemoryToTiles( TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); DCHECK(resource_pool_); - DCHECK(tile_task_runner_); + DCHECK(tile_task_manager_); // Maintain the list of released resources that can potentially be re-used // or deleted. If this operation becomes expensive too, only do this after @@ -591,7 +625,7 @@ void TileManager::AssignGpuMemoryToTiles( MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(), resource_pool_->resource_count()); - scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue; + std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue; for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -760,7 +794,7 @@ void TileManager::ScheduleTasks( if (!tile->raster_task_) tile->raster_task_ = CreateRasterTask(prioritized_tile); - RasterTask* task = tile->raster_task_.get(); + TileTask* task = tile->raster_task_.get(); DCHECK(!task->HasCompleted()); if (tile->required_for_activation()) { @@ -776,27 +810,28 @@ void TileManager::ScheduleTasks( all_count++; graph_.edges.push_back(TaskGraph::Edge(task, all_done_task.get())); - // A tile is high priority if it is either blocking future compositing - // (required for draw or required for activation), or if it has a priority - // bin of NOW for another reason (low resolution tiles). - bool high_priority = + // A tile should use a foreground task cateogry if it is either blocking + // future compositing (required for draw or required for activation), or if + // it has a priority bin of NOW for another reason (low resolution tiles). + bool use_foreground_category = tile->required_for_draw() || tile->required_for_activation() || prioritized_tile.priority().priority_bin == TilePriority::NOW; InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++, - use_gpu_rasterization_, high_priority); + use_foreground_category); } // Insert nodes for our task completion tasks. We enqueue these using - // FOREGROUND priority as they are relatively quick tasks and we'd like - // to trigger our callbacks quickly to aid in scheduling. + // NONCONCURRENT_FOREGROUND category this is the highest prioirty category and + // we'd like to run these tasks as soon as possible. InsertNodeForTask(&graph_, required_for_activation_done_task.get(), - TASK_CATEGORY_FOREGROUND, + TASK_CATEGORY_NONCONCURRENT_FOREGROUND, kRequiredForActivationDoneTaskPriority, required_for_activate_count); InsertNodeForTask(&graph_, required_for_draw_done_task.get(), - TASK_CATEGORY_FOREGROUND, kRequiredForDrawDoneTaskPriority, - required_for_draw_count); - InsertNodeForTask(&graph_, all_done_task.get(), TASK_CATEGORY_FOREGROUND, + TASK_CATEGORY_NONCONCURRENT_FOREGROUND, + kRequiredForDrawDoneTaskPriority, required_for_draw_count); + InsertNodeForTask(&graph_, all_done_task.get(), + TASK_CATEGORY_NONCONCURRENT_FOREGROUND, kAllDoneTaskPriority, all_count); // We must reduce the amount of unused resoruces before calling @@ -807,7 +842,7 @@ void TileManager::ScheduleTasks( // Schedule running of |raster_queue_|. This replaces any previously // scheduled tasks and effectively cancels all tasks not present // in |raster_queue_|. - tile_task_runner_->ScheduleTasks(&graph_); + tile_task_manager_->ScheduleTasks(&graph_); // It's now safe to clean up orphan tasks as raster worker pool is not // allowed to keep around unreferenced raster tasks after ScheduleTasks() has @@ -826,7 +861,7 @@ void TileManager::ScheduleTasks( ScheduledTasksStateAsValue()); } -scoped_refptr<RasterTask> TileManager::CreateRasterTask( +scoped_refptr<TileTask> TileManager::CreateRasterTask( const PrioritizedTile& prioritized_tile) { Tile* tile = prioritized_tile.tile(); @@ -853,7 +888,7 @@ scoped_refptr<RasterTask> TileManager::CreateRasterTask( prioritized_tile.priority().resolution == LOW_RESOLUTION; // Create and queue all image decode tasks that this tile depends on. - ImageDecodeTask::Vector decode_tasks; + TileTask::Vector decode_tasks; std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()]; images.clear(); if (!playback_settings.skip_images) { @@ -861,14 +896,15 @@ scoped_refptr<RasterTask> TileManager::CreateRasterTask( tile->enclosing_layer_rect(), tile->contents_scale(), &images); } - // TODO(vmpstr): We should disable image hijack canvas in - // |playback_settings| here if |images| is empty. - + // We can skip the image hijack canvas if we have no images. + playback_settings.use_image_hijack_canvas = !images.empty(); + ImageDecodeController::TracingInfo tracing_info( + prepare_tiles_count_, prioritized_tile.priority().priority_bin); for (auto it = images.begin(); it != images.end();) { - scoped_refptr<ImageDecodeTask> task; + scoped_refptr<TileTask> task; bool need_to_unref_when_finished = - image_decode_controller_->GetTaskForImageAndRef( - *it, prepare_tiles_count_, &task); + image_decode_controller_->GetTaskForImageAndRef(*it, tracing_info, + &task); if (task) decode_tasks.push_back(task); @@ -878,6 +914,7 @@ scoped_refptr<RasterTask> TileManager::CreateRasterTask( it = images.erase(it); } + bool supports_concurrent_execution = !use_gpu_rasterization_; return make_scoped_refptr(new RasterTaskImpl( resource, prioritized_tile.raster_source(), tile->content_rect(), tile->invalidated_content_rect(), tile->contents_scale(), @@ -887,7 +924,7 @@ scoped_refptr<RasterTask> TileManager::CreateRasterTask( tile->source_frame_number(), base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), tile->id(), resource), - &decode_tasks)); + &decode_tasks, supports_concurrent_execution)); } void TileManager::OnRasterTaskCompleted( @@ -937,7 +974,7 @@ ScopedTilePtr TileManager::CreateTile(const Tile::CreateInfo& info, int flags) { // We need to have a tile task worker pool to do anything meaningful with // tiles. - DCHECK(tile_task_runner_); + DCHECK(tile_task_manager_); ScopedTilePtr tile( new Tile(this, info, layer_id, source_frame_number, flags)); DCHECK(tiles_.find(tile->id()) == tiles_.end()); @@ -946,14 +983,14 @@ ScopedTilePtr TileManager::CreateTile(const Tile::CreateInfo& info, return tile; } -void TileManager::SetTileTaskRunnerForTesting( - TileTaskRunner* tile_task_runner) { - tile_task_runner_ = tile_task_runner; +void TileManager::SetTileTaskManagerForTesting( + TileTaskManager* tile_task_manager) { + tile_task_manager_ = tile_task_manager; } bool TileManager::AreRequiredTilesReadyToDraw( RasterTilePriorityQueue::Type type) const { - scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( + std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( client_->BuildRasterQueue(global_state_.tree_priority, type)); // It is insufficient to check whether the raster queue we constructed is // empty. The reason for this is that there are situations (rasterize on @@ -966,7 +1003,7 @@ bool TileManager::AreRequiredTilesReadyToDraw( } #if DCHECK_IS_ON() - scoped_ptr<RasterTilePriorityQueue> all_queue( + std::unique_ptr<RasterTilePriorityQueue> all_queue( client_->BuildRasterQueue(global_state_.tree_priority, type)); for (; !all_queue->IsEmpty(); all_queue->Pop()) { Tile* tile = all_queue->Top().tile(); @@ -991,7 +1028,7 @@ bool TileManager::IsReadyToDraw() const { void TileManager::CheckAndIssueSignals() { TRACE_EVENT0("cc", "TileManager::CheckAndIssueSignals"); - tile_task_runner_->CheckForCompletedTasks(); + tile_task_manager_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; // Ready to activate. @@ -1031,13 +1068,13 @@ void TileManager::CheckAndIssueSignals() { } void TileManager::CheckIfMoreTilesNeedToBePrepared() { - tile_task_runner_->CheckForCompletedTasks(); + tile_task_manager_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; // When OOM, keep re-assigning memory until we reach a steady state // where top-priority tiles are initialized. PrioritizedTileVector tiles_that_need_to_be_rasterized; - scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( + std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( client_->BuildRasterQueue(global_state_.tree_priority, RasterTilePriorityQueue::Type::ALL)); AssignGpuMemoryToTiles(raster_priority_queue.get(), @@ -1102,7 +1139,7 @@ void TileManager::CheckIfMoreTilesNeedToBePrepared() { } bool TileManager::MarkTilesOutOfMemory( - scoped_ptr<RasterTilePriorityQueue> queue) const { + std::unique_ptr<RasterTilePriorityQueue> queue) const { // Mark required tiles as OOM so that we can activate/draw without them. if (queue->IsEmpty()) return false; @@ -1118,16 +1155,18 @@ bool TileManager::MarkTilesOutOfMemory( } ResourceFormat TileManager::DetermineResourceFormat(const Tile* tile) const { - return tile_task_runner_->GetResourceFormat(!tile->is_opaque()); + return tile_task_manager_->GetRasterBufferProvider()->GetResourceFormat( + !tile->is_opaque()); } bool TileManager::DetermineResourceRequiresSwizzle(const Tile* tile) const { - return tile_task_runner_->GetResourceRequiresSwizzle(!tile->is_opaque()); + return tile_task_manager_->GetRasterBufferProvider() + ->GetResourceRequiresSwizzle(!tile->is_opaque()); } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TileManager::ScheduledTasksStateAsValue() const { - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); state->BeginDictionary("tasks_pending"); state->SetBoolean("ready_to_activate", signals_.ready_to_activate); diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h index 6b5745ea638..b98c4ec49ad 100644 --- a/chromium/cc/tiles/tile_manager.h +++ b/chromium/cc/tiles/tile_manager.h @@ -8,17 +8,17 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <set> #include <unordered_map> #include <utility> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/values.h" #include "cc/base/unique_notifier.h" #include "cc/playback/raster_source.h" -#include "cc/raster/tile_task_runner.h" +#include "cc/raster/raster_buffer_provider.h" #include "cc/resources/memory_history.h" #include "cc/resources/resource_pool.h" #include "cc/tiles/eviction_tile_priority_queue.h" @@ -26,6 +26,7 @@ #include "cc/tiles/raster_tile_priority_queue.h" #include "cc/tiles/tile.h" #include "cc/tiles/tile_draw_info.h" +#include "cc/tiles/tile_task_manager.h" namespace base { namespace trace_event { @@ -60,14 +61,14 @@ class CC_EXPORT TileManagerClient { // Given an empty raster tile priority queue, this will build a priority queue // that will return tiles in order in which they should be rasterized. // Note if the queue was previous built, Reset must be called on it. - virtual scoped_ptr<RasterTilePriorityQueue> BuildRasterQueue( + virtual std::unique_ptr<RasterTilePriorityQueue> BuildRasterQueue( TreePriority tree_priority, RasterTilePriorityQueue::Type type) = 0; // Given an empty eviction tile priority queue, this will build a priority // queue that will return tiles in order in which they should be evicted. // Note if the queue was previous built, Reset must be called on it. - virtual scoped_ptr<EvictionTilePriorityQueue> BuildEvictionQueue( + virtual std::unique_ptr<EvictionTilePriorityQueue> BuildEvictionQueue( TreePriority tree_priority) = 0; // Informs the client that due to the currently rasterizing (or scheduled to @@ -85,7 +86,7 @@ struct RasterTaskCompletionStats { size_t completed_count; size_t canceled_count; }; -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats); // This class manages tiles, deciding which should get rasterized and which @@ -94,10 +95,11 @@ RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats); // created, and unregister from the manager when they are deleted. class CC_EXPORT TileManager { public: - static scoped_ptr<TileManager> Create(TileManagerClient* client, - base::SequencedTaskRunner* task_runner, - size_t scheduled_raster_task_limit, - bool use_partial_raster); + static std::unique_ptr<TileManager> Create( + TileManagerClient* client, + base::SequencedTaskRunner* task_runner, + size_t scheduled_raster_task_limit, + bool use_partial_raster); virtual ~TileManager(); // Assigns tile memory and schedules work to prepare tiles for drawing. @@ -116,8 +118,8 @@ class CC_EXPORT TileManager { // FinishTasksAndCleanUp must be called in between consecutive calls to // SetResources. void SetResources(ResourcePool* resource_pool, - TileTaskRunner* tile_task_runner, ImageDecodeController* image_decode_controller, + TileTaskManager* tile_task_manager, size_t scheduled_raster_task_limit, bool use_gpu_rasterization); @@ -133,8 +135,8 @@ class CC_EXPORT TileManager { bool IsReadyToActivate() const; bool IsReadyToDraw() const; - scoped_ptr<base::trace_event::ConvertableToTraceFormat> BasicStateAsValue() - const; + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> + BasicStateAsValue() const; void BasicStateAsValueInto(base::trace_event::TracedValue* dict) const; const MemoryHistory::Entry& memory_stats_from_last_assign() const { return memory_stats_from_last_assign_; @@ -146,7 +148,8 @@ class CC_EXPORT TileManager { TileDrawInfo& draw_info = tiles[i]->draw_info(); draw_info.resource_ = resource_pool_->AcquireResource( tiles[i]->desired_texture_size(), - tile_task_runner_->GetResourceFormat(false)); + tile_task_manager_->GetRasterBufferProvider()->GetResourceFormat( + false)); } } @@ -162,7 +165,7 @@ class CC_EXPORT TileManager { global_state_ = state; } - void SetTileTaskRunnerForTesting(TileTaskRunner* tile_task_runner); + void SetTileTaskManagerForTesting(TileTaskManager* tile_task_manager); void FreeResourcesAndCleanUpReleasedTilesForTesting() { FreeResourcesForReleasedTiles(); @@ -248,17 +251,17 @@ class CC_EXPORT TileManager { void FreeResourcesForTile(Tile* tile); void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile); - scoped_refptr<RasterTask> CreateRasterTask( + scoped_refptr<TileTask> CreateRasterTask( const PrioritizedTile& prioritized_tile); - scoped_ptr<EvictionTilePriorityQueue> + std::unique_ptr<EvictionTilePriorityQueue> FreeTileResourcesUntilUsageIsWithinLimit( - scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, + std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue, const MemoryUsage& limit, MemoryUsage* usage); - scoped_ptr<EvictionTilePriorityQueue> + std::unique_ptr<EvictionTilePriorityQueue> FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( - scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, + std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue, const MemoryUsage& limit, const TilePriority& oother_priority, MemoryUsage* usage); @@ -266,7 +269,8 @@ class CC_EXPORT TileManager { bool AreRequiredTilesReadyToDraw(RasterTilePriorityQueue::Type type) const; void CheckIfMoreTilesNeedToBePrepared(); void CheckAndIssueSignals(); - bool MarkTilesOutOfMemory(scoped_ptr<RasterTilePriorityQueue> queue) const; + bool MarkTilesOutOfMemory( + std::unique_ptr<RasterTilePriorityQueue> queue) const; ResourceFormat DetermineResourceFormat(const Tile* tile) const; bool DetermineResourceRequiresSwizzle(const Tile* tile) const; @@ -278,13 +282,13 @@ class CC_EXPORT TileManager { scoped_refptr<TileTask> CreateTaskSetFinishedTask( void (TileManager::*callback)()); - scoped_ptr<base::trace_event::ConvertableToTraceFormat> + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> ScheduledTasksStateAsValue() const; TileManagerClient* client_; scoped_refptr<base::SequencedTaskRunner> task_runner_; ResourcePool* resource_pool_; - TileTaskRunner* tile_task_runner_; + TileTaskManager* tile_task_manager_; GlobalStateThatImpactsTilePriority global_state_; size_t scheduled_raster_task_limit_; const bool use_partial_raster_; diff --git a/chromium/cc/tiles/tile_manager_perftest.cc b/chromium/cc/tiles/tile_manager_perftest.cc index cc0a41497e9..b6437ed2e86 100644 --- a/chromium/cc/tiles/tile_manager_perftest.cc +++ b/chromium/cc/tiles/tile_manager_perftest.cc @@ -7,7 +7,7 @@ #include "base/lazy_instance.h" #include "base/location.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "cc/debug/lap_timer.h" #include "cc/raster/raster_buffer.h" @@ -20,6 +20,8 @@ #include "cc/test/fake_raster_source.h" #include "cc/test/fake_tile_manager.h" #include "cc/test/fake_tile_manager_client.h" +#include "cc/test/fake_tile_task_manager.h" +#include "cc/test/test_layer_tree_host_base.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_tile_priorities.h" @@ -37,145 +39,33 @@ static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -class FakeTileTaskRunnerImpl : public TileTaskRunner, public TileTaskClient { - public: - // Overridden from TileTaskRunner: - void Shutdown() override {} - void ScheduleTasks(TaskGraph* graph) override { - for (auto& node : graph->nodes) { - TileTask* task = static_cast<TileTask*>(node.task); - - task->WillSchedule(); - task->ScheduleOnOriginThread(this); - task->DidSchedule(); - - completed_tasks_.push_back(task); - } - } - void CheckForCompletedTasks() override { - for (TileTask::Vector::iterator it = completed_tasks_.begin(); - it != completed_tasks_.end(); ++it) { - TileTask* task = it->get(); - - task->WillComplete(); - task->CompleteOnOriginThread(this); - task->DidComplete(); - } - completed_tasks_.clear(); - } - ResourceFormat GetResourceFormat(bool must_support_alpha) const override { - return RGBA_8888; - } - bool GetResourceRequiresSwizzle(bool must_support_alpha) const override { - return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); - } - - // Overridden from TileTaskClient: - scoped_ptr<RasterBuffer> AcquireBufferForRaster( - const Resource* resource, - uint64_t new_content_id, - uint64_t previous_content_id) override { - return nullptr; - } - void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override {} - - private: - TileTask::Vector completed_tasks_; -}; -base::LazyInstance<FakeTileTaskRunnerImpl> g_fake_tile_task_runner = +base::LazyInstance<FakeTileTaskManagerImpl> g_fake_tile_task_manager = LAZY_INSTANCE_INITIALIZER; -class TileManagerPerfTest : public testing::Test { +class TileManagerPerfTest : public TestLayerTreeHostBase { public: TileManagerPerfTest() - : memory_limit_policy_(ALLOW_ANYTHING), - max_tiles_(10000), - id_(7), - task_runner_provider_(base::ThreadTaskRunnerHandle::Get()), - output_surface_(FakeOutputSurface::Create3d()), - host_impl_(LayerTreeSettings(), - &task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_), - timer_(kWarmupRuns, + : timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) {} - void SetTreePriority(TreePriority tree_priority) { - GlobalStateThatImpactsTilePriority state; - gfx::Size tile_size(256, 256); - - state.soft_memory_limit_in_bytes = 100 * 1000 * 1000; - state.num_resources_limit = max_tiles_; - state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes * 2; - state.memory_limit_policy = memory_limit_policy_; - state.tree_priority = tree_priority; - - global_state_ = state; - host_impl_.resource_pool()->SetResourceUsageLimits( - state.soft_memory_limit_in_bytes, state.num_resources_limit); - host_impl_.tile_manager()->SetGlobalStateForTesting(state); - } - - void SetUp() override { - InitializeRenderer(); - SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES); - } - - virtual void InitializeRenderer() { - host_impl_.SetVisible(true); - host_impl_.InitializeRenderer(output_surface_.get()); - tile_manager()->SetTileTaskRunnerForTesting( - g_fake_tile_task_runner.Pointer()); + void InitializeRenderer() override { + host_impl()->SetVisible(true); + host_impl()->InitializeRenderer(output_surface()); + tile_manager()->SetTileTaskManagerForTesting( + g_fake_tile_task_manager.Pointer()); } - void SetupDefaultTrees(const gfx::Size& layer_bounds) { + void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds, + const gfx::Size& tile_size) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); scoped_refptr<FakeRasterSource> active_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - SetupTrees(pending_raster_source, active_raster_source); - } - - void ActivateTree() { - host_impl_.ActivateSyncTree(); - CHECK(!host_impl_.pending_tree()); - pending_root_layer_ = NULL; - active_root_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.active_tree()->LayerById(id_)); - } - - void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds, - const gfx::Size& tile_size) { - SetupDefaultTrees(layer_bounds); - pending_root_layer_->set_fixed_tile_size(tile_size); - active_root_layer_->set_fixed_tile_size(tile_size); - } - - void SetupTrees(scoped_refptr<RasterSource> pending_raster_source, - scoped_refptr<RasterSource> active_raster_source) { - SetupPendingTree(active_raster_source); + SetupPendingTree(std::move(active_raster_source), tile_size, Region()); ActivateTree(); - SetupPendingTree(pending_raster_source); - } - - void SetupPendingTree(scoped_refptr<RasterSource> raster_source) { - host_impl_.CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl_.pending_tree(); - // Clear recycled tree. - pending_tree->ClearLayers(); - - scoped_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id_, - raster_source); - pending_layer->SetDrawsContent(true); - pending_layer->SetForceRenderSurface(true); - pending_tree->SetRootLayer(std::move(pending_layer)); - pending_tree->BuildPropertyTreesForTesting(); - - pending_root_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.pending_tree()->LayerById(id_)); + SetupPendingTree(std::move(pending_raster_source), tile_size, Region()); } void RunRasterQueueConstructTest(const std::string& test_name, @@ -191,8 +81,9 @@ class TileManagerPerfTest : public testing::Test { timer_.Reset(); do { - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( - priorities[priority_count], RasterTilePriorityQueue::Type::ALL)); + std::unique_ptr<RasterTilePriorityQueue> queue( + host_impl()->BuildRasterQueue(priorities[priority_count], + RasterTilePriorityQueue::Type::ALL)); priority_count = (priority_count + 1) % arraysize(priorities); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); @@ -220,8 +111,9 @@ class TileManagerPerfTest : public testing::Test { timer_.Reset(); do { int count = tile_count; - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( - priorities[priority_count], RasterTilePriorityQueue::Type::ALL)); + std::unique_ptr<RasterTilePriorityQueue> queue( + host_impl()->BuildRasterQueue(priorities[priority_count], + RasterTilePriorityQueue::Type::ALL)); while (count--) { ASSERT_FALSE(queue->IsEmpty()); ASSERT_TRUE(queue->Top().tile()); @@ -258,8 +150,8 @@ class TileManagerPerfTest : public testing::Test { timer_.Reset(); do { - scoped_ptr<EvictionTilePriorityQueue> queue( - host_impl_.BuildEvictionQueue(priorities[priority_count])); + std::unique_ptr<EvictionTilePriorityQueue> queue( + host_impl()->BuildEvictionQueue(priorities[priority_count])); priority_count = (priority_count + 1) % arraysize(priorities); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); @@ -293,8 +185,8 @@ class TileManagerPerfTest : public testing::Test { timer_.Reset(); do { int count = tile_count; - scoped_ptr<EvictionTilePriorityQueue> queue( - host_impl_.BuildEvictionQueue(priorities[priority_count])); + std::unique_ptr<EvictionTilePriorityQueue> queue( + host_impl()->BuildEvictionQueue(priorities[priority_count])); while (count--) { ASSERT_FALSE(queue->IsEmpty()); ASSERT_TRUE(queue->Top().tile()); @@ -314,57 +206,53 @@ class TileManagerPerfTest : public testing::Test { } std::vector<FakePictureLayerImpl*> CreateLayers(int layer_count, - int tiles_per_layer_count) { + int num_tiles_in_high_res) { // Compute the width/height required for high res to get - // tiles_per_layer_count tiles. - float width = std::sqrt(static_cast<float>(tiles_per_layer_count)); - float height = tiles_per_layer_count / width; + // num_tiles_in_high_res tiles. + float width = std::sqrt(static_cast<float>(num_tiles_in_high_res)); + float height = num_tiles_in_high_res / width; // Adjust the width and height to account for the fact that tiles - // are bigger than 1x1. Also, account for the fact that that we - // will be creating one high res and one low res tiling. That is, - // width and height should be smaller by sqrt(1 + low_res_scale). - // This gives us _approximately_ correct counts. - width *= settings_.default_tile_size.width() / - std::sqrt(1 + settings_.low_res_contents_scale_factor); - height *= settings_.default_tile_size.height() / - std::sqrt(1 + settings_.low_res_contents_scale_factor); + // are bigger than 1x1. + LayerTreeSettings settings; + width *= settings.default_tile_size.width(); + height *= settings.default_tile_size.height(); // Ensure that we start with blank trees and no tiles. - host_impl_.ResetTreesForTesting(); + host_impl()->ResetTreesForTesting(); tile_manager()->FreeResourcesAndCleanUpReleasedTilesForTesting(); gfx::Size layer_bounds(width, height); gfx::Size viewport(width / 5, height / 5); - host_impl_.SetViewportSize(viewport); + host_impl()->SetViewportSize(viewport); SetupDefaultTreesWithFixedTileSize(layer_bounds, - settings_.default_tile_size); + settings.default_tile_size); std::vector<FakePictureLayerImpl*> layers; // Pending layer counts as one layer. - layers.push_back(pending_root_layer_); - int next_id = id_ + 1; + layers.push_back(pending_layer()); + int next_id = layer_id() + 1; // Create the rest of the layers as children of the root layer. scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(layer_bounds); while (static_cast<int>(layers.size()) < layer_count) { - scoped_ptr<FakePictureLayerImpl> layer = + std::unique_ptr<FakePictureLayerImpl> child_layer = FakePictureLayerImpl::CreateWithRasterSource( - host_impl_.pending_tree(), next_id, raster_source); - layer->SetBounds(layer_bounds); - layer->SetDrawsContent(true); - layers.push_back(layer.get()); - pending_root_layer_->AddChild(std::move(layer)); + host_impl()->pending_tree(), next_id, raster_source); + child_layer->SetBounds(layer_bounds); + child_layer->SetDrawsContent(true); + layers.push_back(child_layer.get()); + pending_layer()->AddChild(std::move(child_layer)); ++next_id; } // Property trees need to be rebuilt because layers were added above. - host_impl_.pending_tree()->property_trees()->needs_rebuild = true; - host_impl_.pending_tree()->BuildPropertyTreesForTesting(); + host_impl()->pending_tree()->property_trees()->needs_rebuild = true; + host_impl()->pending_tree()->BuildPropertyTreesForTesting(); bool update_lcd_text = false; - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); for (FakePictureLayerImpl* layer : layers) layer->CreateAllTiles(); @@ -373,7 +261,7 @@ class TileManagerPerfTest : public testing::Test { GlobalStateThatImpactsTilePriority GlobalStateForTest() { GlobalStateThatImpactsTilePriority state; - gfx::Size tile_size = settings_.default_tile_size; + gfx::Size tile_size = LayerTreeSettings().default_tile_size; state.soft_memory_limit_in_bytes = 10000u * 4u * static_cast<size_t>(tile_size.width() * tile_size.height()); @@ -392,7 +280,7 @@ class TileManagerPerfTest : public testing::Test { timer_.Reset(); do { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); for (const auto& layer : layers) layer->UpdateTiles(); @@ -406,23 +294,10 @@ class TileManagerPerfTest : public testing::Test { timer_.LapsPerSecond(), "runs/s", true); } - TileManager* tile_manager() { return host_impl_.tile_manager(); } + TileManager* tile_manager() { return host_impl()->tile_manager(); } protected: - GlobalStateThatImpactsTilePriority global_state_; - - TestSharedBitmapManager shared_bitmap_manager_; - TestTaskGraphRunner task_graph_runner_; - TileMemoryLimitPolicy memory_limit_policy_; - int max_tiles_; - int id_; - FakeImplTaskRunnerProvider task_runner_provider_; - scoped_ptr<OutputSurface> output_surface_; - FakeLayerTreeHostImpl host_impl_; - FakePictureLayerImpl* pending_root_layer_; - FakePictureLayerImpl* active_root_layer_; LapTimer timer_; - LayerTreeSettings settings_; }; TEST_F(TileManagerPerfTest, PrepareTiles) { diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc index ba8f369d634..fff4db7e5a0 100644 --- a/chromium/cc/tiles/tile_manager_unittest.cc +++ b/chromium/cc/tiles/tile_manager_unittest.cc @@ -5,11 +5,13 @@ #include <stddef.h> #include <stdint.h> +#include "base/memory/ptr_util.h" #include "base/run_loop.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/playback/raster_source.h" #include "cc/playback/recording_source.h" #include "cc/raster/raster_buffer.h" +#include "cc/raster/synchronous_task_graph_runner.h" #include "cc/resources/resource_pool.h" #include "cc/test/begin_frame_args_test.h" #include "cc/test/fake_impl_task_runner_provider.h" @@ -21,7 +23,9 @@ #include "cc/test/fake_raster_source.h" #include "cc/test/fake_recording_source.h" #include "cc/test/fake_tile_manager.h" +#include "cc/test/fake_tile_task_manager.h" #include "cc/test/test_gpu_memory_buffer_manager.h" +#include "cc/test/test_layer_tree_host_base.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_tile_priorities.h" @@ -33,152 +37,30 @@ #include "cc/trees/layer_tree_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSurface.h" namespace cc { namespace { -class LowResTilingsSettings : public LayerTreeSettings { +class TileManagerTilePriorityQueueTest : public TestLayerTreeHostBase { public: - LowResTilingsSettings() { - create_low_res_tiling = true; - } -}; - -class TileManagerTilePriorityQueueTest : public testing::Test { - public: - TileManagerTilePriorityQueueTest() - : memory_limit_policy_(ALLOW_ANYTHING), - max_tiles_(10000), - ready_to_activate_(false), - id_(7), - task_runner_provider_(base::ThreadTaskRunnerHandle::Get()), - output_surface_(FakeOutputSurface::Create3d()), - host_impl_(LowResTilingsSettings(), - &task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_, - &gpu_memory_buffer_manager_) {} - - void SetTreePriority(TreePriority tree_priority) { - GlobalStateThatImpactsTilePriority state; - gfx::Size tile_size(256, 256); - - state.soft_memory_limit_in_bytes = 100 * 1000 * 1000; - state.num_resources_limit = max_tiles_; - state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes * 2; - state.memory_limit_policy = memory_limit_policy_; - state.tree_priority = tree_priority; - - global_state_ = state; - host_impl_.resource_pool()->SetResourceUsageLimits( - state.soft_memory_limit_in_bytes, - state.num_resources_limit); - host_impl_.tile_manager()->SetGlobalStateForTesting(state); - } - - void SetUp() override { - InitializeRenderer(); - SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES); - } - - virtual void InitializeRenderer() { - host_impl_.SetVisible(true); - host_impl_.InitializeRenderer(output_surface_.get()); - } - - void SetupDefaultTrees(const gfx::Size& layer_bounds) { - scoped_refptr<FakeRasterSource> pending_raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_refptr<FakeRasterSource> active_raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - - SetupTrees(pending_raster_source, active_raster_source); - } - - // This matches picture_layer_impl_unittest's ActivateTree. - void ActivateTree() { - host_impl_.ActivateSyncTree(); - CHECK(!host_impl_.pending_tree()); - pending_layer_ = NULL; - active_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.active_tree()->LayerById(id_)); - bool update_lcd_text = false; - host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text); - } - - void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds, - const gfx::Size& tile_size) { - SetupDefaultTrees(layer_bounds); - pending_layer_->set_fixed_tile_size(tile_size); - active_layer_->set_fixed_tile_size(tile_size); - } - - void SetupTrees(scoped_refptr<RasterSource> pending_raster_source, - scoped_refptr<RasterSource> active_raster_source) { - SetupPendingTree(active_raster_source); - ActivateTree(); - SetupPendingTree(pending_raster_source); - } - - void SetupPendingTree(scoped_refptr<RasterSource> raster_source) { - host_impl_.CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl_.pending_tree(); - - // Steal from the recycled tree. - LayerImpl* old_pending_root = pending_tree->root_layer(); - DCHECK(!old_pending_root || old_pending_root->id() == id_); - - FakePictureLayerImpl* pending_layer = nullptr; - if (old_pending_root) { - pending_layer = static_cast<FakePictureLayerImpl*>(old_pending_root); - pending_layer->SetRasterSourceOnPending(raster_source, Region()); - } else { - scoped_ptr<FakePictureLayerImpl> new_root = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id_, - raster_source); - pending_layer = new_root.get(); - pending_tree->SetRootLayer(std::move(new_root)); - pending_layer->SetDrawsContent(true); - pending_layer->SetHasRenderSurface(true); - } - // The bounds() just mirror the raster source size. - pending_layer->SetBounds(pending_layer->raster_source()->GetSize()); - - pending_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.pending_tree()->LayerById(id_)); - - // Add tilings/tiles for the layer. - bool update_lcd_text = false; - host_impl_.pending_tree()->BuildPropertyTreesForTesting(); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings; + settings.create_low_res_tiling = true; + settings.verify_clip_tree_calculations = true; + return settings; } - TileManager* tile_manager() { return host_impl_.tile_manager(); } - - protected: - GlobalStateThatImpactsTilePriority global_state_; - - TestSharedBitmapManager shared_bitmap_manager_; - TestTaskGraphRunner task_graph_runner_; - TestGpuMemoryBufferManager gpu_memory_buffer_manager_; - TileMemoryLimitPolicy memory_limit_policy_; - int max_tiles_; - bool ready_to_activate_; - int id_; - FakeImplTaskRunnerProvider task_runner_provider_; - scoped_ptr<OutputSurface> output_surface_; - FakeLayerTreeHostImpl host_impl_; - FakePictureLayerImpl* pending_layer_; - FakePictureLayerImpl* active_layer_; + TileManager* tile_manager() { return host_impl()->tile_manager(); } }; TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); @@ -196,8 +78,8 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { // Sanity check, all tiles should be visible. std::set<Tile*> smoothness_tiles; - queue = host_impl_.BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY, - RasterTilePriorityQueue::Type::ALL); + queue = host_impl()->BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY, + RasterTilePriorityQueue::Type::ALL); bool had_low_res = false; while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); @@ -213,7 +95,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { EXPECT_TRUE(had_low_res); // Check that everything is required for activation. - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); std::set<Tile*> required_for_activation_tiles; @@ -226,7 +108,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { EXPECT_EQ(all_tiles, required_for_activation_tiles); // Check that everything is required for draw. - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); std::set<Tile*> required_for_draw_tiles; @@ -241,37 +123,35 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { Region invalidation(gfx::Rect(0, 0, 500, 500)); // Invalidate the pending tree. - pending_layer_->set_invalidation(invalidation); - pending_layer_->HighResTiling()->Invalidate(invalidation); + pending_layer()->set_invalidation(invalidation); + pending_layer()->HighResTiling()->Invalidate(invalidation); // Renew all of the tile priorities. gfx::Rect viewport(50, 50, 100, 100); - pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); + pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); + active_layer()->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); // Populate all tiles directly from the tilings. all_tiles.clear(); std::set<Tile*> high_res_tiles; std::vector<Tile*> pending_high_res_tiles = - pending_layer_->HighResTiling()->AllTilesForTesting(); + pending_layer()->HighResTiling()->AllTilesForTesting(); for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) { all_tiles.insert(pending_high_res_tiles[i]); high_res_tiles.insert(pending_high_res_tiles[i]); } std::vector<Tile*> active_high_res_tiles = - active_layer_->HighResTiling()->AllTilesForTesting(); + active_layer()->HighResTiling()->AllTilesForTesting(); for (size_t i = 0; i < active_high_res_tiles.size(); ++i) { all_tiles.insert(active_high_res_tiles[i]); high_res_tiles.insert(active_high_res_tiles[i]); } std::vector<Tile*> active_low_res_tiles = - active_layer_->LowResTiling()->AllTilesForTesting(); + active_layer()->LowResTiling()->AllTilesForTesting(); for (size_t i = 0; i < active_low_res_tiles.size(); ++i) all_tiles.insert(active_low_res_tiles[i]); @@ -280,8 +160,8 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { tile_count = 0; size_t correct_order_tiles = 0u; // Here we expect to get increasing ACTIVE_TREE priority_bin. - queue = host_impl_.BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY, - RasterTilePriorityQueue::Type::ALL); + queue = host_impl()->BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY, + RasterTilePriorityQueue::Type::ALL); std::set<Tile*> expected_required_for_draw_tiles; std::set<Tile*> expected_required_for_activation_tiles; while (!queue->IsEmpty()) { @@ -330,7 +210,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { EXPECT_GT(correct_order_tiles, 3 * tile_count / 4); // Check that we have consistent required_for_activation tiles. - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); required_for_activation_tiles.clear(); @@ -345,7 +225,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { EXPECT_NE(all_tiles, required_for_activation_tiles); // Check that we have consistent required_for_draw tiles. - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); required_for_draw_tiles.clear(); @@ -362,8 +242,8 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { last_tile = PrioritizedTile(); size_t increasing_distance_tiles = 0u; // Here we expect to get increasing PENDING_TREE priority_bin. - queue = host_impl_.BuildRasterQueue(NEW_CONTENT_TAKES_PRIORITY, - RasterTilePriorityQueue::Type::ALL); + queue = host_impl()->BuildRasterQueue(NEW_CONTENT_TAKES_PRIORITY, + RasterTilePriorityQueue::Type::ALL); tile_count = 0; while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); @@ -401,7 +281,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { EXPECT_GE(increasing_distance_tiles, 3 * tile_count / 4); // Check that we have consistent required_for_activation tiles. - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( NEW_CONTENT_TAKES_PRIORITY, RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); required_for_activation_tiles.clear(); @@ -416,7 +296,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { EXPECT_NE(new_content_tiles, required_for_activation_tiles); // Check that we have consistent required_for_draw tiles. - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( NEW_CONTENT_TAKES_PRIORITY, RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); required_for_draw_tiles.clear(); @@ -434,22 +314,22 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueHighNonIdealTilings) { const gfx::Size layer_bounds(1000, 1000); const gfx::Size viewport(800, 800); - host_impl_.SetViewportSize(viewport); + host_impl()->SetViewportSize(viewport); SetupDefaultTrees(layer_bounds); - pending_layer_->tilings()->AddTiling(1.5f, pending_layer_->raster_source()); - active_layer_->tilings()->AddTiling(1.5f, active_layer_->raster_source()); - pending_layer_->tilings()->AddTiling(1.7f, pending_layer_->raster_source()); - active_layer_->tilings()->AddTiling(1.7f, active_layer_->raster_source()); + pending_layer()->tilings()->AddTiling(1.5f, pending_layer()->raster_source()); + active_layer()->tilings()->AddTiling(1.5f, active_layer()->raster_source()); + pending_layer()->tilings()->AddTiling(1.7f, pending_layer()->raster_source()); + active_layer()->tilings()->AddTiling(1.7f, active_layer()->raster_source()); - pending_layer_->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0, + pending_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, + 5.0, Occlusion(), true); + active_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0, Occlusion(), true); - active_layer_->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0, - Occlusion(), true); std::set<Tile*> all_expected_tiles; - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); if (tiling->contents_scale() == 1.f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); @@ -459,8 +339,8 @@ TEST_F(TileManagerTilePriorityQueueTest, } } - for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); if (tiling->contents_scale() == 1.5f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); @@ -479,7 +359,7 @@ TEST_F(TileManagerTilePriorityQueueTest, } } - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); @@ -501,22 +381,22 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueHighLowTilings) { const gfx::Size layer_bounds(1000, 1000); const gfx::Size viewport(800, 800); - host_impl_.SetViewportSize(viewport); + host_impl()->SetViewportSize(viewport); SetupDefaultTrees(layer_bounds); - pending_layer_->tilings()->AddTiling(1.5f, pending_layer_->raster_source()); - active_layer_->tilings()->AddTiling(1.5f, active_layer_->raster_source()); - pending_layer_->tilings()->AddTiling(1.7f, pending_layer_->raster_source()); - active_layer_->tilings()->AddTiling(1.7f, active_layer_->raster_source()); + pending_layer()->tilings()->AddTiling(1.5f, pending_layer()->raster_source()); + active_layer()->tilings()->AddTiling(1.5f, active_layer()->raster_source()); + pending_layer()->tilings()->AddTiling(1.7f, pending_layer()->raster_source()); + active_layer()->tilings()->AddTiling(1.7f, active_layer()->raster_source()); - pending_layer_->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0, + pending_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, + 5.0, Occlusion(), true); + active_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0, Occlusion(), true); - active_layer_->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0, - Occlusion(), true); std::set<Tile*> all_expected_tiles; - for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); if (tiling->contents_scale() == 1.f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); @@ -526,8 +406,8 @@ TEST_F(TileManagerTilePriorityQueueTest, } } - for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { - PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); if (tiling->contents_scale() == 1.5f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); @@ -546,7 +426,7 @@ TEST_F(TileManagerTilePriorityQueueTest, } } - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); @@ -566,27 +446,27 @@ TEST_F(TileManagerTilePriorityQueueTest, TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(gfx::Size(500, 500)); + host_impl()->SetViewportSize(gfx::Size(500, 500)); SetupDefaultTrees(layer_bounds); // Use a tile's content rect as an invalidation. We should inset it a bit to // ensure that border math doesn't invalidate neighbouring tiles. gfx::Rect invalidation = - active_layer_->HighResTiling()->TileAt(1, 0)->content_rect(); + active_layer()->HighResTiling()->TileAt(1, 0)->content_rect(); invalidation.Inset(2, 2); - pending_layer_->set_invalidation(invalidation); - pending_layer_->HighResTiling()->Invalidate(invalidation); - pending_layer_->HighResTiling()->CreateMissingTilesInLiveTilesRect(); + pending_layer()->set_invalidation(invalidation); + pending_layer()->HighResTiling()->Invalidate(invalidation); + pending_layer()->HighResTiling()->CreateMissingTilesInLiveTilesRect(); // Sanity checks: Tile at 0, 0 not exist on the pending tree (it's not // invalidated). Tile 1, 0 should exist on both. - EXPECT_FALSE(pending_layer_->HighResTiling()->TileAt(0, 0)); - EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(0, 0)); - EXPECT_TRUE(pending_layer_->HighResTiling()->TileAt(1, 0)); - EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(1, 0)); - EXPECT_NE(pending_layer_->HighResTiling()->TileAt(1, 0), - active_layer_->HighResTiling()->TileAt(1, 0)); + EXPECT_FALSE(pending_layer()->HighResTiling()->TileAt(0, 0)); + EXPECT_TRUE(active_layer()->HighResTiling()->TileAt(0, 0)); + EXPECT_TRUE(pending_layer()->HighResTiling()->TileAt(1, 0)); + EXPECT_TRUE(active_layer()->HighResTiling()->TileAt(1, 0)); + EXPECT_NE(pending_layer()->HighResTiling()->TileAt(1, 0), + active_layer()->HighResTiling()->TileAt(1, 0)); std::set<Tile*> expected_now_tiles; std::set<Tile*> expected_required_for_draw_tiles; @@ -594,14 +474,14 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { for (int i = 0; i <= 1; ++i) { for (int j = 0; j <= 1; ++j) { bool have_pending_tile = false; - if (pending_layer_->HighResTiling()->TileAt(i, j)) { + if (pending_layer()->HighResTiling()->TileAt(i, j)) { expected_now_tiles.insert( - pending_layer_->HighResTiling()->TileAt(i, j)); + pending_layer()->HighResTiling()->TileAt(i, j)); expected_required_for_activation_tiles.insert( - pending_layer_->HighResTiling()->TileAt(i, j)); + pending_layer()->HighResTiling()->TileAt(i, j)); have_pending_tile = true; } - Tile* active_tile = active_layer_->HighResTiling()->TileAt(i, j); + Tile* active_tile = active_layer()->HighResTiling()->TileAt(i, j); EXPECT_TRUE(active_tile); expected_now_tiles.insert(active_tile); expected_required_for_draw_tiles.insert(active_tile); @@ -620,11 +500,11 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { std::set<Tile*> expected_all_tiles; for (int i = 0; i <= 3; ++i) { for (int j = 0; j <= 3; ++j) { - if (pending_layer_->HighResTiling()->TileAt(i, j)) + if (pending_layer()->HighResTiling()->TileAt(i, j)) expected_all_tiles.insert( - pending_layer_->HighResTiling()->TileAt(i, j)); - EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(i, j)); - expected_all_tiles.insert(active_layer_->HighResTiling()->TileAt(i, j)); + pending_layer()->HighResTiling()->TileAt(i, j)); + EXPECT_TRUE(active_layer()->HighResTiling()->TileAt(i, j)); + expected_all_tiles.insert(active_layer()->HighResTiling()->TileAt(i, j)); } } // Expect 15 shared tiles and 1 unshared tile. @@ -632,7 +512,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { // The actual test will now build different queues and verify that the queues // return the same information as computed manually above. - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); std::set<Tile*> actual_now_tiles; std::set<Tile*> actual_all_tiles; @@ -646,7 +526,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { EXPECT_EQ(expected_now_tiles, actual_now_tiles); EXPECT_EQ(expected_all_tiles, actual_all_tiles); - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); std::set<Tile*> actual_required_for_draw_tiles; @@ -657,7 +537,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { } EXPECT_EQ(expected_required_for_draw_tiles, actual_required_for_draw_tiles); - queue = host_impl_.BuildRasterQueue( + queue = host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); std::set<Tile*> actual_required_for_activation_tiles; @@ -671,7 +551,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { } TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); SetupDefaultTrees(layer_bounds); @@ -679,23 +559,23 @@ TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) { // Create a pending child layer. scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - scoped_ptr<FakePictureLayerImpl> pending_child = + std::unique_ptr<FakePictureLayerImpl> pending_child = FakePictureLayerImpl::CreateWithRasterSource( - host_impl_.pending_tree(), id_ + 1, pending_raster_source); + host_impl()->pending_tree(), layer_id() + 1, pending_raster_source); FakePictureLayerImpl* pending_child_raw = pending_child.get(); pending_child_raw->SetDrawsContent(true); - pending_layer_->AddChild(std::move(pending_child)); + pending_layer()->AddChild(std::move(pending_child)); // Set a small viewport, so we have soon and eventually tiles. - host_impl_.SetViewportSize(gfx::Size(200, 200)); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->SetViewportSize(gfx::Size(200, 200)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); bool update_lcd_text = false; - host_impl_.pending_tree()->property_trees()->needs_rebuild = true; - host_impl_.pending_tree()->BuildPropertyTreesForTesting(); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->property_trees()->needs_rebuild = true; + host_impl()->pending_tree()->BuildPropertyTreesForTesting(); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); - host_impl_.SetRequiresHighResToDraw(); - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + host_impl()->SetRequiresHighResToDraw(); + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); @@ -720,21 +600,22 @@ TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) { TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); - ASSERT_TRUE(active_layer_->HighResTiling()); - ASSERT_TRUE(active_layer_->LowResTiling()); - ASSERT_TRUE(pending_layer_->HighResTiling()); - EXPECT_FALSE(pending_layer_->LowResTiling()); + ASSERT_TRUE(active_layer()->HighResTiling()); + ASSERT_TRUE(active_layer()->LowResTiling()); + ASSERT_TRUE(pending_layer()->HighResTiling()); + EXPECT_FALSE(pending_layer()->LowResTiling()); - scoped_ptr<EvictionTilePriorityQueue> empty_queue( - host_impl_.BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); + std::unique_ptr<EvictionTilePriorityQueue> empty_queue( + host_impl()->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); EXPECT_TRUE(empty_queue->IsEmpty()); std::set<Tile*> all_tiles; size_t tile_count = 0; - scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue( - SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); + std::unique_ptr<RasterTilePriorityQueue> raster_queue( + host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES, + RasterTilePriorityQueue::Type::ALL)); while (!raster_queue->IsEmpty()) { ++tile_count; EXPECT_TRUE(raster_queue->Top().tile()); @@ -748,8 +629,8 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { tile_manager()->InitializeTilesWithResourcesForTesting( std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); - scoped_ptr<EvictionTilePriorityQueue> queue( - host_impl_.BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY)); + std::unique_ptr<EvictionTilePriorityQueue> queue( + host_impl()->BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY)); EXPECT_FALSE(queue->IsEmpty()); // Sanity check, all tiles should be visible. @@ -770,34 +651,32 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { Region invalidation(gfx::Rect(0, 0, 500, 500)); // Invalidate the pending tree. - pending_layer_->set_invalidation(invalidation); - pending_layer_->HighResTiling()->Invalidate(invalidation); - pending_layer_->HighResTiling()->CreateMissingTilesInLiveTilesRect(); - EXPECT_FALSE(pending_layer_->LowResTiling()); + pending_layer()->set_invalidation(invalidation); + pending_layer()->HighResTiling()->Invalidate(invalidation); + pending_layer()->HighResTiling()->CreateMissingTilesInLiveTilesRect(); + EXPECT_FALSE(pending_layer()->LowResTiling()); // Renew all of the tile priorities. gfx::Rect viewport(50, 50, 100, 100); - pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); + pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); + active_layer()->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); // Populate all tiles directly from the tilings. all_tiles.clear(); std::vector<Tile*> pending_high_res_tiles = - pending_layer_->HighResTiling()->AllTilesForTesting(); + pending_layer()->HighResTiling()->AllTilesForTesting(); for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) all_tiles.insert(pending_high_res_tiles[i]); std::vector<Tile*> active_high_res_tiles = - active_layer_->HighResTiling()->AllTilesForTesting(); + active_layer()->HighResTiling()->AllTilesForTesting(); for (size_t i = 0; i < active_high_res_tiles.size(); ++i) all_tiles.insert(active_high_res_tiles[i]); std::vector<Tile*> active_low_res_tiles = - active_layer_->LowResTiling()->AllTilesForTesting(); + active_layer()->LowResTiling()->AllTilesForTesting(); for (size_t i = 0; i < active_low_res_tiles.size(); ++i) all_tiles.insert(active_low_res_tiles[i]); @@ -808,7 +687,7 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { smoothness_tiles.clear(); tile_count = 0; // Here we expect to get increasing combined priority_bin. - queue = host_impl_.BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY); + queue = host_impl()->BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY); int distance_increasing = 0; int distance_decreasing = 0; while (!queue->IsEmpty()) { @@ -851,7 +730,7 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { std::set<Tile*> new_content_tiles; last_tile = PrioritizedTile(); // Again, we expect to get increasing combined priority_bin. - queue = host_impl_.BuildEvictionQueue(NEW_CONTENT_TAKES_PRIORITY); + queue = host_impl()->BuildEvictionQueue(NEW_CONTENT_TAKES_PRIORITY); distance_decreasing = 0; distance_increasing = 0; while (!queue->IsEmpty()) { @@ -892,41 +771,42 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueWithOcclusion) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - scoped_ptr<FakePictureLayerImpl> pending_child = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), 2, - pending_raster_source); - pending_layer_->AddChild(std::move(pending_child)); + std::unique_ptr<FakePictureLayerImpl> pending_child = + FakePictureLayerImpl::CreateWithRasterSource(host_impl()->pending_tree(), + 2, pending_raster_source); + pending_layer()->AddChild(std::move(pending_child)); FakePictureLayerImpl* pending_child_layer = - static_cast<FakePictureLayerImpl*>(pending_layer_->children()[0]); + static_cast<FakePictureLayerImpl*>(pending_layer()->children()[0]); pending_child_layer->SetDrawsContent(true); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); bool update_lcd_text = false; - host_impl_.pending_tree()->property_trees()->needs_rebuild = true; - host_impl_.pending_tree()->BuildPropertyTreesForTesting(); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->property_trees()->needs_rebuild = true; + host_impl()->pending_tree()->BuildPropertyTreesForTesting(); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); ActivateTree(); SetupPendingTree(pending_raster_source); FakePictureLayerImpl* active_child_layer = - static_cast<FakePictureLayerImpl*>(active_layer_->children()[0]); + static_cast<FakePictureLayerImpl*>(active_layer()->children()[0]); std::set<Tile*> all_tiles; size_t tile_count = 0; - scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue( - SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); + std::unique_ptr<RasterTilePriorityQueue> raster_queue( + host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES, + RasterTilePriorityQueue::Type::ALL)); while (!raster_queue->IsEmpty()) { ++tile_count; EXPECT_TRUE(raster_queue->Top().tile()); @@ -938,24 +818,20 @@ TEST_F(TileManagerTilePriorityQueueTest, // Renew all of the tile priorities. gfx::Rect viewport(layer_bounds); - pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - pending_child_layer->HighResTiling()->ComputeTilePriorityRects( - viewport, 1.0f, 1.0, Occlusion()); - - active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - active_child_layer->HighResTiling()->ComputeTilePriorityRects( - viewport, 1.0f, 1.0, Occlusion()); - active_child_layer->LowResTiling()->ComputeTilePriorityRects( - viewport, 1.0f, 1.0, Occlusion()); + pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); + pending_child_layer->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); + + active_layer()->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); + active_child_layer->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); // Populate all tiles directly from the tilings. all_tiles.clear(); std::vector<Tile*> pending_high_res_tiles = - pending_layer_->HighResTiling()->AllTilesForTesting(); + pending_layer()->HighResTiling()->AllTilesForTesting(); all_tiles.insert(pending_high_res_tiles.begin(), pending_high_res_tiles.end()); @@ -973,8 +849,8 @@ TEST_F(TileManagerTilePriorityQueueTest, TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY; size_t occluded_count = 0u; PrioritizedTile last_tile; - scoped_ptr<EvictionTilePriorityQueue> queue( - host_impl_.BuildEvictionQueue(tree_priority)); + std::unique_ptr<EvictionTilePriorityQueue> queue( + host_impl()->BuildEvictionQueue(tree_priority)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); if (!last_tile.tile()) @@ -1010,7 +886,7 @@ TEST_F(TileManagerTilePriorityQueueTest, TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueWithTransparentLayer) { - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); @@ -1018,39 +894,39 @@ TEST_F(TileManagerTilePriorityQueueTest, FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - scoped_ptr<FakePictureLayerImpl> pending_child = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), 2, - pending_raster_source); + std::unique_ptr<FakePictureLayerImpl> pending_child = + FakePictureLayerImpl::CreateWithRasterSource(host_impl()->pending_tree(), + 2, pending_raster_source); FakePictureLayerImpl* pending_child_layer = pending_child.get(); - pending_layer_->AddChild(std::move(pending_child)); + pending_layer()->AddChild(std::move(pending_child)); // Create a fully transparent child layer so that its tile priorities are not // considered to be valid. pending_child_layer->SetDrawsContent(true); - pending_child_layer->SetForceRenderSurface(true); + pending_child_layer->test_properties()->force_render_surface = true; - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); bool update_lcd_text = false; - host_impl_.pending_tree()->property_trees()->needs_rebuild = true; - host_impl_.pending_tree()->BuildPropertyTreesForTesting(); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->pending_tree()->property_trees()->needs_rebuild = true; + host_impl()->pending_tree()->BuildPropertyTreesForTesting(); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); pending_child_layer->OnOpacityAnimated(0.0); - host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); // Renew all of the tile priorities. gfx::Rect viewport(layer_bounds); - pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, - Occlusion()); - pending_child_layer->HighResTiling()->ComputeTilePriorityRects( - viewport, 1.0f, 1.0, Occlusion()); + pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); + pending_child_layer->picture_layer_tiling_set()->UpdateTilePriorities( + viewport, 1.0f, 1.0, Occlusion(), true); // Populate all tiles directly from the tilings. std::set<Tile*> all_pending_tiles; std::vector<Tile*> pending_high_res_tiles = - pending_layer_->HighResTiling()->AllTilesForTesting(); + pending_layer()->HighResTiling()->AllTilesForTesting(); all_pending_tiles.insert(pending_high_res_tiles.begin(), pending_high_res_tiles.end()); EXPECT_EQ(16u, pending_high_res_tiles.size()); @@ -1069,7 +945,7 @@ TEST_F(TileManagerTilePriorityQueueTest, tile_manager()->InitializeTilesWithResourcesForTesting( std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); - EXPECT_TRUE(pending_layer_->HasValidTilePriorities()); + EXPECT_TRUE(pending_layer()->HasValidTilePriorities()); EXPECT_FALSE(pending_child_layer->HasValidTilePriorities()); // Verify that eviction queue returns tiles also from layers without valid @@ -1078,8 +954,8 @@ TEST_F(TileManagerTilePriorityQueueTest, TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY; std::set<Tile*> new_content_tiles; size_t tile_count = 0; - scoped_ptr<EvictionTilePriorityQueue> queue( - host_impl_.BuildEvictionQueue(tree_priority)); + std::unique_ptr<EvictionTilePriorityQueue> queue( + host_impl()->BuildEvictionQueue(tree_priority)); while (!queue->IsEmpty()) { PrioritizedTile prioritized_tile = queue->Top(); Tile* tile = prioritized_tile.tile(); @@ -1100,10 +976,10 @@ TEST_F(TileManagerTilePriorityQueueTest, TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); @@ -1120,15 +996,16 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) { EXPECT_EQ(16u, tile_count); for (int i = 1; i < 10; ++i) { - scoped_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i); - pending_layer->SetDrawsContent(true); - pending_layer->set_has_valid_tile_priorities(true); - pending_layer_->AddChild(std::move(pending_layer)); + std::unique_ptr<FakePictureLayerImpl> pending_child_layer = + FakePictureLayerImpl::Create(host_impl()->pending_tree(), + layer_id() + i); + pending_child_layer->SetDrawsContent(true); + pending_child_layer->set_has_valid_tile_priorities(true); + pending_layer()->AddChild(std::move(pending_child_layer)); } - queue = host_impl_.BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES, - RasterTilePriorityQueue::Type::ALL); + queue = host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES, + RasterTilePriorityQueue::Type::ALL); EXPECT_FALSE(queue->IsEmpty()); tile_count = 0; @@ -1145,11 +1022,12 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) { TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); - scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue( - SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); + std::unique_ptr<RasterTilePriorityQueue> raster_queue( + host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES, + RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(raster_queue->IsEmpty()); size_t tile_count = 0; @@ -1164,18 +1042,19 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) { EXPECT_EQ(16u, tile_count); std::vector<Tile*> tiles(all_tiles.begin(), all_tiles.end()); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); for (int i = 1; i < 10; ++i) { - scoped_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i); - pending_layer->SetDrawsContent(true); - pending_layer->set_has_valid_tile_priorities(true); - pending_layer_->AddChild(std::move(pending_layer)); + std::unique_ptr<FakePictureLayerImpl> pending_child_layer = + FakePictureLayerImpl::Create(host_impl()->pending_tree(), + layer_id() + i); + pending_child_layer->SetDrawsContent(true); + pending_child_layer->set_has_valid_tile_priorities(true); + pending_layer()->AddChild(std::move(pending_child_layer)); } - scoped_ptr<EvictionTilePriorityQueue> queue( - host_impl_.BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); + std::unique_ptr<EvictionTilePriorityQueue> queue( + host_impl()->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); EXPECT_FALSE(queue->IsEmpty()); tile_count = 0; @@ -1197,17 +1076,19 @@ TEST_F(TileManagerTilePriorityQueueTest, gfx::Rect viewport(50, 50, 500, 500); gfx::Size layer_bounds(1600, 1600); - float inset = PictureLayerTiling::CalculateSoonBorderDistance(viewport, 1.0f); + const int soon_border_outset = 312; gfx::Rect soon_rect = viewport; - soon_rect.Inset(-inset, -inset); + soon_rect.Inset(-soon_border_outset, -soon_border_outset); client.SetTileSize(gfx::Size(30, 30)); LayerTreeSettings settings; + settings.verify_clip_tree_calculations = true; - scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( - ACTIVE_TREE, &client, settings.tiling_interest_area_padding, - settings.skewport_target_time_in_seconds, - settings.skewport_extrapolation_limit_in_content_pixels); + std::unique_ptr<PictureLayerTilingSet> tiling_set = + PictureLayerTilingSet::Create( + ACTIVE_TREE, &client, settings.tiling_interest_area_padding, + settings.skewport_target_time_in_seconds, + settings.skewport_extrapolation_limit_in_screen_pixels); scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -1227,7 +1108,7 @@ TEST_F(TileManagerTilePriorityQueueTest, // 3. Third iteration ensures that no tiles are returned, since they were all // marked as ready to draw. for (int i = 0; i < 3; ++i) { - scoped_ptr<TilingSetRasterQueueAll> queue( + std::unique_ptr<TilingSetRasterQueueAll> queue( new TilingSetRasterQueueAll(tiling_set.get(), false)); // There are 3 bins in TilePriority. @@ -1312,11 +1193,13 @@ TEST_F(TileManagerTilePriorityQueueTest, client.SetTileSize(gfx::Size(30, 30)); LayerTreeSettings settings; + settings.verify_clip_tree_calculations = true; - scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( - ACTIVE_TREE, &client, settings.tiling_interest_area_padding, - settings.skewport_target_time_in_seconds, - settings.skewport_extrapolation_limit_in_content_pixels); + std::unique_ptr<PictureLayerTilingSet> tiling_set = + PictureLayerTilingSet::Create( + ACTIVE_TREE, &client, settings.tiling_interest_area_padding, + settings.skewport_target_time_in_seconds, + settings.skewport_extrapolation_limit_in_screen_pixels); scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -1327,17 +1210,16 @@ TEST_F(TileManagerTilePriorityQueueTest, tiling_set->UpdateTilePriorities(moved_viewport, 1.0f, 2.0, Occlusion(), true); - float inset = - PictureLayerTiling::CalculateSoonBorderDistance(moved_viewport, 1.0f); + const int soon_border_outset = 312; gfx::Rect soon_rect = moved_viewport; - soon_rect.Inset(-inset, -inset); + soon_rect.Inset(-soon_border_outset, -soon_border_outset); // There are 3 bins in TilePriority. bool have_tiles[3] = {}; PrioritizedTile last_tile; int eventually_bin_order_correct_count = 0; int eventually_bin_order_incorrect_count = 0; - scoped_ptr<TilingSetRasterQueueAll> queue( + std::unique_ptr<TilingSetRasterQueueAll> queue( new TilingSetRasterQueueAll(tiling_set.get(), false)); for (; !queue->IsEmpty(); queue->Pop()) { if (!last_tile.tile()) @@ -1378,87 +1260,87 @@ TEST_F(TileManagerTilePriorityQueueTest, TEST_F(TileManagerTilePriorityQueueTest, SetIsLikelyToRequireADraw) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); // Verify that the queue has a required for draw tile at Top. - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); EXPECT_TRUE(queue->Top().tile()->required_for_draw()); - EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); - host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state()); - EXPECT_TRUE(host_impl_.is_likely_to_require_a_draw()); + EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw()); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_TRUE(host_impl()->is_likely_to_require_a_draw()); } TEST_F(TileManagerTilePriorityQueueTest, SetIsLikelyToRequireADrawOnZeroMemoryBudget) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); // Verify that the queue has a required for draw tile at Top. - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); EXPECT_TRUE(queue->Top().tile()->required_for_draw()); - ManagedMemoryPolicy policy = host_impl_.ActualManagedMemoryPolicy(); + ManagedMemoryPolicy policy = host_impl()->ActualManagedMemoryPolicy(); policy.bytes_limit_when_visible = 0; - host_impl_.SetMemoryPolicy(policy); + host_impl()->SetMemoryPolicy(policy); - EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); - host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state()); - EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); + EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw()); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw()); } TEST_F(TileManagerTilePriorityQueueTest, SetIsLikelyToRequireADrawOnLimitedMemoryBudget) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); // Verify that the queue has a required for draw tile at Top. - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); EXPECT_TRUE(queue->Top().tile()->required_for_draw()); EXPECT_EQ(gfx::Size(256, 256), queue->Top().tile()->desired_texture_size()); - EXPECT_EQ(RGBA_8888, host_impl_.resource_provider()->best_texture_format()); + EXPECT_EQ(RGBA_8888, host_impl()->resource_provider()->best_texture_format()); - ManagedMemoryPolicy policy = host_impl_.ActualManagedMemoryPolicy(); + ManagedMemoryPolicy policy = host_impl()->ActualManagedMemoryPolicy(); policy.bytes_limit_when_visible = ResourceUtil::UncheckedSizeInBytes<size_t>( gfx::Size(256, 256), RGBA_8888); - host_impl_.SetMemoryPolicy(policy); + host_impl()->SetMemoryPolicy(policy); - EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); - host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state()); - EXPECT_TRUE(host_impl_.is_likely_to_require_a_draw()); + EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw()); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_TRUE(host_impl()->is_likely_to_require_a_draw()); - Resource* resource = host_impl_.resource_pool()->AcquireResource( + Resource* resource = host_impl()->resource_pool()->AcquireResource( gfx::Size(256, 256), RGBA_8888); - host_impl_.tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting(); - EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); + host_impl()->tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting(); + EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw()); - host_impl_.resource_pool()->ReleaseResource(resource, 0); + host_impl()->resource_pool()->ReleaseResource(resource, 0); } TEST_F(TileManagerTilePriorityQueueTest, DefaultMemoryPolicy) { const gfx::Size layer_bounds(1000, 1000); - host_impl_.SetViewportSize(layer_bounds); + host_impl()->SetViewportSize(layer_bounds); SetupDefaultTrees(layer_bounds); - host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state()); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); // 64MB is the default mem limit. EXPECT_EQ(67108864u, - host_impl_.global_tile_state().hard_memory_limit_in_bytes); + host_impl()->global_tile_state().hard_memory_limit_in_bytes); EXPECT_EQ(TileMemoryLimitPolicy::ALLOW_ANYTHING, - host_impl_.global_tile_state().memory_limit_policy); + host_impl()->global_tile_state().memory_limit_policy); EXPECT_EQ(ManagedMemoryPolicy::kDefaultNumResourcesLimit, - host_impl_.global_tile_state().num_resources_limit); + host_impl()->global_tile_state().num_resources_limit); } TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) { @@ -1472,8 +1354,9 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) { FakePictureLayerTilingClient pending_client; pending_client.SetTileSize(gfx::Size(64, 64)); - scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( - WhichTree::ACTIVE_TREE, &pending_client, 1.0f, 1.0f, 1000); + std::unique_ptr<PictureLayerTilingSet> 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, raster_source); @@ -1493,7 +1376,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) { intersecting_rect, // Skewport rect. intersecting_rect, // Soon rect. intersecting_rect); // Eventually rect. - scoped_ptr<TilingSetRasterQueueAll> queue( + std::unique_ptr<TilingSetRasterQueueAll> queue( new TilingSetRasterQueueAll(tiling_set.get(), false)); EXPECT_FALSE(queue->IsEmpty()); } @@ -1503,7 +1386,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) { non_intersecting_rect, // Skewport rect. intersecting_rect, // Soon rect. intersecting_rect); // Eventually rect. - scoped_ptr<TilingSetRasterQueueAll> queue( + std::unique_ptr<TilingSetRasterQueueAll> queue( new TilingSetRasterQueueAll(tiling_set.get(), false)); EXPECT_FALSE(queue->IsEmpty()); } @@ -1513,7 +1396,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) { non_intersecting_rect, // Skewport rect. non_intersecting_rect, // Soon rect. intersecting_rect); // Eventually rect. - scoped_ptr<TilingSetRasterQueueAll> queue( + std::unique_ptr<TilingSetRasterQueueAll> queue( new TilingSetRasterQueueAll(tiling_set.get(), false)); EXPECT_FALSE(queue->IsEmpty()); } @@ -1523,7 +1406,7 @@ TEST_F(TileManagerTilePriorityQueueTest, NoRasterTasksforSolidColorTiles) { gfx::Size size(10, 10); const gfx::Size layer_bounds(1000, 1000); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); SkPaint solid_paint; @@ -1547,8 +1430,9 @@ TEST_F(TileManagerTilePriorityQueueTest, NoRasterTasksforSolidColorTiles) { FakePictureLayerTilingClient tiling_client; tiling_client.SetTileSize(size); - scoped_ptr<PictureLayerImpl> layer_impl = - PictureLayerImpl::Create(host_impl_.active_tree(), 1, false); + std::unique_ptr<PictureLayerImpl> layer_impl = + PictureLayerImpl::Create(host_impl()->active_tree(), 1, false); + layer_impl->set_is_drawn_render_surface_layer_list_member(true); PictureLayerTilingSet* tiling_set = layer_impl->picture_layer_tiling_set(); PictureLayerTiling* tiling = tiling_set->AddTiling(1.0f, raster_source); @@ -1560,7 +1444,7 @@ TEST_F(TileManagerTilePriorityQueueTest, NoRasterTasksforSolidColorTiles) { gfx::Rect(layer_bounds), // Soon rect. gfx::Rect(layer_bounds)); // Eventually rect. - host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state()); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); std::vector<Tile*> tiles = tiling->AllTilesForTesting(); for (size_t tile_idx = 0; tile_idx < tiles.size(); ++tile_idx) { @@ -1577,101 +1461,47 @@ TEST_F(TileManagerTilePriorityQueueTest, NoRasterTasksforSolidColorTiles) { } } -// TODO(vmpstr): Merge TileManagerTest and TileManagerTilePriorityQueueTest. -class TileManagerTest : public testing::Test { +class TileManagerTest : public TestLayerTreeHostBase { public: - TileManagerTest() - : output_surface_(FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice))) {} - - void SetUp() override { - LayerTreeSettings settings; - CustomizeSettings(&settings); - host_impl_.reset(new MockLayerTreeHostImpl(settings, &task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_)); - host_impl_->SetVisible(true); - host_impl_->InitializeRenderer(output_surface_.get()); - } - - void SetupDefaultTrees(const gfx::Size& layer_bounds) { - scoped_refptr<FakeRasterSource> pending_raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - scoped_refptr<FakeRasterSource> active_raster_source = - FakeRasterSource::CreateFilled(layer_bounds); - - SetupTrees(pending_raster_source, active_raster_source); - } - - // This matches picture_layer_impl_unittest's ActivateTree. - void ActivateTree() { - host_impl_->ActivateSyncTree(); - CHECK(!host_impl_->pending_tree()); - bool update_lcd_text = false; - host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); - } - - void SetupTrees(scoped_refptr<RasterSource> pending_raster_source, - scoped_refptr<RasterSource> active_raster_source) { - SetupPendingTree(active_raster_source); - ActivateTree(); - SetupPendingTree(pending_raster_source); - } - - void SetupPendingTree(scoped_refptr<RasterSource> raster_source) { - host_impl_->CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - - // Steal from the recycled tree. - LayerImpl* old_pending_root = pending_tree->root_layer(); - FakePictureLayerImpl* pending_layer = nullptr; - if (old_pending_root) { - pending_layer = static_cast<FakePictureLayerImpl*>(old_pending_root); - pending_layer->SetRasterSourceOnPending(raster_source, Region()); - } else { - int id = 7; - scoped_ptr<FakePictureLayerImpl> new_root = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id, - raster_source); - pending_layer = new_root.get(); - pending_layer->SetDrawsContent(true); - pending_layer->SetHasRenderSurface(true); - pending_tree->SetRootLayer(std::move(new_root)); - } - - // The bounds() just mirror the raster source size. - pending_layer->SetBounds(pending_layer->raster_source()->GetSize()); - - // Add tilings/tiles for the layer. - bool update_lcd_text = false; - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - host_impl_->pending_tree()->UpdateDrawProperties(update_lcd_text); - } - - protected: // MockLayerTreeHostImpl allows us to intercept tile manager callbacks. class MockLayerTreeHostImpl : public FakeLayerTreeHostImpl { public: - MockLayerTreeHostImpl(const LayerTreeSettings& settings, - TaskRunnerProvider* task_runner_provider, - SharedBitmapManager* manager, - TaskGraphRunner* task_graph_runner) + MockLayerTreeHostImpl( + const LayerTreeSettings& settings, + TaskRunnerProvider* task_runner_provider, + SharedBitmapManager* manager, + TaskGraphRunner* task_graph_runner, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) : FakeLayerTreeHostImpl(settings, task_runner_provider, manager, - task_graph_runner) {} + task_graph_runner, + gpu_memory_buffer_manager) {} MOCK_METHOD0(NotifyAllTileTasksCompleted, void()); + MOCK_METHOD0(NotifyReadyToDraw, void()); }; - // By default do no customization. - virtual void CustomizeSettings(LayerTreeSettings* settings) {} + std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl( + const LayerTreeSettings& settings, + TaskRunnerProvider* task_runner_provider, + SharedBitmapManager* shared_bitmap_manager, + TaskGraphRunner* task_graph_runner, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) override { + return base::WrapUnique(new MockLayerTreeHostImpl( + settings, task_runner_provider, shared_bitmap_manager, + task_graph_runner, gpu_memory_buffer_manager)); + } + + // By default use SoftwareOutputSurface. + std::unique_ptr<OutputSurface> CreateOutputSurface() override { + return FakeOutputSurface::CreateSoftware( + base::WrapUnique(new SoftwareOutputDevice)); + } - TestSharedBitmapManager shared_bitmap_manager_; - TestTaskGraphRunner task_graph_runner_; - FakeImplTaskRunnerProvider task_runner_provider_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<MockLayerTreeHostImpl> host_impl_; + MockLayerTreeHostImpl& MockHostImpl() { + return *static_cast<MockLayerTreeHostImpl*>(host_impl()); + } }; // Test to ensure that we call NotifyAllTileTasksCompleted when PrepareTiles is @@ -1680,11 +1510,12 @@ 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()) + EXPECT_FALSE( + host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), 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()); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); run_loop.Run(); } @@ -1692,12 +1523,13 @@ TEST_F(TileManagerTest, AllWorkFinishedTest) { // callback. { base::RunLoop run_loop; - EXPECT_FALSE(host_impl_->tile_manager()->HasScheduledTileTasksForTesting()); - EXPECT_CALL(*host_impl_, NotifyAllTileTasksCompleted()) + EXPECT_FALSE( + host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), 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()); + 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(); } } @@ -1705,34 +1537,35 @@ TEST_F(TileManagerTest, AllWorkFinishedTest) { TEST_F(TileManagerTest, ActivateAndDrawWhenOOM) { SetupDefaultTrees(gfx::Size(1000, 1000)); - auto global_state = host_impl_->global_tile_state(); + auto global_state = host_impl()->global_tile_state(); global_state.hard_memory_limit_in_bytes = 1u; global_state.soft_memory_limit_in_bytes = 1u; { base::RunLoop run_loop; - EXPECT_FALSE(host_impl_->tile_manager()->HasScheduledTileTasksForTesting()); - EXPECT_CALL(*host_impl_, NotifyAllTileTasksCompleted()) + EXPECT_FALSE( + host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); - host_impl_->tile_manager()->PrepareTiles(global_state); - EXPECT_TRUE(host_impl_->tile_manager()->HasScheduledTileTasksForTesting()); + host_impl()->tile_manager()->PrepareTiles(global_state); + EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); run_loop.Run(); } - EXPECT_TRUE(host_impl_->tile_manager()->IsReadyToDraw()); - EXPECT_TRUE(host_impl_->tile_manager()->IsReadyToActivate()); - EXPECT_TRUE(host_impl_->notify_tile_state_changed_called()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); + EXPECT_TRUE(host_impl()->notify_tile_state_changed_called()); // Next PrepareTiles should skip NotifyTileStateChanged since all tiles // are marked oom already. { base::RunLoop run_loop; - host_impl_->set_notify_tile_state_changed_called(false); - EXPECT_CALL(*host_impl_, NotifyAllTileTasksCompleted()) + host_impl()->set_notify_tile_state_changed_called(false); + EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); - host_impl_->tile_manager()->PrepareTiles(global_state); + host_impl()->tile_manager()->PrepareTiles(global_state); run_loop.Run(); - EXPECT_FALSE(host_impl_->notify_tile_state_changed_called()); + EXPECT_FALSE(host_impl()->notify_tile_state_changed_called()); } } @@ -1748,10 +1581,9 @@ TEST_F(TileManagerTest, LowResHasNoImage) { SkSurface::MakeRasterN32Premul(size.width(), size.height()); ASSERT_NE(surface, nullptr); surface->getCanvas()->clear(SK_ColorBLUE); - skia::RefPtr<SkImage> blue_image = - skia::AdoptRef(surface->newImageSnapshot()); + sk_sp<SkImage> blue_image = surface->makeImageSnapshot(); - scoped_ptr<FakeRecordingSource> recording_source = + std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(size); recording_source->SetBackgroundColor(SK_ColorTRANSPARENT); recording_source->SetRequiresClear(true); @@ -1759,7 +1591,7 @@ TEST_F(TileManagerTest, LowResHasNoImage) { SkPaint paint; paint.setColor(SK_ColorGREEN); recording_source->add_draw_rect_with_paint(gfx::Rect(size), paint); - recording_source->add_draw_image(blue_image.get(), gfx::Point()); + recording_source->add_draw_image(std::move(blue_image), gfx::Point()); recording_source->Rerecord(); scoped_refptr<RasterSource> raster = RasterSource::CreateFromRecordingSource(recording_source.get(), false); @@ -1767,9 +1599,10 @@ TEST_F(TileManagerTest, LowResHasNoImage) { FakePictureLayerTilingClient tiling_client; tiling_client.SetTileSize(size); - scoped_ptr<PictureLayerImpl> layer = - PictureLayerImpl::Create(host_impl_->active_tree(), 1, false); + std::unique_ptr<PictureLayerImpl> layer = + PictureLayerImpl::Create(host_impl()->active_tree(), 1, false); PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set(); + layer->set_is_drawn_render_surface_layer_list_member(true); auto* tiling = tiling_set->AddTiling(1.0f, raster); tiling->set_resolution(resolutions[i]); @@ -1782,14 +1615,14 @@ TEST_F(TileManagerTest, LowResHasNoImage) { // SMOOTHNESS_TAKES_PRIORITY ensures that we will actually raster // LOW_RESOLUTION tiles, otherwise they are skipped. - host_impl_->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY); + host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY); // Call PrepareTiles and wait for it to complete. - auto* tile_manager = host_impl_->tile_manager(); + auto* tile_manager = host_impl()->tile_manager(); base::RunLoop run_loop; - EXPECT_CALL(*host_impl_, NotifyAllTileTasksCompleted()) + EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); - tile_manager->PrepareTiles(host_impl_->global_tile_state()); + tile_manager->PrepareTiles(host_impl()->global_tile_state()); run_loop.Run(); tile_manager->Flush(); @@ -1799,7 +1632,7 @@ TEST_F(TileManagerTest, LowResHasNoImage) { EXPECT_TRUE(tile->draw_info().IsReadyToDraw()); ResourceProvider::ScopedReadLockSoftware lock( - host_impl_->resource_provider(), tile->draw_info().resource_id()); + host_impl()->resource_provider(), tile->draw_info().resource_id()); const SkBitmap* bitmap = lock.sk_bitmap(); for (int x = 0; x < size.width(); ++x) { for (int y = 0; y < size.height(); ++y) { @@ -1820,54 +1653,95 @@ TEST_F(TileManagerTest, LowResHasNoImage) { } } -// Fake TileTaskRunner that just no-ops all calls. -class FakeTileTaskRunner : public TileTaskRunner, public TileTaskClient { - public: - FakeTileTaskRunner() {} - ~FakeTileTaskRunner() override {} - - // TileTaskRunner methods. - void Shutdown() override {} - void CheckForCompletedTasks() override {} - ResourceFormat GetResourceFormat(bool must_support_alpha) const override { - return ResourceFormat::RGBA_8888; - } - bool GetResourceRequiresSwizzle(bool must_support_alpha) const override { - return false; +class ActivationTasksDoNotBlockReadyToDrawTest : public TileManagerTest { + protected: + std::unique_ptr<TaskGraphRunner> CreateTaskGraphRunner() override { + return base::WrapUnique(new SynchronousTaskGraphRunner()); } - void ScheduleTasks(TaskGraph* graph) override {} + std::unique_ptr<OutputSurface> CreateOutputSurface() override { + return FakeOutputSurface::Create3d(); + } - // TileTaskClient methods. - scoped_ptr<RasterBuffer> AcquireBufferForRaster( - const Resource* resource, - uint64_t resource_content_id, - uint64_t previous_content_id) override { - NOTREACHED(); - return nullptr; + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = TileManagerTest::CreateSettings(); + settings.gpu_rasterization_forced = true; + return settings; } - void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override {} }; -// Fake TileTaskRunner that just cancels all scheduled tasks immediately. -class CancellingTileTaskRunner : public FakeTileTaskRunner { +TEST_F(ActivationTasksDoNotBlockReadyToDrawTest, + ActivationTasksDoNotBlockReadyToDraw) { + const gfx::Size layer_bounds(1000, 1000); + + EXPECT_TRUE(host_impl()->use_gpu_rasterization()); + + // Active tree has no non-solid tiles, so it will generate no tile tasks. + std::unique_ptr<FakeRecordingSource> active_tree_recording_source = + FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); + + SkPaint solid_paint; + SkColor solid_color = SkColorSetARGB(255, 12, 23, 34); + solid_paint.setColor(solid_color); + active_tree_recording_source->add_draw_rect_with_paint( + gfx::Rect(layer_bounds), solid_paint); + + active_tree_recording_source->Rerecord(); + + // Pending tree has non-solid tiles, so it will generate tile tasks. + std::unique_ptr<FakeRecordingSource> pending_tree_recording_source = + FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); + SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67); + SkPaint non_solid_paint; + non_solid_paint.setColor(non_solid_color); + + pending_tree_recording_source->add_draw_rect_with_paint( + gfx::Rect(5, 5, 10, 10), non_solid_paint); + pending_tree_recording_source->Rerecord(); + + scoped_refptr<RasterSource> active_tree_raster_source = + RasterSource::CreateFromRecordingSource( + active_tree_recording_source.get(), false); + scoped_refptr<RasterSource> pending_tree_raster_source = + RasterSource::CreateFromRecordingSource( + pending_tree_recording_source.get(), false); + + SetupTrees(pending_tree_raster_source, active_tree_raster_source); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + + // The first task to run should be ReadyToDraw (this should not be blocked by + // the tasks required for activation). + base::RunLoop run_loop; + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()) + .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); + static_cast<SynchronousTaskGraphRunner*>(task_graph_runner()) + ->RunSingleTaskForTesting(); + run_loop.Run(); +} + +// Fake TileTaskManager that just cancels all scheduled tasks immediately. +class CancellingTileTaskManager : public FakeTileTaskManagerImpl { public: - CancellingTileTaskRunner() {} - ~CancellingTileTaskRunner() override {} + CancellingTileTaskManager() {} + ~CancellingTileTaskManager() override {} void ScheduleTasks(TaskGraph* graph) override { // Just call CompleteOnOriginThread on each item in the queue. As none of // these items have run yet, they will be treated as cancelled tasks. for (const auto& node : graph->nodes) { - static_cast<TileTask*>(node.task)->CompleteOnOriginThread(this); + static_cast<TileTask*>(node.task)->CompleteOnOriginThread( + raster_buffer_provider_.get()); } } + void CheckForCompletedTasks() override {} }; class PartialRasterTileManagerTest : public TileManagerTest { public: - void CustomizeSettings(LayerTreeSettings* settings) override { - settings->use_partial_raster = true; + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = TileManagerTest::CreateSettings(); + settings.use_partial_raster = true; + return settings; } }; @@ -1876,8 +1750,9 @@ class PartialRasterTileManagerTest : public TileManagerTest { TEST_F(PartialRasterTileManagerTest, CancelledTasksHaveNoContentId) { // Create a CancellingTaskRunner and set it on the tile manager so that all // scheduled work is immediately cancelled. - CancellingTileTaskRunner cancelling_runner; - host_impl_->tile_manager()->SetTileTaskRunnerForTesting(&cancelling_runner); + CancellingTileTaskManager cancelling_task_manager; + host_impl()->tile_manager()->SetTileTaskManagerForTesting( + &cancelling_task_manager); // Pick arbitrary IDs - they don't really matter as long as they're constant. const int kLayerId = 7; @@ -1886,11 +1761,11 @@ TEST_F(PartialRasterTileManagerTest, CancelledTasksHaveNoContentId) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(kTileSize); - host_impl_->CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl_->pending_tree(); + host_impl()->CreatePendingTree(); + LayerTreeImpl* pending_tree = host_impl()->pending_tree(); // Steal from the recycled tree. - scoped_ptr<FakePictureLayerImpl> pending_layer = + std::unique_ptr<FakePictureLayerImpl> pending_layer = FakePictureLayerImpl::CreateWithRasterSource(pending_tree, kLayerId, pending_raster_source); pending_layer->SetDrawsContent(true); @@ -1901,49 +1776,43 @@ TEST_F(PartialRasterTileManagerTest, CancelledTasksHaveNoContentId) { pending_tree->SetRootLayer(std::move(pending_layer)); // Add tilings/tiles for the layer. - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - host_impl_->pending_tree()->UpdateDrawProperties(false /* update_lcd_text */); + host_impl()->pending_tree()->BuildPropertyTreesForTesting(); + host_impl()->pending_tree()->UpdateDrawProperties( + false /* update_lcd_text */); // Build the raster queue and invalidate the top tile. - scoped_ptr<RasterTilePriorityQueue> queue(host_impl_->BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); queue->Top().tile()->SetInvalidated(gfx::Rect(), kInvalidatedId); - // PrepareTiles to schedule tasks. Due to the CancellingTileTaskRunner, these - // tasks will immediately be canceled. - host_impl_->tile_manager()->PrepareTiles(host_impl_->global_tile_state()); + // PrepareTiles to schedule tasks. Due to the CancellingTileTaskManager, + // these tasks will immediately be canceled. + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); // Make sure that the tile we invalidated above was not returned to the pool // with its invalidated resource ID. - host_impl_->resource_pool()->CheckBusyResources(); - EXPECT_FALSE(host_impl_->resource_pool()->TryAcquireResourceWithContentId( + host_impl()->resource_pool()->CheckBusyResources(); + EXPECT_FALSE(host_impl()->resource_pool()->TryAcquireResourceWithContentId( kInvalidatedId)); - // Free our host_impl_ before the cancelling_runner we passed it, as it will - // use that class in clean up. - host_impl_ = nullptr; + // Free our host_impl_ before the cancelling_task_manager we passed it, as it + // will use that class in clean up. + TakeHostImpl(); } -// Fake TileTaskRunner that verifies the resource content ID of raster tasks. -class VerifyResourceContentIdTileTaskRunner : public FakeTileTaskRunner { +// FakeRasterBufferProviderImpl that verifies the resource content ID of raster +// tasks. +class VerifyResourceContentIdRasterBufferProvider + : public FakeRasterBufferProviderImpl { public: - explicit VerifyResourceContentIdTileTaskRunner(uint64_t expected_resource_id) + explicit VerifyResourceContentIdRasterBufferProvider( + uint64_t expected_resource_id) : expected_resource_id_(expected_resource_id) {} - ~VerifyResourceContentIdTileTaskRunner() override {} - - void ScheduleTasks(TaskGraph* graph) override { - for (const auto& node : graph->nodes) { - TileTask* task = static_cast<TileTask*>(node.task); - // Triggers a call to AcquireBufferForRaster. - task->ScheduleOnOriginThread(this); - // Calls TileManager as though task was cancelled. - task->CompleteOnOriginThread(this); - } - } + ~VerifyResourceContentIdRasterBufferProvider() override {} - // TileTaskClient methods. - scoped_ptr<RasterBuffer> AcquireBufferForRaster( + // RasterBufferProvider methods. + std::unique_ptr<RasterBuffer> AcquireBufferForRaster( const Resource* resource, uint64_t resource_content_id, uint64_t previous_content_id) override { @@ -1955,10 +1824,30 @@ class VerifyResourceContentIdTileTaskRunner : public FakeTileTaskRunner { uint64_t expected_resource_id_; }; +class VerifyResourceContentIdTileTaskManager : public FakeTileTaskManagerImpl { + public: + explicit VerifyResourceContentIdTileTaskManager(uint64_t expected_resource_id) + : FakeTileTaskManagerImpl(base::WrapUnique<RasterBufferProvider>( + new VerifyResourceContentIdRasterBufferProvider( + expected_resource_id))) {} + ~VerifyResourceContentIdTileTaskManager() override {} + + void ScheduleTasks(TaskGraph* graph) override { + for (const auto& node : graph->nodes) { + TileTask* task = static_cast<TileTask*>(node.task); + // Triggers a call to AcquireBufferForRaster. + task->ScheduleOnOriginThread(raster_buffer_provider_.get()); + // Calls TileManager as though task was cancelled. + task->CompleteOnOriginThread(raster_buffer_provider_.get()); + } + } + void CheckForCompletedTasks() override {} +}; + // Runs a test to ensure that partial raster is either enabled or disabled, // depending on |partial_raster_enabled|'s value. Takes ownership of host_impl // so that cleanup order can be controlled. -void RunPartialRasterCheck(scoped_ptr<LayerTreeHostImpl> host_impl, +void RunPartialRasterCheck(std::unique_ptr<LayerTreeHostImpl> host_impl, bool partial_raster_enabled) { // Pick arbitrary IDs - they don't really matter as long as they're constant. const int kLayerId = 7; @@ -1966,10 +1855,11 @@ void RunPartialRasterCheck(scoped_ptr<LayerTreeHostImpl> host_impl, const uint64_t kExpectedId = partial_raster_enabled ? kInvalidatedId : 0u; const gfx::Size kTileSize(128, 128); - // Create a VerifyResourceContentIdTileTaskRunner to ensure that the raster - // task we see is created with |kExpectedId|. - VerifyResourceContentIdTileTaskRunner verifying_runner(kExpectedId); - host_impl->tile_manager()->SetTileTaskRunnerForTesting(&verifying_runner); + // Create a VerifyResourceContentIdTileTaskManager to ensure that the + // raster task we see is created with |kExpectedId|. + VerifyResourceContentIdTileTaskManager verifying_task_manager(kExpectedId); + host_impl->tile_manager()->SetTileTaskManagerForTesting( + &verifying_task_manager); // Ensure there's a resource with our |kInvalidatedId| in the resource pool. host_impl->resource_pool()->ReleaseResource( @@ -1983,7 +1873,7 @@ void RunPartialRasterCheck(scoped_ptr<LayerTreeHostImpl> host_impl, LayerTreeImpl* pending_tree = host_impl->pending_tree(); // Steal from the recycled tree. - scoped_ptr<FakePictureLayerImpl> pending_layer = + std::unique_ptr<FakePictureLayerImpl> pending_layer = FakePictureLayerImpl::CreateWithRasterSource(pending_tree, kLayerId, pending_raster_source); pending_layer->SetDrawsContent(true); @@ -1998,33 +1888,31 @@ void RunPartialRasterCheck(scoped_ptr<LayerTreeHostImpl> host_impl, host_impl->pending_tree()->UpdateDrawProperties(false /* update_lcd_text */); // Build the raster queue and invalidate the top tile. - scoped_ptr<RasterTilePriorityQueue> queue(host_impl->BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> queue(host_impl->BuildRasterQueue( SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); EXPECT_FALSE(queue->IsEmpty()); queue->Top().tile()->SetInvalidated(gfx::Rect(), kInvalidatedId); // PrepareTiles to schedule tasks. Due to the - // VerifyPreviousContentTileTaskRunner, these tasks will verified and + // VerifyPreviousContentRasterBufferProvider, these tasks will verified and // cancelled. host_impl->tile_manager()->PrepareTiles(host_impl->global_tile_state()); - // Free our host_impl before the cancelling_runner we passed it, as it will - // use that class in clean up. + // Free our host_impl before the verifying_task_manager we passed it, as it + // will use that class in clean up. host_impl = nullptr; } // Ensures that the tile manager successfully reuses tiles when partial // raster is enabled. TEST_F(PartialRasterTileManagerTest, PartialRasterSuccessfullyEnabled) { - RunPartialRasterCheck(std::move(host_impl_), - true /* partial_raster_enabled */); + RunPartialRasterCheck(TakeHostImpl(), true /* partial_raster_enabled */); } // Ensures that the tile manager does not attempt to reuse tiles when partial // raster is disabled. TEST_F(TileManagerTest, PartialRasterSuccessfullyDisabled) { - RunPartialRasterCheck(std::move(host_impl_), - false /* partial_raster_enabled */); + RunPartialRasterCheck(TakeHostImpl(), false /* partial_raster_enabled */); } } // namespace diff --git a/chromium/cc/tiles/tile_priority.h b/chromium/cc/tiles/tile_priority.h index 023fac53cf0..cf0bbd13817 100644 --- a/chromium/cc/tiles/tile_priority.h +++ b/chromium/cc/tiles/tile_priority.h @@ -9,9 +9,9 @@ #include <algorithm> #include <limits> +#include <memory> #include <string> -#include "base/memory/scoped_ptr.h" #include "base/trace_event/trace_event_argument.h" #include "cc/base/cc_export.h" @@ -29,7 +29,7 @@ enum WhichTree { LAST_TREE = 1 // Be sure to update WhichTreeAsValue when adding new fields. }; -scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree); +std::unique_ptr<base::Value> WhichTreeAsValue(WhichTree tree); enum TileResolution { LOW_RESOLUTION = 0 , diff --git a/chromium/cc/tiles/tile_task_manager.cc b/chromium/cc/tiles/tile_task_manager.cc new file mode 100644 index 00000000000..9f78d388eb4 --- /dev/null +++ b/chromium/cc/tiles/tile_task_manager.cc @@ -0,0 +1,86 @@ +// Copyright 2016 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/tile_task_manager.h" + +#include "base/memory/ptr_util.h" +#include "base/trace_event/trace_event.h" + +namespace cc { + +TileTaskManager::TileTaskManager() {} + +TileTaskManager::~TileTaskManager() {} + +// static +std::unique_ptr<TileTaskManagerImpl> TileTaskManagerImpl::Create( + std::unique_ptr<RasterBufferProvider> raster_buffer_provider, + TaskGraphRunner* task_graph_runner) { + return base::WrapUnique<TileTaskManagerImpl>(new TileTaskManagerImpl( + std::move(raster_buffer_provider), task_graph_runner)); +} + +TileTaskManagerImpl::TileTaskManagerImpl( + std::unique_ptr<RasterBufferProvider> raster_buffer_provider, + TaskGraphRunner* task_graph_runner) + : raster_buffer_provider_(std::move(raster_buffer_provider)), + task_graph_runner_(task_graph_runner), + namespace_token_(task_graph_runner->GetNamespaceToken()) {} + +TileTaskManagerImpl::~TileTaskManagerImpl() { + DCHECK_EQ(0u, completed_tasks_.size()); +} + +void TileTaskManagerImpl::ScheduleTasks(TaskGraph* graph) { + TRACE_EVENT0("cc", "TileTaskManagerImpl::ScheduleTasks"); + + for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); + it != graph->nodes.end(); ++it) { + TaskGraph::Node& node = *it; + TileTask* task = static_cast<TileTask*>(node.task); + + if (!task->HasBeenScheduled()) { + task->WillSchedule(); + task->ScheduleOnOriginThread(raster_buffer_provider_.get()); + task->DidSchedule(); + } + } + + raster_buffer_provider_->OrderingBarrier(); + + task_graph_runner_->ScheduleTasks(namespace_token_, graph); +} + +void TileTaskManagerImpl::CheckForCompletedTasks() { + TRACE_EVENT0("cc", "TileTaskManagerImpl::CheckForCompletedTasks"); + + task_graph_runner_->CollectCompletedTasks(namespace_token_, + &completed_tasks_); + for (Task::Vector::const_iterator it = completed_tasks_.begin(); + it != completed_tasks_.end(); ++it) { + TileTask* task = static_cast<TileTask*>(it->get()); + + task->WillComplete(); + task->CompleteOnOriginThread(raster_buffer_provider_.get()); + task->DidComplete(); + } + completed_tasks_.clear(); +} + +void TileTaskManagerImpl::Shutdown() { + TRACE_EVENT0("cc", "TileTaskManagerImpl::Shutdown"); + + // Cancel non-scheduled tasks and wait for running tasks to finish. + TaskGraph empty; + task_graph_runner_->ScheduleTasks(namespace_token_, &empty); + task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); + + raster_buffer_provider_->Shutdown(); +} + +RasterBufferProvider* TileTaskManagerImpl::GetRasterBufferProvider() const { + return raster_buffer_provider_.get(); +} + +} // namespace cc diff --git a/chromium/cc/tiles/tile_task_manager.h b/chromium/cc/tiles/tile_task_manager.h new file mode 100644 index 00000000000..e670b415602 --- /dev/null +++ b/chromium/cc/tiles/tile_task_manager.h @@ -0,0 +1,72 @@ +// Copyright 2016 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_TILE_TASK_MANAGER_H_ +#define CC_TILES_TILE_TASK_MANAGER_H_ + +#include <stddef.h> + +#include "cc/raster/raster_buffer_provider.h" +#include "cc/raster/task_graph_runner.h" +#include "cc/raster/tile_task.h" + +namespace cc { +// This interface provides the wrapper over TaskGraphRunner for scheduling and +// collecting tasks. The client can call CheckForCompletedTasks() at any time to +// process all completed tasks at the moment that have finished running or +// cancelled. +class CC_EXPORT TileTaskManager { + public: + TileTaskManager(); + virtual ~TileTaskManager(); + + // Schedule running of tile tasks in |graph| and all dependencies. + // Previously scheduled tasks that are not in |graph| will be canceled unless + // already running. Once scheduled, reply callbacks are guaranteed to run for + // all tasks even if they later get canceled by another call to + // ScheduleTasks(). + virtual void ScheduleTasks(TaskGraph* graph) = 0; + + // Check for completed tasks and dispatch reply callbacks. + virtual void CheckForCompletedTasks() = 0; + + // Shutdown after canceling all previously scheduled tasks. Reply callbacks + // are still guaranteed to run when CheckForCompletedTasks() is called. + virtual void Shutdown() = 0; + + // Get RasterBufferProvider. + virtual RasterBufferProvider* GetRasterBufferProvider() const = 0; +}; + +class CC_EXPORT TileTaskManagerImpl : public TileTaskManager { + public: + ~TileTaskManagerImpl() override; + + static std::unique_ptr<TileTaskManagerImpl> Create( + std::unique_ptr<RasterBufferProvider> raster_buffer_provider, + TaskGraphRunner* task_graph_runner); + + // Overridden from TileTaskManager: + void ScheduleTasks(TaskGraph* graph) override; + void CheckForCompletedTasks() override; + void Shutdown() override; + RasterBufferProvider* GetRasterBufferProvider() const override; + + protected: + TileTaskManagerImpl( + std::unique_ptr<RasterBufferProvider> raster_buffer_provider, + TaskGraphRunner* task_graph_runner); + + std::unique_ptr<RasterBufferProvider> raster_buffer_provider_; + TaskGraphRunner* task_graph_runner_; + const NamespaceToken namespace_token_; + Task::Vector completed_tasks_; + + private: + DISALLOW_COPY_AND_ASSIGN(TileTaskManagerImpl); +}; + +} // namespace cc + +#endif // CC_TILES_TILE_TASK_MANAGER_H_ diff --git a/chromium/cc/trees/blocking_task_runner.cc b/chromium/cc/trees/blocking_task_runner.cc index c276044af34..78ef04e1eec 100644 --- a/chromium/cc/trees/blocking_task_runner.cc +++ b/chromium/cc/trees/blocking_task_runner.cc @@ -10,13 +10,14 @@ #include "base/callback.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" namespace cc { // static -scoped_ptr<BlockingTaskRunner> BlockingTaskRunner::Create( +std::unique_ptr<BlockingTaskRunner> BlockingTaskRunner::Create( scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - return make_scoped_ptr(new BlockingTaskRunner(task_runner)); + return base::WrapUnique(new BlockingTaskRunner(task_runner)); } BlockingTaskRunner::BlockingTaskRunner( diff --git a/chromium/cc/trees/blocking_task_runner.h b/chromium/cc/trees/blocking_task_runner.h index a0101766671..515cb258945 100644 --- a/chromium/cc/trees/blocking_task_runner.h +++ b/chromium/cc/trees/blocking_task_runner.h @@ -5,11 +5,11 @@ #ifndef CC_TREES_BLOCKING_TASK_RUNNER_H_ #define CC_TREES_BLOCKING_TASK_RUNNER_H_ +#include <memory> #include <vector> #include "base/location.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" @@ -48,7 +48,7 @@ class CC_EXPORT BlockingTaskRunner { // |task_runner| will be used to run the tasks which are posted while we are // not capturing. |task_runner| should belong to same the thread on which // capturing is done. - static scoped_ptr<BlockingTaskRunner> Create( + static std::unique_ptr<BlockingTaskRunner> Create( scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~BlockingTaskRunner(); diff --git a/chromium/cc/trees/blocking_task_runner_unittest.cc b/chromium/cc/trees/blocking_task_runner_unittest.cc index f837a7ccd48..03b9fae9c63 100644 --- a/chromium/cc/trees/blocking_task_runner_unittest.cc +++ b/chromium/cc/trees/blocking_task_runner_unittest.cc @@ -8,7 +8,7 @@ #include "base/location.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/test/ordered_simple_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,7 +21,7 @@ void TestTask(bool* result) { TEST(BlockingTaskRunnerTest, NoCapture) { bool did_run = false; - scoped_ptr<BlockingTaskRunner> runner( + std::unique_ptr<BlockingTaskRunner> runner( BlockingTaskRunner::Create(base::ThreadTaskRunnerHandle::Get())); runner->PostTask(FROM_HERE, base::Bind(&TestTask, &did_run)); EXPECT_FALSE(did_run); @@ -31,7 +31,7 @@ TEST(BlockingTaskRunnerTest, NoCapture) { TEST(BlockingTaskRunnerTest, Capture) { bool did_run = false; - scoped_ptr<BlockingTaskRunner> runner( + std::unique_ptr<BlockingTaskRunner> runner( BlockingTaskRunner::Create(base::ThreadTaskRunnerHandle::Get())); { BlockingTaskRunner::CapturePostTasks capture(runner.get()); diff --git a/chromium/cc/trees/channel_impl.h b/chromium/cc/trees/channel_impl.h index d5d3159cc44..c0985b7e03e 100644 --- a/chromium/cc/trees/channel_impl.h +++ b/chromium/cc/trees/channel_impl.h @@ -6,7 +6,6 @@ #define CC_TREES_CHANNEL_IMPL_H_ #include "cc/base/cc_export.h" -#include "cc/debug/frame_timing_tracker.h" #include "cc/output/renderer_capabilities.h" #include "cc/trees/proxy_common.h" @@ -26,18 +25,15 @@ class CC_EXPORT ChannelImpl { const RendererCapabilities& capabilities) = 0; virtual void BeginMainFrameNotExpectedSoon() = 0; virtual void DidCommitAndDrawFrame() = 0; - virtual void SetAnimationEvents(scoped_ptr<AnimationEvents> queue) = 0; + virtual void SetAnimationEvents(std::unique_ptr<AnimationEvents> queue) = 0; virtual void DidLoseOutputSurface() = 0; virtual void RequestNewOutputSurface() = 0; virtual void DidInitializeOutputSurface( bool success, const RendererCapabilities& capabilities) = 0; virtual void DidCompletePageScaleAnimation() = 0; - virtual void PostFrameTimingEventsOnMain( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) = 0; virtual void BeginMainFrame( - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) = 0; + std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) = 0; protected: virtual ~ChannelImpl() {} diff --git a/chromium/cc/trees/channel_main.h b/chromium/cc/trees/channel_main.h index 277507f30df..96fbb544265 100644 --- a/chromium/cc/trees/channel_main.h +++ b/chromium/cc/trees/channel_main.h @@ -56,7 +56,7 @@ class CC_EXPORT ChannelMain { // Must be called before using the channel. virtual void SynchronouslyInitializeImpl( LayerTreeHost* layer_tree_host, - scoped_ptr<BeginFrameSource> external_begin_frame_source) = 0; + std::unique_ptr<BeginFrameSource> external_begin_frame_source) = 0; // Must be called before deleting the channel. virtual void SynchronouslyCloseImpl() = 0; diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc index f534c73e40b..95e545f2a38 100644 --- a/chromium/cc/trees/damage_tracker.cc +++ b/chromium/cc/trees/damage_tracker.cc @@ -8,6 +8,7 @@ #include <algorithm> +#include "base/memory/ptr_util.h" #include "cc/base/math_util.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer_impl.h" @@ -19,8 +20,8 @@ namespace cc { -scoped_ptr<DamageTracker> DamageTracker::Create() { - return make_scoped_ptr(new DamageTracker()); +std::unique_ptr<DamageTracker> DamageTracker::Create() { + return base::WrapUnique(new DamageTracker()); } DamageTracker::DamageTracker() @@ -50,7 +51,7 @@ static inline void ExpandDamageRectInsideRectWithFilters( void DamageTracker::UpdateDamageTrackingState( const LayerImplList& layer_list, - int target_surface_layer_id, + const RenderSurfaceImpl* target_surface, bool target_surface_property_changed_only_from_descendant, const gfx::Rect& target_surface_content_rect, LayerImpl* target_surface_mask_layer, @@ -128,7 +129,7 @@ void DamageTracker::UpdateDamageTrackingState( // the damage will be for this frame, because we need to update the damage // tracker state to correctly track the next frame. gfx::Rect damage_from_active_layers = - TrackDamageFromActiveLayers(layer_list, target_surface_layer_id); + TrackDamageFromActiveLayers(layer_list, target_surface); gfx::Rect damage_from_surface_mask = TrackDamageFromSurfaceMask(target_surface_mask_layer); gfx::Rect damage_from_leftover_rects = TrackDamageFromLeftoverRects(); @@ -152,18 +153,34 @@ void DamageTracker::UpdateDamageTrackingState( current_damage_rect_.Union(damage_rect_for_this_update); } -DamageTracker::RectMapData& DamageTracker::RectDataForLayer( +DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer( int layer_id, bool* layer_is_new) { + LayerRectMapData data(layer_id); - RectMapData data(layer_id); + SortedRectMapForLayers::iterator it = std::lower_bound( + rect_history_for_layers_.begin(), rect_history_for_layers_.end(), data); - SortedRectMap::iterator it = std::lower_bound(rect_history_.begin(), - rect_history_.end(), data); - - if (it == rect_history_.end() || it->layer_id_ != layer_id) { + if (it == rect_history_for_layers_.end() || it->layer_id_ != layer_id) { *layer_is_new = true; - it = rect_history_.insert(it, data); + it = rect_history_for_layers_.insert(it, data); + } + + return *it; +} + +DamageTracker::SurfaceRectMapData& DamageTracker::RectDataForSurface( + int surface_id, + bool* surface_is_new) { + SurfaceRectMapData data(surface_id); + + SortedRectMapForSurfaces::iterator it = + std::lower_bound(rect_history_for_surfaces_.begin(), + rect_history_for_surfaces_.end(), data); + + if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) { + *surface_is_new = true; + it = rect_history_for_surfaces_.insert(it, data); } return *it; @@ -171,7 +188,7 @@ DamageTracker::RectMapData& DamageTracker::RectDataForLayer( gfx::Rect DamageTracker::TrackDamageFromActiveLayers( const LayerImplList& layer_list, - int target_surface_layer_id) { + const RenderSurfaceImpl* target_surface) { gfx::Rect damage_rect; for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { @@ -183,8 +200,8 @@ gfx::Rect DamageTracker::TrackDamageFromActiveLayers( // HUD damage rect visualization. if (layer == layer->layer_tree_impl()->hud_layer()) continue; - if (LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>( - layer, target_surface_layer_id)) + + if (layer->render_surface() && layer->render_surface() != target_surface) ExtendDamageForRenderSurface(layer, &damage_rect); else ExtendDamageForLayer(layer, &damage_rect); @@ -221,8 +238,12 @@ gfx::Rect DamageTracker::TrackDamageFromLeftoverRects() { // So, these regions are now exposed on the target surface. gfx::Rect damage_rect; - SortedRectMap::iterator cur_pos = rect_history_.begin(); - SortedRectMap::iterator copy_pos = cur_pos; + SortedRectMapForLayers::iterator layer_cur_pos = + rect_history_for_layers_.begin(); + SortedRectMapForLayers::iterator layer_copy_pos = layer_cur_pos; + SortedRectMapForSurfaces::iterator surface_cur_pos = + rect_history_for_surfaces_.begin(); + SortedRectMapForSurfaces::iterator surface_copy_pos = surface_cur_pos; // Loop below basically implements std::remove_if loop with and extra // processing (adding deleted rect to damage_rect) for deleted items. @@ -232,25 +253,47 @@ gfx::Rect DamageTracker::TrackDamageFromLeftoverRects() { // moved to the next position. // If there are no deleted elements then copy_pos iterator is in sync with // cur_pos and no copy happens. - while (cur_pos < rect_history_.end()) { - if (cur_pos->mailboxId_ == mailboxId_) { - if (cur_pos != copy_pos) - *copy_pos = *cur_pos; + while (layer_cur_pos < rect_history_for_layers_.end()) { + if (layer_cur_pos->mailboxId_ == mailboxId_) { + if (layer_cur_pos != layer_copy_pos) + *layer_copy_pos = *layer_cur_pos; - ++copy_pos; + ++layer_copy_pos; } else { - damage_rect.Union(cur_pos->rect_); + damage_rect.Union(layer_cur_pos->rect_); } - ++cur_pos; + ++layer_cur_pos; } - if (copy_pos != rect_history_.end()) - rect_history_.erase(copy_pos, rect_history_.end()); + while (surface_cur_pos < rect_history_for_surfaces_.end()) { + if (surface_cur_pos->mailboxId_ == mailboxId_) { + if (surface_cur_pos != surface_copy_pos) + *surface_copy_pos = *surface_cur_pos; + + ++surface_copy_pos; + } else { + damage_rect.Union(surface_cur_pos->rect_); + } + + ++surface_cur_pos; + } + + if (layer_copy_pos != rect_history_for_layers_.end()) + rect_history_for_layers_.erase(layer_copy_pos, + rect_history_for_layers_.end()); + if (surface_copy_pos != rect_history_for_surfaces_.end()) + rect_history_for_surfaces_.erase(surface_copy_pos, + rect_history_for_surfaces_.end()); // If the vector has excessive storage, shrink it - if (rect_history_.capacity() > rect_history_.size() * 4) - SortedRectMap(rect_history_).swap(rect_history_); + if (rect_history_for_layers_.capacity() > rect_history_for_layers_.size() * 4) + SortedRectMapForLayers(rect_history_for_layers_) + .swap(rect_history_for_layers_); + if (rect_history_for_surfaces_.capacity() > + rect_history_for_surfaces_.size() * 4) + SortedRectMapForSurfaces(rect_history_for_surfaces_) + .swap(rect_history_for_surfaces_); return damage_rect; } @@ -276,7 +319,7 @@ void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, // ancestor surface, ExtendDamageForRenderSurface() must be called instead. bool layer_is_new = false; - RectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); + LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); gfx::Rect old_rect_in_target_space = data.rect_; gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); @@ -326,7 +369,7 @@ void DamageTracker::ExtendDamageForRenderSurface( RenderSurfaceImpl* render_surface = layer->render_surface(); bool surface_is_new = false; - RectMapData& data = RectDataForLayer(layer->id(), &surface_is_new); + SurfaceRectMapData& data = RectDataForSurface(layer->id(), &surface_is_new); gfx::Rect old_surface_rect = data.rect_; // The drawableContextRect() already includes the replica if it exists. @@ -334,32 +377,31 @@ void DamageTracker::ExtendDamageForRenderSurface( gfx::ToEnclosingRect(render_surface->DrawableContentRect()); data.Update(surface_rect_in_target_space, mailboxId_); - gfx::Rect damage_rect_in_local_space; if (surface_is_new || render_surface->SurfacePropertyChanged()) { // The entire surface contributes damage. - damage_rect_in_local_space = render_surface->content_rect(); + target_damage_rect->Union(surface_rect_in_target_space); // The surface's old region is now exposed on the target surface, too. target_damage_rect->Union(old_surface_rect); } else { // Only the surface's damage_rect will damage the target surface. - damage_rect_in_local_space = + gfx::Rect damage_rect_in_local_space = render_surface->damage_tracker()->current_damage_rect(); - } - - // If there was damage, transform it to target space, and possibly contribute - // its reflection if needed. - if (!damage_rect_in_local_space.IsEmpty()) { - const gfx::Transform& draw_transform = render_surface->draw_transform(); - gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( - draw_transform, damage_rect_in_local_space); - target_damage_rect->Union(damage_rect_in_target_space); - if (layer->replica_layer()) { - const gfx::Transform& replica_draw_transform = - render_surface->replica_draw_transform(); - target_damage_rect->Union(MathUtil::MapEnclosingClippedRect( - replica_draw_transform, damage_rect_in_local_space)); + // If there was damage, transform it to target space, and possibly + // contribute its reflection if needed. + if (!damage_rect_in_local_space.IsEmpty()) { + const gfx::Transform& draw_transform = render_surface->draw_transform(); + gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( + draw_transform, damage_rect_in_local_space); + target_damage_rect->Union(damage_rect_in_target_space); + + if (layer->replica_layer()) { + const gfx::Transform& replica_draw_transform = + render_surface->replica_draw_transform(); + target_damage_rect->Union(MathUtil::MapEnclosingClippedRect( + replica_draw_transform, damage_rect_in_local_space)); + } } } @@ -369,7 +411,7 @@ void DamageTracker::ExtendDamageForRenderSurface( LayerImpl* replica_mask_layer = layer->replica_layer()->mask_layer(); bool replica_is_new = false; - RectMapData& data = + LayerRectMapData& data = RectDataForLayer(replica_mask_layer->id(), &replica_is_new); const gfx::Transform& replica_draw_transform = diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h index bded662e41d..c03ca329ceb 100644 --- a/chromium/cc/trees/damage_tracker.h +++ b/chromium/cc/trees/damage_tracker.h @@ -5,9 +5,10 @@ #ifndef CC_TREES_DAMAGE_TRACKER_H_ #define CC_TREES_DAMAGE_TRACKER_H_ +#include <memory> #include <vector> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_collections.h" #include "ui/gfx/geometry/rect.h" @@ -29,7 +30,7 @@ class RenderSurfaceImpl; // the screen to save GPU computation and bandwidth. class CC_EXPORT DamageTracker { public: - static scoped_ptr<DamageTracker> Create(); + static std::unique_ptr<DamageTracker> Create(); ~DamageTracker(); void DidDrawDamagedArea() { current_damage_rect_ = gfx::Rect(); } @@ -38,7 +39,7 @@ class CC_EXPORT DamageTracker { } void UpdateDamageTrackingState( const LayerImplList& layer_list, - int target_surface_layer_id, + const RenderSurfaceImpl* target_surface, bool target_surface_property_changed_only_from_descendant, const gfx::Rect& target_surface_content_rect, LayerImpl* target_surface_mask_layer, @@ -49,8 +50,9 @@ class CC_EXPORT DamageTracker { private: DamageTracker(); - gfx::Rect TrackDamageFromActiveLayers(const LayerImplList& layer_list, - int target_surface_layer_id); + gfx::Rect TrackDamageFromActiveLayers( + const LayerImplList& layer_list, + const RenderSurfaceImpl* target_surface); gfx::Rect TrackDamageFromSurfaceMask(LayerImpl* target_surface_mask_layer); gfx::Rect TrackDamageFromLeftoverRects(); @@ -61,15 +63,16 @@ class CC_EXPORT DamageTracker { void ExtendDamageForRenderSurface(LayerImpl* layer, gfx::Rect* target_damage_rect); - struct RectMapData { - RectMapData() : layer_id_(0), mailboxId_(0) {} - explicit RectMapData(int layer_id) : layer_id_(layer_id), mailboxId_(0) {} + struct LayerRectMapData { + LayerRectMapData() : layer_id_(0), mailboxId_(0) {} + explicit LayerRectMapData(int layer_id) + : layer_id_(layer_id), mailboxId_(0) {} void Update(const gfx::Rect& rect, unsigned int mailboxId) { mailboxId_ = mailboxId; rect_ = rect; } - bool operator < (const RectMapData& other) const { + bool operator<(const LayerRectMapData& other) const { return layer_id_ < other.layer_id_; } @@ -77,11 +80,32 @@ class CC_EXPORT DamageTracker { unsigned int mailboxId_; gfx::Rect rect_; }; - typedef std::vector<RectMapData> SortedRectMap; - RectMapData& RectDataForLayer(int layer_id, bool* layer_is_new); + struct SurfaceRectMapData { + SurfaceRectMapData() : surface_id_(0), mailboxId_(0) {} + explicit SurfaceRectMapData(int surface_id) + : surface_id_(surface_id), mailboxId_(0) {} + void Update(const gfx::Rect& rect, unsigned int mailboxId) { + mailboxId_ = mailboxId; + rect_ = rect; + } + + bool operator<(const SurfaceRectMapData& other) const { + return surface_id_ < other.surface_id_; + } + + int surface_id_; + unsigned int mailboxId_; + gfx::Rect rect_; + }; + typedef std::vector<LayerRectMapData> SortedRectMapForLayers; + typedef std::vector<SurfaceRectMapData> SortedRectMapForSurfaces; + + LayerRectMapData& RectDataForLayer(int layer_id, bool* layer_is_new); + SurfaceRectMapData& RectDataForSurface(int layer_id, bool* layer_is_new); - SortedRectMap rect_history_; + SortedRectMapForLayers rect_history_for_layers_; + SortedRectMapForSurfaces rect_history_for_surfaces_; unsigned int mailboxId_; gfx::Rect current_damage_rect_; diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index b776ef83091..769d6f534f4 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -34,21 +34,17 @@ void ExecuteCalculateDrawProperties(LayerImpl* root, ASSERT_FALSE(render_surface_layer_list->size()); FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + root, root->bounds(), render_surface_layer_list); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(root->render_surface()); } -void ClearDamageForAllSurfaces(LayerImpl* layer) { - if (layer->render_surface()) - layer->render_surface()->damage_tracker()->DidDrawDamagedArea(); - - // Recursively clear damage for any existing surface. - for (size_t i = 0; i < layer->children().size(); ++i) - ClearDamageForAllSurfaces(layer->children()[i]); +void ClearDamageForAllSurfaces(LayerImpl* root) { + for (auto* layer : *root->layer_tree_impl()) { + if (layer->render_surface()) + layer->render_surface()->damage_tracker()->DidDrawDamagedArea(); + } } void EmulateDrawingOneFrame(LayerImpl* root) { @@ -69,15 +65,14 @@ void EmulateDrawingOneFrame(LayerImpl* root) { RenderSurfaceImpl* target_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, target_surface->SurfacePropertyChangedOnlyFromDescendant(), target_surface->content_rect(), render_surface_layer_list[index]->mask_layer(), render_surface_layer_list[index]->filters()); } - root->layer_tree_impl()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + root->layer_tree_impl()->ResetAllChangeTracking(); } class DamageTrackerTest : public testing::Test { @@ -89,15 +84,15 @@ class DamageTrackerTest : public testing::Test { LayerImpl* CreateTestTreeWithOneSurface() { host_impl_.active_tree()->ClearLayers(); - scoped_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_.active_tree(), 1); - scoped_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_.active_tree(), 2); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_.active_tree(), 1); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl_.active_tree(), 2); root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(500, 500)); root->SetDrawsContent(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; child->SetPosition(gfx::PointF(100.f, 100.f)); child->SetBounds(gfx::Size(30, 30)); @@ -114,21 +109,21 @@ class DamageTrackerTest : public testing::Test { // two children of its own. host_impl_.active_tree()->ClearLayers(); - scoped_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_.active_tree(), 1); - scoped_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl_.active_tree(), 2); - scoped_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); - scoped_ptr<LayerImpl> grand_child1 = - LayerImpl::Create(host_impl_.active_tree(), 4); - scoped_ptr<LayerImpl> grand_child2 = - LayerImpl::Create(host_impl_.active_tree(), 5); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_.active_tree(), 1); + std::unique_ptr<LayerImpl> child1 = + LayerImpl::Create(host_impl_.active_tree(), 2); + std::unique_ptr<LayerImpl> child2 = + LayerImpl::Create(host_impl_.active_tree(), 3); + std::unique_ptr<LayerImpl> grand_child1 = + LayerImpl::Create(host_impl_.active_tree(), 4); + std::unique_ptr<LayerImpl> grand_child2 = + LayerImpl::Create(host_impl_.active_tree(), 5); root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(500, 500)); root->SetDrawsContent(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; child1->SetPosition(gfx::PointF(100.f, 100.f)); child1->SetBounds(gfx::Size(30, 30)); @@ -136,7 +131,7 @@ class DamageTrackerTest : public testing::Test { // its own RenderSurface. This layer does not draw, but is intended to // create its own RenderSurface. child1->SetDrawsContent(false); - child1->SetForceRenderSurface(true); + child1->test_properties()->force_render_surface = true; child2->SetPosition(gfx::PointF(11.f, 11.f)); child2->SetBounds(gfx::Size(18, 18)); @@ -379,7 +374,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // CASE 1: The layer's property changed flag takes priority over update rect. // - child->SetForceRenderSurface(true); + child->test_properties()->force_render_surface = true; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); @@ -422,20 +417,38 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect); } +TEST_F(DamageTrackerTest, VerifyDamageWhenSurfaceRemoved) { + LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); + LayerImpl* surface = root->children()[0]; + LayerImpl* child = surface->children()[0]; + child->SetDrawsContent(true); + EmulateDrawingOneFrame(root); + ClearDamageForAllSurfaces(root); + + surface->test_properties()->force_render_surface = false; + child->SetDrawsContent(false); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + EmulateDrawingOneFrame(root); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), + root_damage_rect.ToString()); +} + TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { // If a layer is transformed, the damage rect should still enclose the entire // transformed layer. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); LayerImpl* child = root->children()[0]; - child->SetForceRenderSurface(true); + child->test_properties()->force_render_surface = true; gfx::Transform rotation; rotation.Rotate(45.0); ClearDamageForAllSurfaces(root); - child->SetTransformOrigin(gfx::Point3F( - child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f)); + child->test_properties()->transform_origin = gfx::Point3F( + child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f); child->SetPosition(gfx::PointF(85.f, 85.f)); child->NoteLayerPropertyChanged(); root->layer_tree_impl()->property_trees()->needs_rebuild = true; @@ -503,7 +516,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { EXPECT_TRUE(clipped); // Damage the child without moving it. - child->SetForceRenderSurface(true); + child->test_properties()->force_render_surface = true; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); @@ -563,30 +576,31 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { // Allow us to set damage on child too. child->SetDrawsContent(true); - skia::RefPtr<SkImageFilter> filter = skia::AdoptRef( - SkBlurImageFilter::Create(SkIntToScalar(2), SkIntToScalar(2))); FilterOperations filters; - filters.Append(FilterOperation::CreateReferenceFilter(filter)); + filters.Append(FilterOperation::CreateReferenceFilter( + SkBlurImageFilter::Make(2, 2, nullptr))); int outset_top, outset_right, outset_bottom, outset_left; filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left); // Setting the filter will damage the whole surface. ClearDamageForAllSurfaces(root); - child->SetForceRenderSurface(true); - child->SetFilters(filters); + child->test_properties()->force_render_surface = true; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); + child->OnFilterAnimated(filters); + EmulateDrawingOneFrame(root); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); child_damage_rect = child->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), - root_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(100 - outset_left, 100 - outset_top, + 30 + outset_left + outset_right, + 30 + outset_top + outset_bottom), + root_damage_rect); EXPECT_EQ( gfx::Rect(-outset_left, -outset_top, 30 + (outset_left + outset_right), - 30 + (outset_top + outset_bottom)) - .ToString(), - child_damage_rect.ToString()); + 30 + (outset_top + outset_bottom)), + child_damage_rect); // CASE 1: Setting the update rect should damage the whole surface (for now) ClearDamageForAllSurfaces(root); @@ -602,12 +616,70 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { int expect_width = 1 + outset_left + outset_right; int expect_height = 1 + outset_top + outset_bottom; EXPECT_EQ(gfx::Rect(100 - outset_left, 100 - outset_top, expect_width, - expect_height) - .ToString(), - root_damage_rect.ToString()); - EXPECT_EQ(gfx::Rect(-outset_left, -outset_top, expect_width, expect_height) - .ToString(), - child_damage_rect.ToString()); + expect_height), + root_damage_rect); + EXPECT_EQ(gfx::Rect(-outset_left, -outset_top, expect_width, expect_height), + child_damage_rect); +} + +TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { + LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); + LayerImpl* child = root->children()[0]; + gfx::Rect root_damage_rect, child_damage_rect; + + // Allow us to set damage on child too. + child->SetDrawsContent(true); + + FilterOperations filters; + filters.Append(FilterOperation::CreateReferenceFilter( + SkBlurImageFilter::Make(2, 2, nullptr))); + int outset_top, outset_right, outset_bottom, outset_left; + filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left); + + // Setting the filter will damage the whole surface. + gfx::Transform transform; + transform.RotateAboutYAxis(60); + ClearDamageForAllSurfaces(root); + child->test_properties()->force_render_surface = true; + child->SetTransform(transform); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + EmulateDrawingOneFrame(root); + child->OnFilterAnimated(filters); + EmulateDrawingOneFrame(root); + root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + child_damage_rect = + child->render_surface()->damage_tracker()->current_damage_rect(); + int rotated_outset_left = outset_left / 2; + int expected_rotated_width = (30 + outset_left + outset_right) / 2; + gfx::Rect expected_root_damage(100 - rotated_outset_left, 100 - outset_top, + expected_rotated_width, + 30 + outset_top + outset_bottom); + expected_root_damage.Union(gfx::Rect(100, 100, 30, 30)); + EXPECT_EQ(expected_root_damage, root_damage_rect); + EXPECT_EQ( + gfx::Rect(-outset_left, -outset_top, 30 + (outset_left + outset_right), + 30 + (outset_top + outset_bottom)), + child_damage_rect); + + // Setting the update rect should damage the whole surface (for now) + ClearDamageForAllSurfaces(root); + child->SetUpdateRect(gfx::Rect(30, 30)); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + EmulateDrawingOneFrame(root); + + root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + child_damage_rect = + child->render_surface()->damage_tracker()->current_damage_rect(); + + int expect_width = 30 + outset_left + outset_right; + int expect_height = 30 + outset_top + outset_bottom; + EXPECT_EQ(gfx::Rect(100 - outset_left / 2, 100 - outset_top, expect_width / 2, + expect_height), + root_damage_rect); + EXPECT_EQ(gfx::Rect(-outset_left, -outset_top, expect_width, expect_height), + child_damage_rect); } TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { @@ -752,8 +824,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { // ClearDamageForAllSurfaces(root); { - scoped_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); + std::unique_ptr<LayerImpl> child2 = + LayerImpl::Create(host_impl_.active_tree(), 3); child2->SetPosition(gfx::PointF(400.f, 380.f)); child2->SetBounds(gfx::Size(6, 8)); child2->SetDrawsContent(true); @@ -803,14 +875,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { ClearDamageForAllSurfaces(root); { - scoped_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); + std::unique_ptr<LayerImpl> child2 = + LayerImpl::Create(host_impl_.active_tree(), 3); child2->SetPosition(gfx::PointF(400.f, 380.f)); child2->SetBounds(gfx::Size(6, 8)); child2->SetDrawsContent(true); root->AddChild(std::move(child2)); - host_impl_.active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + host_impl_.active_tree()->ResetAllChangeTracking(); LayerImpl* child2_ptr = host_impl_.active_tree()->LayerById(3); // Sanity check the initial conditions of the test, if these asserts // trigger, it means the test no longer actually covers the intended @@ -838,8 +909,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { // part of the same frame. ClearDamageForAllSurfaces(root); { - scoped_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); + std::unique_ptr<LayerImpl> child2 = + LayerImpl::Create(host_impl_.active_tree(), 3); child2->SetPosition(gfx::PointF(400.f, 380.f)); child2->SetBounds(gfx::Size(6, 8)); child2->SetDrawsContent(true); @@ -868,8 +939,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { LayerImpl* child1 = root->children()[0]; LayerImpl* child2 = root->children()[1]; LayerImpl* grand_child1 = root->children()[0]->children()[0]; - child2->SetForceRenderSurface(true); - grand_child1->SetForceRenderSurface(true); + child2->test_properties()->force_render_surface = true; + grand_child1->test_properties()->force_render_surface = true; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; @@ -993,7 +1064,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // CASE 1: If a descendant surface disappears, its entire old area becomes // exposed. ClearDamageForAllSurfaces(root); - child1->SetForceRenderSurface(false); + child1->test_properties()->force_render_surface = false; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); @@ -1020,7 +1091,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // Then change the tree so that the render surface is added back. ClearDamageForAllSurfaces(root); - child1->SetForceRenderSurface(true); + child1->test_properties()->force_render_surface = true; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); @@ -1106,8 +1177,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { // without changing content_bounds of the surface. grand_child2->SetPosition(gfx::PointF(180.f, 180.f)); { - scoped_ptr<LayerImpl> grand_child3 = - LayerImpl::Create(host_impl_.active_tree(), 6); + std::unique_ptr<LayerImpl> grand_child3 = + 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->SetDrawsContent(true); @@ -1121,14 +1192,15 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { // ClearDamageForAllSurfaces(root); { - scoped_ptr<LayerImpl> grand_child1_replica = - LayerImpl::Create(host_impl_.active_tree(), 7); + std::unique_ptr<LayerImpl> grand_child1_replica = + LayerImpl::Create(host_impl_.active_tree(), 7); grand_child1_replica->SetPosition(gfx::PointF()); gfx::Transform reflection; reflection.Scale3d(-1.0, 1.0, 1.0); grand_child1_replica->SetTransform(reflection); grand_child1->SetReplicaLayer(std::move(grand_child1_replica)); - grand_child1->SetForceRenderSurface(true); + grand_child1->test_properties()->force_render_surface = true; + grand_child1->NoteLayerPropertyChanged(); } root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); @@ -1182,7 +1254,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { // reflection to damage the target surface. ClearDamageForAllSurfaces(root); grand_child1->SetReplicaLayer(nullptr); - grand_child1->SetForceRenderSurface(false); + grand_child1->test_properties()->force_render_surface = false; + grand_child1->NoteLayerPropertyChanged(); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); ASSERT_EQ(old_content_rect.width(), @@ -1212,20 +1285,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Set up the mask layer. { - scoped_ptr<LayerImpl> mask_layer = - LayerImpl::Create(host_impl_.active_tree(), 3); + std::unique_ptr<LayerImpl> mask_layer = + LayerImpl::Create(host_impl_.active_tree(), 3); mask_layer->SetPosition(child->position()); mask_layer->SetBounds(child->bounds()); child->SetMaskLayer(std::move(mask_layer)); - child->SetForceRenderSurface(true); + child->test_properties()->force_render_surface = true; } LayerImpl* mask_layer = child->mask_layer(); // Add opacity and a grand_child so that the render surface persists even // after we remove the mask. { - scoped_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl_.active_tree(), 4); + std::unique_ptr<LayerImpl> grand_child = + 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->SetDrawsContent(true); @@ -1306,21 +1379,21 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) { // Create a reflection about the left edge of grand_child1. { - scoped_ptr<LayerImpl> grand_child1_replica = - LayerImpl::Create(host_impl_.active_tree(), 6); + std::unique_ptr<LayerImpl> grand_child1_replica = + LayerImpl::Create(host_impl_.active_tree(), 6); grand_child1_replica->SetPosition(gfx::PointF()); gfx::Transform reflection; reflection.Scale3d(-1.0, 1.0, 1.0); grand_child1_replica->SetTransform(reflection); grand_child1->SetReplicaLayer(std::move(grand_child1_replica)); - grand_child1->SetForceRenderSurface(true); + grand_child1->test_properties()->force_render_surface = true; } LayerImpl* grand_child1_replica = grand_child1->replica_layer(); // Set up the mask layer on the replica layer { - scoped_ptr<LayerImpl> replica_mask_layer = - LayerImpl::Create(host_impl_.active_tree(), 7); + std::unique_ptr<LayerImpl> replica_mask_layer = + LayerImpl::Create(host_impl_.active_tree(), 7); replica_mask_layer->SetPosition(gfx::PointF()); replica_mask_layer->SetBounds(grand_child1->bounds()); grand_child1_replica->SetMaskLayer(std::move(replica_mask_layer)); @@ -1378,31 +1451,31 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithTransformOrigin) { // This is not actually the transform origin point being tested, but by // convention its // expected to be the same as the replica's anchor point. - grand_child1->SetTransformOrigin( - gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f)); + grand_child1->test_properties()->transform_origin = + gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f); { - scoped_ptr<LayerImpl> grand_child1_replica = - LayerImpl::Create(host_impl_.active_tree(), 6); + std::unique_ptr<LayerImpl> grand_child1_replica = + LayerImpl::Create(host_impl_.active_tree(), 6); grand_child1_replica->SetPosition(gfx::PointF()); // This is the anchor being tested. - grand_child1_replica->SetTransformOrigin( - gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f)); + grand_child1_replica->test_properties()->transform_origin = + gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f); gfx::Transform reflection; reflection.Scale3d(-1.0, 1.0, 1.0); grand_child1_replica->SetTransform(reflection); // We need to set parent on replica layer for property tree building. grand_child1_replica->SetParent(grand_child1); grand_child1->SetReplicaLayer(std::move(grand_child1_replica)); - grand_child1->SetForceRenderSurface(true); + grand_child1->test_properties()->force_render_surface = true; } LayerImpl* grand_child1_replica = grand_child1->replica_layer(); // Set up the mask layer on the replica layer { - scoped_ptr<LayerImpl> replica_mask_layer = - LayerImpl::Create(host_impl_.active_tree(), 7); + std::unique_ptr<LayerImpl> replica_mask_layer = + LayerImpl::Create(host_impl_.active_tree(), 7); replica_mask_layer->SetPosition(gfx::PointF()); // Note: this is not the transform origin being tested. replica_mask_layer->SetBounds(grand_child1->bounds()); @@ -1465,25 +1538,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { // Though it should never happen, its a good idea to verify that the damage // tracker does not crash when it receives an empty layer_list. - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 1); - root->SetForceRenderSurface(true); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_.active_tree(), 1); + root->test_properties()->force_render_surface = true; host_impl_.active_tree()->SetRootLayer(std::move(root)); LayerImpl* root_ptr = host_impl_.active_tree()->root_layer(); root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root_ptr); - root_ptr->draw_properties().render_target = root_ptr; - ASSERT_EQ(root_ptr, root_ptr->render_target()); + DCHECK_EQ(root_ptr->render_surface(), root_ptr->render_target()); RenderSurfaceImpl* target_surface = root_ptr->render_surface(); LayerImplList empty_list; target_surface->damage_tracker()->UpdateDamageTrackingState( - empty_list, - target_surface->OwningLayerId(), - false, - gfx::Rect(), - NULL, - FilterOperations()); + empty_list, target_surface, false, gfx::Rect(), NULL, FilterOperations()); gfx::Rect damage_rect = target_surface->damage_tracker()->current_damage_rect(); diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index 6a8c35986eb..74981b8265b 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -33,13 +33,6 @@ static bool IsRootLayer(const LayerImpl* layer) { } #if DCHECK_IS_ON() -static Layer* EffectNodeOwner(Layer* layer) { - EffectNode* node = - layer->layer_tree_host()->property_trees()->effect_tree.Node( - layer->effect_tree_index()); - return layer->layer_tree_host()->LayerById(node->owner_id); -} - static LayerImpl* EffectNodeOwner(LayerImpl* layer) { EffectNode* node = layer->layer_tree_impl()->property_trees()->effect_tree.Node( @@ -47,8 +40,7 @@ static LayerImpl* EffectNodeOwner(LayerImpl* layer) { return layer->layer_tree_impl()->LayerById(node->owner_id); } -template <typename LayerType> -static void ValidateRenderSurfaceForLayer(LayerType* layer) { +static void ValidateRenderSurfaceForLayer(LayerImpl* layer) { // This test verifies that there are no cases where a LayerImpl needs // a render surface, but doesn't have one. if (layer->has_render_surface()) @@ -61,15 +53,9 @@ static void ValidateRenderSurfaceForLayer(LayerType* layer) { return; DCHECK(!layer->mask_layer()) << "layer: " << layer->id(); DCHECK(!layer->replica_layer()) << "layer: " << layer->id(); - DCHECK(!layer->is_root_for_isolated_group()) << "layer: " << layer->id(); DCHECK(!layer->HasCopyRequest()) << "layer: " << layer->id(); } -static void ValidateRenderSurfacesRecursive(Layer* layer) { - ValidateRenderSurfaceForLayer(layer); - for (size_t i = 0; i < layer->children().size(); ++i) - ValidateRenderSurfacesRecursive(layer->child_at(i)); -} #endif template <typename LayerType> @@ -161,7 +147,6 @@ void CalculateVisibleRects( clip_to_target, clip_node->data.clip_in_target_space)); } clip_rect_in_target_space = combined_clip_rect_in_target_space; - } else { clip_rect_in_target_space = gfx::ToEnclosingRect(clip_node->data.clip_in_target_space); @@ -267,34 +252,6 @@ static bool IsLayerBackFaceVisible(LayerType* layer, : node->data.to_target.IsBackFaceVisible(); } -template <typename LayerType> -static bool IsSurfaceBackFaceVisible(LayerType* layer, - const TransformTree& tree) { - if (HasSingularTransform(layer->transform_tree_index(), tree)) - return false; - const TransformNode* node = tree.Node(layer->transform_tree_index()); - // If the render_surface is not part of a new or existing rendering context, - // then the layers that contribute to this surface will decide back-face - // visibility for themselves. - if (!node->data.sorting_context_id) - return false; - - const TransformNode* parent_node = tree.parent(node); - if (parent_node && - parent_node->data.sorting_context_id == node->data.sorting_context_id) { - // Draw transform as a contributing render surface. - // TODO(enne): we shouldn't walk the tree during a tree walk. - gfx::Transform surface_draw_transform; - tree.ComputeTransform(node->id, node->data.target_id, - &surface_draw_transform); - return surface_draw_transform.IsBackFaceVisible(); - } - - // We use layer's transform to determine back face visibility when its the - // root of a new rendering context. - return layer->transform().IsBackFaceVisible(); -} - static inline bool TransformToScreenIsKnown(Layer* layer, int transform_tree_index, const TransformTree& tree) { @@ -309,12 +266,6 @@ static inline bool TransformToScreenIsKnown(LayerImpl* layer, } template <typename LayerType> -static bool HasInvertibleOrAnimatedTransform(LayerType* layer) { - return layer->transform_is_invertible() || - layer->HasPotentiallyRunningTransformAnimation(); -} - -template <typename LayerType> static bool LayerNeedsUpdateInternal(LayerType* layer, bool layer_is_drawn, const TransformTree& tree) { @@ -384,14 +335,14 @@ void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, } } -template <typename LayerType> void UpdateRenderSurfaceForLayer(EffectTree* effect_tree, bool non_root_surfaces_enabled, - LayerType* layer) { + LayerImpl* layer) { if (!non_root_surfaces_enabled) { layer->SetHasRenderSurface(IsRootLayer(layer)); return; } + EffectNode* node = effect_tree->Node(layer->effect_tree_index()); if (node->owner_id == layer->id() && node->data.has_render_surface) @@ -399,140 +350,73 @@ void UpdateRenderSurfaceForLayer(EffectTree* effect_tree, else layer->SetHasRenderSurface(false); } - -void UpdateRenderSurfacesForLayersRecursive(EffectTree* effect_tree, - Layer* layer) { - UpdateRenderSurfaceForLayer(effect_tree, true, layer); - - for (size_t i = 0; i < layer->children().size(); ++i) { - UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i)); - } -} - } // namespace -static inline bool LayerShouldBeSkipped(Layer* layer, - bool layer_is_drawn, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { +template <typename LayerType> +static inline bool LayerShouldBeSkippedInternal( + LayerType* layer, + bool layer_is_drawn, + const TransformTree& transform_tree, + const EffectTree& effect_tree) { const TransformNode* transform_node = transform_tree.Node(layer->transform_tree_index()); const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); - // If the layer transform is not invertible, it should not be drawn. - bool has_inherited_invertible_or_animated_transform = - (transform_node->data.is_invertible && - transform_node->data.ancestors_are_invertible) || - transform_node->data.to_screen_is_potentially_animated; - if (!has_inherited_invertible_or_animated_transform) - return true; - - // When we need to do a readback/copy of a layer's output, we can not skip - // it or any of its ancestors. - if (effect_node->data.num_copy_requests_in_subtree > 0) - return false; - - // If the layer is not drawn, then skip it and its subtree. - if (!effect_node->data.is_drawn) - return true; - - if (!transform_node->data.to_screen_is_potentially_animated && - effect_node->data.hidden_by_backface_visibility) - return true; - - // If layer has a background filter, don't skip the layer, even it the - // opacity is 0. - if (effect_node->data.node_or_ancestor_has_background_filters) + if (effect_node->data.has_render_surface && + effect_node->data.num_copy_requests_in_subtree > 0) return false; - - // If the opacity is being animated then the opacity on the main thread is - // unreliable (since the impl thread may be using a different opacity), so it - // should not be trusted. - // In particular, it should not cause the subtree to be skipped. - // Similarly, for layers that might animate opacity using an impl-only - // animation, their subtree should also not be skipped. - return !effect_node->data.screen_space_opacity && - !effect_node->data.to_screen_opacity_is_animated; + // If the layer transform is not invertible, it should be skipped. + // TODO(ajuma): Correctly process subtrees with singular transform for the + // case where we may animate to a non-singular transform and wish to + // pre-raster. + return !transform_node->data.node_and_ancestors_are_animated_or_invertible || + effect_node->data.hidden_by_backface_visibility || + !effect_node->data.is_drawn; } bool LayerShouldBeSkipped(LayerImpl* layer, bool layer_is_drawn, const TransformTree& transform_tree, const EffectTree& effect_tree) { - const TransformNode* transform_node = - transform_tree.Node(layer->transform_tree_index()); - const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); - // If the layer transform is not invertible, it should not be drawn. - // TODO(ajuma): Correctly process subtrees with singular transform for the - // case where we may animate to a non-singular transform and wish to - // pre-raster. - bool has_inherited_invertible_or_animated_transform = - (transform_node->data.is_invertible && - transform_node->data.ancestors_are_invertible) || - transform_node->data.to_screen_is_potentially_animated; - if (!has_inherited_invertible_or_animated_transform) - return true; - - // When we need to do a readback/copy of a layer's output, we can not skip - // it or any of its ancestors. - if (effect_node->data.num_copy_requests_in_subtree > 0) - return false; - - // If the layer is not drawn, then skip it and its subtree. - if (!effect_node->data.is_drawn) - return true; - - if (effect_node->data.hidden_by_backface_visibility) - return true; - - // If layer is on the pending tree and opacity is being animated then - // this subtree can't be skipped as we need to create, prioritize and - // include tiles for this layer when deciding if tree can be activated. - if (!transform_tree.property_trees()->is_active && - effect_node->data.to_screen_opacity_is_animated) - return false; - - // If layer has a background filter, don't skip the layer, even it the - // opacity is 0. - if (effect_node->data.node_or_ancestor_has_background_filters) - return false; + return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, + effect_tree); +} - // The opacity of a layer always applies to its children (either implicitly - // via a render surface or explicitly if the parent preserves 3D), so the - // entire subtree can be skipped if this layer is fully transparent. - return !effect_node->data.screen_space_opacity; +bool LayerShouldBeSkipped(Layer* layer, + bool layer_is_drawn, + const TransformTree& transform_tree, + const EffectTree& effect_tree) { + return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, + effect_tree); } void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, const TransformTree& transform_tree, const EffectTree& effect_tree, LayerList* update_layer_list) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - layer_tree_host, - [&](Layer* layer) { - bool layer_is_drawn = - effect_tree.Node(layer->effect_tree_index())->data.is_drawn; - - if (!IsRootLayer(layer) && - LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree, - effect_tree)) - return; - - if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree)) { - update_layer_list->push_back(layer); - } + for (auto* layer : *layer_tree_host) { + bool layer_is_drawn = + effect_tree.Node(layer->effect_tree_index())->data.is_drawn; - // Append mask layers to the update layer list. They don't have valid - // visible rects, so need to get added after the above calculation. - // Replica layers don't need to be updated. - if (Layer* mask_layer = layer->mask_layer()) - update_layer_list->push_back(mask_layer); - if (Layer* replica_layer = layer->replica_layer()) { - if (Layer* mask_layer = replica_layer->mask_layer()) - update_layer_list->push_back(mask_layer); - } - }, - CallFunctionLayerType::BASIC_LAYER); + if (!IsRootLayer(layer) && + LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree, + effect_tree)) + continue; + + if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree)) { + update_layer_list->push_back(layer); + } + + // Append mask layers to the update layer list. They don't have valid + // visible rects, so need to get added after the above calculation. + // Replica layers don't need to be updated. + if (Layer* mask_layer = layer->mask_layer()) + update_layer_list->push_back(mask_layer); + if (Layer* replica_layer = layer->replica_layer()) { + if (Layer* mask_layer = replica_layer->mask_layer()) + update_layer_list->push_back(mask_layer); + } + } } static void ResetIfHasNanCoordinate(gfx::RectF* rect) { @@ -688,6 +572,23 @@ void ComputeTransforms(TransformTree* transform_tree) { transform_tree->set_needs_update(false); } +void UpdateRenderTarget(EffectTree* effect_tree, + bool can_render_to_separate_surface) { + for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) { + EffectNode* node = effect_tree->Node(i); + if (i == 1) { + // Render target on the first effect node is root. + node->data.target_id = 0; + } else if (!can_render_to_separate_surface) { + node->data.target_id = 1; + } else if (effect_tree->parent(node)->data.has_render_surface) { + node->data.target_id = node->parent_id; + } else { + node->data.target_id = effect_tree->parent(node)->data.target_id; + } + } +} + void ComputeEffects(EffectTree* effect_tree) { if (!effect_tree->needs_update()) return; @@ -696,6 +597,162 @@ void ComputeEffects(EffectTree* effect_tree) { effect_tree->set_needs_update(false); } +static gfx::RectF ComputeCurrentClip(const ClipNode* clip_node, + const TransformTree& transform_tree, + int target_transform_id) { + if (clip_node->data.transform_id != target_transform_id) { + gfx::Transform current_to_target; + if (!transform_tree.ComputeTransformWithDestinationSublayerScale( + clip_node->data.transform_id, target_transform_id, + ¤t_to_target)) + return gfx::RectF(); + if (clip_node->data.transform_id > target_transform_id) + return MathUtil::MapClippedRect(current_to_target, clip_node->data.clip); + else + return MathUtil::ProjectClippedRect(current_to_target, + clip_node->data.clip); + } else { + gfx::RectF current_clip = clip_node->data.clip; + gfx::Vector2dF sublayer_scale = + transform_tree.Node(target_transform_id)->data.sublayer_scale; + if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) { + current_clip.Scale(sublayer_scale.x(), sublayer_scale.y()); + } + return current_clip; + } +} + +static gfx::RectF ComputeAccumulatedClip(const ClipTree& clip_tree, + int local_clip_id, + const EffectTree& effect_tree, + int target_id, + const TransformTree& transform_tree) { + const ClipNode* clip_node = clip_tree.Node(local_clip_id); + const EffectNode* target_node = effect_tree.Node(target_id); + int target_transform_id = target_node->data.transform_id; + + // Collect all the clips that need to be accumulated. + std::stack<const ClipNode*> parent_chain; + + // If target is not direct ancestor of clip, this will find least common + // ancestor between the target and the clip. + while (target_node->id >= 0 && clip_node->id >= 0) { + while (target_node->data.clip_id > clip_node->id || + target_node->data.has_unclipped_descendants) { + target_node = effect_tree.Node(target_node->data.target_id); + } + if (target_node->data.clip_id == clip_node->id) + break; + while (target_node->data.clip_id < clip_node->id) { + parent_chain.push(clip_node); + clip_node = clip_tree.parent(clip_node); + } + if (target_node->data.clip_id == clip_node->id) { + clip_node = parent_chain.top(); + parent_chain.pop(); + break; + } + } + + // TODO(weiliangc): If we don't create clip for render surface, we don't need + // to check applies_local_clip. + while (!clip_node->data.applies_local_clip && parent_chain.size() > 0) { + clip_node = parent_chain.top(); + parent_chain.pop(); + } + + if (!clip_node->data.applies_local_clip) + return gfx::RectF(); + + gfx::RectF accumulated_clip = + ComputeCurrentClip(clip_node, transform_tree, target_transform_id); + + while (parent_chain.size() > 0) { + clip_node = parent_chain.top(); + parent_chain.pop(); + if (!clip_node->data.applies_local_clip) { + continue; + } + gfx::RectF current_clip = + ComputeCurrentClip(clip_node, transform_tree, target_transform_id); + + if (current_clip.IsEmpty()) + return gfx::RectF(); + + accumulated_clip = gfx::IntersectRects(accumulated_clip, current_clip); + } + + return accumulated_clip.IsEmpty() ? gfx::RectF() : accumulated_clip; +} + +static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) { + EffectTree* effect_tree = &property_trees->effect_tree; + const ClipTree* clip_tree = &property_trees->clip_tree; + const TransformTree* transform_tree = &property_trees->transform_tree; + EffectNode* root_effect_node = effect_tree->Node(1); + const RenderSurfaceImpl* root_render_surface = + root_effect_node->data.render_surface; + gfx::Rect root_clip = gfx::ToEnclosingRect( + clip_tree->Node(root_effect_node->data.clip_id)->data.clip); + if (root_render_surface->is_clipped()) + DCHECK(root_clip == root_render_surface->clip_rect()) + << "clip on root render surface: " + << root_render_surface->clip_rect().ToString() + << " v.s. root effect node's clip: " << root_clip.ToString(); + for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) { + EffectNode* effect_node = effect_tree->Node(i); + const EffectNode* target_node = + effect_tree->Node(effect_node->data.target_id); + gfx::RectF accumulated_clip = + ComputeAccumulatedClip(*clip_tree, effect_node->data.clip_id, + *effect_tree, target_node->id, *transform_tree); + const RenderSurfaceImpl* render_surface = effect_node->data.render_surface; + if (render_surface && render_surface->is_clipped()) { + DCHECK(gfx::ToEnclosingRect(accumulated_clip) == + render_surface->clip_rect()) + << " render surface's clip rect: " + << render_surface->clip_rect().ToString() + << " v.s. accumulated clip: " + << gfx::ToEnclosingRect(accumulated_clip).ToString(); + } + } +} + +static void ComputeLayerClipRect(const PropertyTrees* property_trees, + const LayerImpl* layer) { + const EffectTree* effect_tree = &property_trees->effect_tree; + const ClipTree* clip_tree = &property_trees->clip_tree; + const TransformTree* transform_tree = &property_trees->transform_tree; + const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); + const EffectNode* target_node = + effect_node->data.has_render_surface + ? effect_node + : effect_tree->Node(effect_node->data.target_id); + // TODO(weiliangc): When effect node has up to date render surface info on + // compositor thread, no need to check for resourceless draw mode + if (!property_trees->non_root_surfaces_enabled) { + target_node = effect_tree->Node(1); + } + + gfx::RectF accumulated_clip = + ComputeAccumulatedClip(*clip_tree, layer->clip_tree_index(), *effect_tree, + target_node->id, *transform_tree); + + if ((!property_trees->non_root_surfaces_enabled && + clip_tree->Node(layer->clip_tree_index()) + ->data.layers_are_clipped_when_surfaces_disabled) || + clip_tree->Node(layer->clip_tree_index())->data.layers_are_clipped) { + DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip)) + << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() + << " layer clip: " << layer->clip_rect().ToString() << " v.s. " + << gfx::ToEnclosingRect(accumulated_clip).ToString() + << " and clip node clip: " + << gfx::ToEnclosingRect(clip_tree->Node(layer->clip_tree_index()) + ->data.clip_in_target_space) + .ToString(); + } +} + static void ComputeVisibleRectsInternal( LayerImpl* root_layer, PropertyTrees* property_trees, @@ -711,6 +768,8 @@ static void ComputeVisibleRectsInternal( property_trees->clip_tree.set_needs_update(true); property_trees->effect_tree.set_needs_update(true); } + UpdateRenderTarget(&property_trees->effect_tree, + property_trees->non_root_surfaces_enabled); ComputeTransforms(&property_trees->transform_tree); ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, can_render_to_separate_surface); @@ -724,14 +783,6 @@ static void ComputeVisibleRectsInternal( property_trees->transform_tree, can_render_to_separate_surface); } -void UpdateRenderSurfaces(Layer* root_layer, PropertyTrees* property_trees) { - UpdateRenderSurfacesForLayersRecursive(&property_trees->effect_tree, - root_layer); -#if DCHECK_IS_ON() - ValidateRenderSurfacesRecursive(root_layer); -#endif -} - void UpdatePropertyTrees(PropertyTrees* property_trees, bool can_render_to_separate_surface) { if (property_trees->non_root_surfaces_enabled != @@ -780,6 +831,15 @@ void BuildPropertyTreesAndComputeVisibleRects( can_render_to_separate_surface, visible_layer_list); } +void VerifyClipTreeCalculations(const LayerImplList& layer_list, + PropertyTrees* property_trees) { + if (property_trees->non_root_surfaces_enabled) { + ComputeClipsWithEffectTree(property_trees); + } + for (auto layer : layer_list) + ComputeLayerClipRect(property_trees, layer); +} + void ComputeVisibleRects(LayerImpl* root_layer, PropertyTrees* property_trees, bool can_render_to_separate_surface, @@ -787,6 +847,10 @@ void ComputeVisibleRects(LayerImpl* root_layer, for (auto* layer : *root_layer->layer_tree_impl()) { UpdateRenderSurfaceForLayer(&property_trees->effect_tree, can_render_to_separate_surface, layer); + EffectNode* node = + property_trees->effect_tree.Node(layer->effect_tree_index()); + if (node->owner_id == layer->id()) + node->data.render_surface = layer->render_surface(); #if DCHECK_IS_ON() if (can_render_to_separate_surface) ValidateRenderSurfaceForLayer(layer); @@ -853,12 +917,10 @@ static void SetSurfaceDrawTransform(const TransformTree& tree, static void SetSurfaceIsClipped(const ClipNode* clip_node, RenderSurfaceImpl* render_surface) { - // If the render surface's owning layer doesn't form a clip node, it is not - // clipped. - if (render_surface->OwningLayerId() != clip_node->owner_id) - render_surface->SetIsClipped(false); - else - render_surface->SetIsClipped(clip_node->data.target_is_clipped); + DCHECK(render_surface->OwningLayerId() == clip_node->owner_id) + << "we now create clip node for every render surface"; + + render_surface->SetIsClipped(clip_node->data.target_is_clipped); } static void SetSurfaceClipRect(const ClipNode* parent_clip_node, @@ -926,14 +988,14 @@ static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { return 0.f; const EffectNode* target_node = - tree.Node(layer->render_target()->effect_tree_index()); + tree.Node(layer->render_target()->EffectTreeIndex()); const EffectNode* node = tree.Node(layer->effect_tree_index()); if (node == target_node) return 1.f; float draw_opacity = 1.f; while (node != target_node) { - draw_opacity *= node->data.opacity; + draw_opacity *= tree.EffectiveOpacity(node); node = tree.parent(node); } return draw_opacity; @@ -944,10 +1006,10 @@ static void SetSurfaceDrawOpacity(const EffectTree& tree, // Draw opacity of a surface is the product of opacities between the surface // (included) and its target surface (excluded). const EffectNode* node = tree.Node(render_surface->EffectTreeIndex()); - float draw_opacity = node->data.opacity; + float draw_opacity = tree.EffectiveOpacity(node); for (node = tree.parent(node); node && !node->data.has_render_surface; node = tree.parent(node)) { - draw_opacity *= node->data.opacity; + draw_opacity *= tree.EffectiveOpacity(node); } render_surface->SetDrawOpacity(draw_opacity); } @@ -1095,6 +1157,16 @@ void ComputeSurfaceDrawProperties(const PropertyTrees* property_trees, property_trees->transform_tree, render_surface); } +#if DCHECK_IS_ON() +static void ValidatePageScaleLayer(const Layer* page_scale_layer) { + DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString()); + DCHECK_EQ(page_scale_layer->transform_origin().ToString(), + gfx::Point3F().ToString()); +} + +static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {} +#endif + template <typename LayerType> static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees, const LayerType* page_scale_layer, @@ -1111,9 +1183,9 @@ static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees, page_scale_layer->transform_tree_index()); // 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()); +#if DCHECK_IS_ON() + ValidatePageScaleLayer(page_scale_layer); +#endif if (IsRootLayer(page_scale_layer)) { // When the page scale layer is also the root layer, the node should also diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h index fcd31bf2a1a..c660686127f 100644 --- a/chromium/cc/trees/draw_property_utils.h +++ b/chromium/cc/trees/draw_property_utils.h @@ -56,9 +56,6 @@ void CC_EXPORT BuildPropertyTreesAndComputeVisibleRects( PropertyTrees* property_trees, LayerImplList* visible_layer_list); -void CC_EXPORT UpdateRenderSurfaces(Layer* root_layer, - PropertyTrees* property_trees); - void CC_EXPORT UpdatePropertyTrees(PropertyTrees* property_trees, bool can_render_to_separate_surface); @@ -98,6 +95,9 @@ bool CC_EXPORT LayerNeedsUpdate(LayerImpl* layer, bool layer_is_drawn, const TransformTree& tree); +void CC_EXPORT VerifyClipTreeCalculations(const LayerImplList& layer_list, + PropertyTrees* property_trees); + gfx::Transform CC_EXPORT DrawTransform(const LayerImpl* layer, const TransformTree& tree); diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.cc b/chromium/cc/trees/latency_info_swap_promise_monitor.cc index 23635cd8566..96a6d7786e1 100644 --- a/chromium/cc/trees/latency_info_swap_promise_monitor.cc +++ b/chromium/cc/trees/latency_info_swap_promise_monitor.cc @@ -53,14 +53,16 @@ LatencyInfoSwapPromiseMonitor::~LatencyInfoSwapPromiseMonitor() { void LatencyInfoSwapPromiseMonitor::OnSetNeedsCommitOnMain() { if (AddRenderingScheduledComponent(latency_, true /* on_main */)) { - scoped_ptr<SwapPromise> swap_promise(new LatencyInfoSwapPromise(*latency_)); + std::unique_ptr<SwapPromise> swap_promise( + new LatencyInfoSwapPromise(*latency_)); layer_tree_host_->QueueSwapPromise(std::move(swap_promise)); } } void LatencyInfoSwapPromiseMonitor::OnSetNeedsRedrawOnImpl() { if (AddRenderingScheduledComponent(latency_, false /* on_main */)) { - scoped_ptr<SwapPromise> swap_promise(new LatencyInfoSwapPromise(*latency_)); + std::unique_ptr<SwapPromise> swap_promise( + new LatencyInfoSwapPromise(*latency_)); // Queue a pinned swap promise on the active tree. This will allow // measurement of the time to the next SwapBuffers(). The swap // promise is pinned so that it is not interrupted by new incoming @@ -95,7 +97,7 @@ void LatencyInfoSwapPromiseMonitor::OnForwardScrollUpdateToMainThreadOnImpl() { new_latency.CopyLatencyFrom( *latency_, ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT); - scoped_ptr<SwapPromise> swap_promise( + std::unique_ptr<SwapPromise> swap_promise( new LatencyInfoSwapPromise(new_latency)); layer_tree_host_impl_->QueueSwapPromiseForMainThreadScrollUpdate( std::move(swap_promise)); diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index 3f0d58c5039..794809f4599 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -22,7 +22,7 @@ #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "cc/animation/animation_events.h" @@ -81,9 +81,9 @@ Layer* UpdateAndGetLayer(Layer* current_layer, return layer_it->second; } -scoped_ptr<base::trace_event::TracedValue> +std::unique_ptr<base::trace_event::TracedValue> ComputeLayerTreeHostProtoSizeSplitAsValue(proto::LayerTreeHost* proto) { - scoped_ptr<base::trace_event::TracedValue> value( + std::unique_ptr<base::trace_event::TracedValue> value( new base::trace_event::TracedValue()); base::CheckedNumeric<int> base_layer_properties_size = 0; base::CheckedNumeric<int> picture_layer_properties_size = 0; @@ -140,13 +140,13 @@ LayerTreeHost::InitParams::InitParams() { LayerTreeHost::InitParams::~InitParams() { } -scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded( +std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, InitParams* params) { DCHECK(params->main_task_runner.get()); DCHECK(impl_task_runner.get()); DCHECK(params->settings); - scoped_ptr<LayerTreeHost> layer_tree_host( + std::unique_ptr<LayerTreeHost> layer_tree_host( new LayerTreeHost(params, CompositorMode::THREADED)); layer_tree_host->InitializeThreaded( params->main_task_runner, impl_task_runner, @@ -154,11 +154,11 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded( return layer_tree_host; } -scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded( +std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client, InitParams* params) { DCHECK(params->settings); - scoped_ptr<LayerTreeHost> layer_tree_host( + std::unique_ptr<LayerTreeHost> layer_tree_host( new LayerTreeHost(params, CompositorMode::SINGLE_THREADED)); layer_tree_host->InitializeSingleThreaded( single_thread_client, params->main_task_runner, @@ -166,12 +166,13 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded( return layer_tree_host; } -scoped_ptr<LayerTreeHost> LayerTreeHost::CreateRemoteServer( +std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateRemoteServer( RemoteProtoChannel* remote_proto_channel, InitParams* params) { DCHECK(params->main_task_runner.get()); DCHECK(params->settings); DCHECK(remote_proto_channel); + TRACE_EVENT0("cc.remote", "LayerTreeHost::CreateRemoteServer"); // Using an external begin frame source is not supported on the server in // remote mode. @@ -179,14 +180,14 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::CreateRemoteServer( DCHECK(!params->external_begin_frame_source); DCHECK(params->image_serialization_processor); - scoped_ptr<LayerTreeHost> layer_tree_host( + std::unique_ptr<LayerTreeHost> layer_tree_host( new LayerTreeHost(params, CompositorMode::REMOTE)); layer_tree_host->InitializeRemoteServer(remote_proto_channel, params->main_task_runner); return layer_tree_host; } -scoped_ptr<LayerTreeHost> LayerTreeHost::CreateRemoteClient( +std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateRemoteClient( RemoteProtoChannel* remote_proto_channel, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, InitParams* params) { @@ -201,7 +202,7 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::CreateRemoteClient( DCHECK(!params->external_begin_frame_source); DCHECK(params->image_serialization_processor); - scoped_ptr<LayerTreeHost> layer_tree_host( + std::unique_ptr<LayerTreeHost> layer_tree_host( new LayerTreeHost(params, CompositorMode::REMOTE)); layer_tree_host->InitializeRemoteClient( remote_proto_channel, params->main_task_runner, impl_task_runner); @@ -216,7 +217,6 @@ LayerTreeHost::LayerTreeHost(InitParams* params, CompositorMode mode) 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), @@ -259,10 +259,10 @@ LayerTreeHost::LayerTreeHost(InitParams* params, CompositorMode mode) void LayerTreeHost::InitializeThreaded( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { task_runner_provider_ = TaskRunnerProvider::Create(main_task_runner, impl_task_runner); - scoped_ptr<ProxyMain> proxy_main = + std::unique_ptr<ProxyMain> proxy_main = ProxyMain::CreateThreaded(this, task_runner_provider_.get()); InitializeProxy(std::move(proxy_main), std::move(external_begin_frame_source)); @@ -271,7 +271,7 @@ void LayerTreeHost::InitializeThreaded( void LayerTreeHost::InitializeSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { task_runner_provider_ = TaskRunnerProvider::Create(main_task_runner, nullptr); InitializeProxy(SingleThreadProxy::Create(this, single_thread_client, task_runner_provider_.get()), @@ -313,23 +313,23 @@ void LayerTreeHost::InitializeRemoteClient( } void LayerTreeHost::InitializeForTesting( - scoped_ptr<TaskRunnerProvider> task_runner_provider, - scoped_ptr<Proxy> proxy_for_testing, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<TaskRunnerProvider> task_runner_provider, + std::unique_ptr<Proxy> proxy_for_testing, + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { task_runner_provider_ = std::move(task_runner_provider); InitializeProxy(std::move(proxy_for_testing), std::move(external_begin_frame_source)); } void LayerTreeHost::SetTaskRunnerProviderForTesting( - scoped_ptr<TaskRunnerProvider> task_runner_provider) { + std::unique_ptr<TaskRunnerProvider> task_runner_provider) { DCHECK(!task_runner_provider_); task_runner_provider_ = std::move(task_runner_provider); } void LayerTreeHost::InitializeProxy( - scoped_ptr<Proxy> proxy, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<Proxy> proxy, + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal"); DCHECK(task_runner_provider_); @@ -364,7 +364,7 @@ LayerTreeHost::~LayerTreeHost() { if (root_layer_.get()) { // The layer tree must be destroyed before the layer tree host. We've - // made a contract with our animation controllers that the registrar + // made a contract with our animation controllers that the animation_host // will outlive them, and we must make good. root_layer_ = NULL; } @@ -411,8 +411,7 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() && root_layer()) { LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->DidBeginTracing(); }, - CallFunctionLayerType::ALL_LAYERS); + this, [](Layer* layer) { layer->DidBeginTracing(); }); } LayerTreeImpl* sync_tree = host_impl->sync_tree(); @@ -466,15 +465,15 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { bool property_trees_changed_on_active_tree = sync_tree->IsActiveTree() && sync_tree->property_trees()->changed; - // We need to preserve the damage status of property trees on active tree. We - // do this by pushing the damage status from active tree property trees to - // main thread property trees. + // Property trees may store damage status. We preserve the sync tree damage + // status by pushing the damage status from sync tree property trees to main + // thread property trees or by moving it onto the layers. if (root_layer_ && property_trees_changed_on_active_tree) { if (property_trees_.sequence_number == sync_tree->property_trees()->sequence_number) sync_tree->property_trees()->PushChangeTrackingTo(&property_trees_); else - sync_tree->root_layer()->PushLayerPropertyChangedForSubtree(); + sync_tree->MoveChangeTrackingToLayers(); } // Setting property trees must happen before pushing the page scale. sync_tree->SetPropertyTrees(property_trees_); @@ -537,16 +536,7 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { sync_tree->UpdatePropertyTreeScrollOffset(&property_trees_); micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl); - // We don't track changes to effect tree on main thread. But, to preserve any - // change tracking done on active tree's effect tree, we copy it to the main - // thread's effect tree before we push the main thread property trees to - // active tree. - if (property_trees_changed_on_active_tree) - property_trees_.ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); - else - property_trees_.ResetAllChangeTracking( - PropertyTrees::ResetFlags::TRANSFORM_TREE); + property_trees_.ResetAllChangeTracking(); } void LayerTreeHost::WillCommit() { @@ -577,7 +567,7 @@ void LayerTreeHost::CommitComplete() { } } -void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) { +void LayerTreeHost::SetOutputSurface(std::unique_ptr<OutputSurface> surface) { TRACE_EVENT0("cc", "LayerTreeHost::SetOutputSurface"); DCHECK(output_surface_lost_); DCHECK(surface); @@ -587,7 +577,7 @@ void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) { proxy_->SetOutputSurface(new_output_surface_.get()); } -scoped_ptr<OutputSurface> LayerTreeHost::ReleaseOutputSurface() { +std::unique_ptr<OutputSurface> LayerTreeHost::ReleaseOutputSurface() { DCHECK(!visible_); DCHECK(!output_surface_lost_); @@ -618,11 +608,11 @@ void LayerTreeHost::DidFailToInitializeOutputSurface() { client_->DidFailToInitializeOutputSurface(); } -scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( +std::unique_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( LayerTreeHostImplClient* client) { DCHECK(!IsRemoteServer()); DCHECK(task_runner_provider_->IsImplThread()); - scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( + std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( settings_, client, task_runner_provider_.get(), rendering_stats_instrumentation_.get(), shared_bitmap_manager_, gpu_memory_buffer_manager_, task_graph_runner_, id_); @@ -656,20 +646,8 @@ void LayerTreeHost::SetDeferCommits(bool defer_commits) { } void LayerTreeHost::SetNeedsDisplayOnAllLayers() { - std::stack<Layer*> layer_stack; - layer_stack.push(root_layer()); - while (!layer_stack.empty()) { - Layer* current_layer = layer_stack.top(); - layer_stack.pop(); - current_layer->SetNeedsDisplay(); - for (unsigned int i = 0; i < current_layer->children().size(); i++) { - layer_stack.push(current_layer->child_at(i)); - } - } -} - -void LayerTreeHost::SetOutputIsSecure(bool output_is_secure) { - proxy_->SetOutputIsSecure(output_is_secure); + for (auto* layer : *this) + layer->SetNeedsDisplay(); } const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const { @@ -724,7 +702,6 @@ bool LayerTreeHost::BeginMainFrameRequested() const { return proxy_->BeginMainFrameRequested(); } - void LayerTreeHost::SetNextCommitWaitsForActivation() { proxy_->SetNextCommitWaitsForActivation(); } @@ -734,7 +711,8 @@ void LayerTreeHost::SetNextCommitForcesRedraw() { proxy_->SetNeedsUpdateLayers(); } -void LayerTreeHost::SetAnimationEvents(scoped_ptr<AnimationEvents> events) { +void LayerTreeHost::SetAnimationEvents( + std::unique_ptr<AnimationEvents> events) { DCHECK(task_runner_provider_->IsMainThread()); animation_host_->SetAnimationEvents(std::move(events)); } @@ -902,24 +880,32 @@ bool LayerTreeHost::UpdateLayers() { return result || next_commit_forces_redraw_; } -void LayerTreeHost::DidCompletePageScaleAnimation() { - did_complete_scale_animation_ = true; +LayerListIterator<Layer> LayerTreeHost::begin() { + return LayerListIterator<Layer>(root_layer_.get()); } -static Layer* FindFirstScrollableLayer(Layer* layer) { - if (!layer) - return NULL; +LayerListIterator<Layer> LayerTreeHost::end() { + return LayerListIterator<Layer>(nullptr); +} - if (layer->scrollable()) - return layer; +const LayerListIterator<Layer> LayerTreeHost::begin() const { + return LayerListIterator<Layer>(root_layer_.get()); +} - for (size_t i = 0; i < layer->children().size(); ++i) { - Layer* found = FindFirstScrollableLayer(layer->children()[i].get()); - if (found) - return found; - } +const LayerListIterator<Layer> LayerTreeHost::end() const { + return LayerListIterator<Layer>(nullptr); +} - return NULL; +LayerListReverseIterator<Layer> LayerTreeHost::rbegin() { + return LayerListReverseIterator<Layer>(root_layer_.get()); +} + +LayerListReverseIterator<Layer> LayerTreeHost::rend() { + return LayerListReverseIterator<Layer>(nullptr); +} + +void LayerTreeHost::DidCompletePageScaleAnimation() { + did_complete_scale_animation_ = true; } void LayerTreeHost::RecordGpuRasterizationHistogram() { @@ -949,7 +935,7 @@ void LayerTreeHost::RecordGpuRasterizationHistogram() { } void LayerTreeHost::BuildPropertyTreesForTesting() { - LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer_.get()); + PropertyTreeBuilder::PreCalculateMetaInformation(root_layer_.get()); gfx::Transform identity_transform; PropertyTreeBuilder::BuildPropertyTrees( root_layer_.get(), page_scale_layer_.get(), @@ -959,6 +945,14 @@ void LayerTreeHost::BuildPropertyTreesForTesting() { gfx::Rect(device_viewport_size_), identity_transform, &property_trees_); } +void LayerTreeHost::ReportFixedRasterScaleUseCounters( + bool has_fixed_raster_scale_blurry_content, + bool has_fixed_raster_scale_potential_performance_regression) { + client_->ReportFixedRasterScaleUseCounters( + has_fixed_raster_scale_blurry_content, + has_fixed_raster_scale_potential_performance_regression); +} + bool LayerTreeHost::UsingSharedMemoryResources() { return GetRendererCapabilities().using_shared_memory_resources; } @@ -969,7 +963,8 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { UpdateHudLayer(); - Layer* root_scroll = FindFirstScrollableLayer(root_layer); + Layer* root_scroll = + PropertyTreeBuilder::FindFirstScrollableLayer(root_layer); Layer* page_scale_layer = page_scale_layer_.get(); if (!page_scale_layer && root_scroll) page_scale_layer = root_scroll->parent(); @@ -986,14 +981,23 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees"); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees"); - LayerTreeHostCommon::PreCalculateMetaInformation(root_layer); + PropertyTreeBuilder::PreCalculateMetaInformation(root_layer); bool can_render_to_separate_surface = true; - PropertyTreeBuilder::BuildPropertyTrees( - root_layer, page_scale_layer, inner_viewport_scroll_layer_.get(), - outer_viewport_scroll_layer_.get(), overscroll_elasticity_layer_.get(), - elastic_overscroll_, page_scale_factor_, device_scale_factor_, - gfx::Rect(device_viewport_size_), identity_transform, &property_trees_); - draw_property_utils::UpdateRenderSurfaces(root_layer, &property_trees_); + if (!settings_.use_layer_lists) { + // If use_layer_lists is set, then the property trees should have been + // built by the client already. + PropertyTreeBuilder::BuildPropertyTrees( + root_layer, page_scale_layer, inner_viewport_scroll_layer_.get(), + outer_viewport_scroll_layer_.get(), + overscroll_elasticity_layer_.get(), elastic_overscroll_, + page_scale_factor_, device_scale_factor_, + gfx::Rect(device_viewport_size_), identity_transform, + &property_trees_); + TRACE_EVENT_INSTANT1("cc", + "LayerTreeHost::UpdateLayers_BuiltPropertyTrees", + TRACE_EVENT_SCOPE_THREAD, "property_trees", + property_trees_.AsTracedValue()); + } draw_property_utils::UpdatePropertyTrees(&property_trees_, can_render_to_separate_surface); draw_property_utils::FindLayersThatNeedUpdates( @@ -1104,7 +1108,7 @@ void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints, } void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) { - scoped_ptr<AnimationEvents> events = animation_host_->CreateEvents(); + std::unique_ptr<AnimationEvents> events = animation_host_->CreateEvents(); if (animation_host_->AnimateLayers(monotonic_time)) animation_host_->UpdateAnimationState(true, events.get()); @@ -1209,14 +1213,15 @@ void LayerTreeHost::SetEventListenerProperties( int LayerTreeHost::ScheduleMicroBenchmark( const std::string& benchmark_name, - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback) { return micro_benchmark_controller_.ScheduleRun(benchmark_name, std::move(value), callback); } -bool LayerTreeHost::SendMessageToMicroBenchmark(int id, - scoped_ptr<base::Value> value) { +bool LayerTreeHost::SendMessageToMicroBenchmark( + int id, + std::unique_ptr<base::Value> value) { return micro_benchmark_controller_.SendMessage(id, std::move(value)); } @@ -1234,7 +1239,8 @@ void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() { (*it)->OnSetNeedsCommitOnMain(); } -void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) { +void LayerTreeHost::QueueSwapPromise( + std::unique_ptr<SwapPromise> swap_promise) { DCHECK(swap_promise); swap_promise_list_.push_back(std::move(swap_promise)); } @@ -1258,28 +1264,6 @@ SurfaceSequence LayerTreeHost::CreateSurfaceSequence() { return SurfaceSequence(surface_id_namespace_, next_surface_sequence_++); } -void LayerTreeHost::SetChildrenNeedBeginFrames( - bool children_need_begin_frames) const { - proxy_->SetChildrenNeedBeginFrames(children_need_begin_frames); -} - -void LayerTreeHost::SendBeginFramesToChildren( - const BeginFrameArgs& args) const { - client_->SendBeginFramesToChildren(args); -} - -void LayerTreeHost::SetAuthoritativeVSyncInterval( - const base::TimeDelta& interval) { - proxy_->SetAuthoritativeVSyncInterval(interval); -} - -void LayerTreeHost::RecordFrameTimingEvents( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) { - client_->RecordFrameTimingEvents(std::move(composite_events), - std::move(main_frame_events)); -} - Layer* LayerTreeHost::LayerById(int id) const { LayerIdMap::const_iterator iter = layer_id_map_.find(id); return iter != layer_id_map_.end() ? iter->second : NULL; @@ -1306,19 +1290,20 @@ void LayerTreeHost::RegisterLayer(Layer* layer) { DCHECK(!LayerById(layer->id())); DCHECK(!in_paint_layer_contents_); layer_id_map_[layer->id()] = layer; - animation_host_->RegisterLayer(layer->id(), LayerTreeType::ACTIVE); + animation_host_->RegisterElement(layer->id(), ElementListType::ACTIVE); } void LayerTreeHost::UnregisterLayer(Layer* layer) { DCHECK(LayerById(layer->id())); DCHECK(!in_paint_layer_contents_); - animation_host_->UnregisterLayer(layer->id(), LayerTreeType::ACTIVE); + animation_host_->UnregisterElement(layer->id(), ElementListType::ACTIVE); RemoveLayerShouldPushProperties(layer); layer_id_map_.erase(layer->id()); } -bool LayerTreeHost::IsLayerInTree(int layer_id, LayerTreeType tree_type) const { - return tree_type == LayerTreeType::ACTIVE && LayerById(layer_id); +bool LayerTreeHost::IsElementInList(ElementId element_id, + ElementListType list_type) const { + return list_type == ElementListType::ACTIVE && LayerById(element_id); } void LayerTreeHost::SetMutatorsNeedCommit() { @@ -1329,51 +1314,87 @@ void LayerTreeHost::SetMutatorsNeedRebuildPropertyTrees() { property_trees_.needs_rebuild = true; } -void LayerTreeHost::SetLayerFilterMutated(int layer_id, - LayerTreeType tree_type, - const FilterOperations& filters) { - Layer* layer = LayerById(layer_id); +void LayerTreeHost::SetElementFilterMutated(ElementId element_id, + ElementListType list_type, + const FilterOperations& filters) { + Layer* layer = LayerById(element_id); DCHECK(layer); layer->OnFilterAnimated(filters); } -void LayerTreeHost::SetLayerOpacityMutated(int layer_id, - LayerTreeType tree_type, - float opacity) { - Layer* layer = LayerById(layer_id); +void LayerTreeHost::SetElementOpacityMutated(ElementId element_id, + ElementListType list_type, + float opacity) { + Layer* layer = LayerById(element_id); DCHECK(layer); layer->OnOpacityAnimated(opacity); } -void LayerTreeHost::SetLayerTransformMutated(int layer_id, - LayerTreeType tree_type, - const gfx::Transform& transform) { - Layer* layer = LayerById(layer_id); +void LayerTreeHost::SetElementTransformMutated( + ElementId element_id, + ElementListType list_type, + const gfx::Transform& transform) { + Layer* layer = LayerById(element_id); DCHECK(layer); layer->OnTransformAnimated(transform); } -void LayerTreeHost::SetLayerScrollOffsetMutated( - int layer_id, - LayerTreeType tree_type, +void LayerTreeHost::SetElementScrollOffsetMutated( + ElementId element_id, + ElementListType list_type, const gfx::ScrollOffset& scroll_offset) { - Layer* layer = LayerById(layer_id); + Layer* layer = LayerById(element_id); DCHECK(layer); layer->OnScrollOffsetAnimated(scroll_offset); } -void LayerTreeHost::LayerTransformIsPotentiallyAnimatingChanged( - int layer_id, - LayerTreeType tree_type, +void LayerTreeHost::ElementTransformIsAnimatingChanged( + ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, bool is_animating) { - Layer* layer = LayerById(layer_id); - DCHECK(layer); - layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); + Layer* layer = LayerById(element_id); + if (layer) { + switch (change_type) { + case AnimationChangeType::POTENTIAL: + layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); + break; + case AnimationChangeType::RUNNING: + layer->OnTransformIsCurrentlyAnimatingChanged(is_animating); + break; + case AnimationChangeType::BOTH: + layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); + layer->OnTransformIsCurrentlyAnimatingChanged(is_animating); + break; + } + } +} + +void LayerTreeHost::ElementOpacityIsAnimatingChanged( + ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, + bool is_animating) { + Layer* layer = LayerById(element_id); + if (layer) { + switch (change_type) { + case AnimationChangeType::POTENTIAL: + layer->OnOpacityIsPotentiallyAnimatingChanged(is_animating); + break; + case AnimationChangeType::RUNNING: + layer->OnOpacityIsCurrentlyAnimatingChanged(is_animating); + break; + case AnimationChangeType::BOTH: + layer->OnOpacityIsPotentiallyAnimatingChanged(is_animating); + layer->OnOpacityIsCurrentlyAnimatingChanged(is_animating); + break; + } + } } gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation( - int layer_id) const { - Layer* layer = LayerById(layer_id); + ElementId element_id) const { + Layer* layer = LayerById(element_id); DCHECK(layer); return layer->ScrollOffsetForAnimation(); } @@ -1385,52 +1406,52 @@ bool LayerTreeHost::ScrollOffsetAnimationWasInterrupted( bool LayerTreeHost::IsAnimatingFilterProperty(const Layer* layer) const { return animation_host_->IsAnimatingFilterProperty(layer->id(), - LayerTreeType::ACTIVE); + ElementListType::ACTIVE); } bool LayerTreeHost::IsAnimatingOpacityProperty(const Layer* layer) const { return animation_host_->IsAnimatingOpacityProperty(layer->id(), - LayerTreeType::ACTIVE); + ElementListType::ACTIVE); } bool LayerTreeHost::IsAnimatingTransformProperty(const Layer* layer) const { return animation_host_->IsAnimatingTransformProperty(layer->id(), - LayerTreeType::ACTIVE); + ElementListType::ACTIVE); } bool LayerTreeHost::HasPotentiallyRunningFilterAnimation( const Layer* layer) const { return animation_host_->HasPotentiallyRunningFilterAnimation( - layer->id(), LayerTreeType::ACTIVE); + layer->id(), ElementListType::ACTIVE); } bool LayerTreeHost::HasPotentiallyRunningOpacityAnimation( const Layer* layer) const { return animation_host_->HasPotentiallyRunningOpacityAnimation( - layer->id(), LayerTreeType::ACTIVE); + layer->id(), ElementListType::ACTIVE); } bool LayerTreeHost::HasPotentiallyRunningTransformAnimation( const Layer* layer) const { return animation_host_->HasPotentiallyRunningTransformAnimation( - layer->id(), LayerTreeType::ACTIVE); + layer->id(), ElementListType::ACTIVE); } bool LayerTreeHost::HasOnlyTranslationTransforms(const Layer* layer) const { return animation_host_->HasOnlyTranslationTransforms(layer->id(), - LayerTreeType::ACTIVE); + ElementListType::ACTIVE); } bool LayerTreeHost::MaximumTargetScale(const Layer* layer, float* max_scale) const { - return animation_host_->MaximumTargetScale(layer->id(), LayerTreeType::ACTIVE, - max_scale); + return animation_host_->MaximumTargetScale( + layer->id(), ElementListType::ACTIVE, max_scale); } bool LayerTreeHost::AnimationStartScale(const Layer* layer, float* start_scale) const { return animation_host_->AnimationStartScale( - layer->id(), LayerTreeType::ACTIVE, start_scale); + layer->id(), ElementListType::ACTIVE, start_scale); } bool LayerTreeHost::HasAnyAnimationTargetingProperty( @@ -1500,16 +1521,18 @@ void LayerTreeHost::ToProtobufForCommit(proto::LayerTreeHost* proto) { proto->set_needs_full_tree_sync(needs_full_tree_sync_); proto->set_needs_meta_info_recomputation(needs_meta_info_recomputation_); proto->set_source_frame_number(source_frame_number_); - proto->set_meta_information_sequence_number( - meta_information_sequence_number_); + LayerProtoConverter::SerializeLayerHierarchy(root_layer_, proto->mutable_root_layer()); + // layers_that_should_push_properties_ should be serialized before layer // properties because it is cleared during the properties serialization. for (auto layer : layers_that_should_push_properties_) proto->add_layers_that_should_push_properties(layer->id()); + LayerProtoConverter::SerializeLayerProperties(this, proto->mutable_layer_updates()); + proto->set_hud_layer_id(hud_layer_ ? hud_layer_->id() : Layer::INVALID_ID); debug_state_.ToProtobuf(proto->mutable_debug_state()); SizeToProto(device_viewport_size_, proto->mutable_device_viewport_size()); @@ -1554,7 +1577,9 @@ void LayerTreeHost::ToProtobufForCommit(proto::LayerTreeHost* proto) { : Layer::INVALID_ID); LayerSelectionToProtobuf(selection_, proto->mutable_selection()); + property_trees_.ToProtobuf(proto->mutable_property_trees()); + proto->set_surface_id_namespace(surface_id_namespace_); proto->set_next_surface_sequence(next_surface_sequence_); @@ -1567,7 +1592,6 @@ void LayerTreeHost::FromProtobufForCommit(const proto::LayerTreeHost& proto) { needs_full_tree_sync_ = proto.needs_full_tree_sync(); needs_meta_info_recomputation_ = proto.needs_meta_info_recomputation(); source_frame_number_ = proto.source_frame_number(); - meta_information_sequence_number_ = proto.meta_information_sequence_number(); // Layer hierarchy. scoped_refptr<Layer> new_root_layer = @@ -1642,12 +1666,9 @@ void LayerTreeHost::FromProtobufForCommit(const proto::LayerTreeHost& proto) { // updated for other reasons. All layers that at this point are part of the // layer tree are valid, so it is OK that they have a valid sequence number. int seq_num = property_trees_.sequence_number; - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, - [seq_num](Layer* layer) { - layer->set_property_tree_sequence_number(seq_num); - }, - CallFunctionLayerType::ALL_LAYERS); + LayerTreeHostCommon::CallFunctionForEveryLayer(this, [seq_num](Layer* layer) { + layer->set_property_tree_sequence_number(seq_num); + }); surface_id_namespace_ = proto.surface_id_namespace(); next_surface_sequence_ = proto.next_surface_sequence(); diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index e8bbf5b11fe..e544e0cac41 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -9,6 +9,7 @@ #include <stdint.h> #include <limits> +#include <memory> #include <set> #include <string> #include <unordered_map> @@ -17,12 +18,10 @@ #include "base/cancelable_callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "cc/animation/target_property.h" #include "cc/base/cc_export.h" -#include "cc/debug/frame_timing_tracker.h" #include "cc/debug/micro_benchmark.h" #include "cc/debug/micro_benchmark_controller.h" #include "cc/input/event_listener_properties.h" @@ -31,6 +30,7 @@ #include "cc/input/scrollbar.h" #include "cc/input/top_controls_state.h" #include "cc/layers/layer_collections.h" +#include "cc/layers/layer_list_iterator.h" #include "cc/output/output_surface.h" #include "cc/output/renderer_capabilities.h" #include "cc/output/swap_promise.h" @@ -53,7 +53,6 @@ class GpuMemoryBufferManager; namespace cc { class AnimationEvents; -class AnimationRegistrar; class AnimationHost; class BeginFrameSource; class HeadsUpDisplayLayer; @@ -91,7 +90,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { TaskGraphRunner* task_graph_runner = nullptr; LayerTreeSettings const* settings = nullptr; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner; - scoped_ptr<BeginFrameSource> external_begin_frame_source; + std::unique_ptr<BeginFrameSource> external_begin_frame_source; ImageSerializationProcessor* image_serialization_processor = nullptr; InitParams(); @@ -99,15 +98,15 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { }; // The SharedBitmapManager will be used on the compositor thread. - static scoped_ptr<LayerTreeHost> CreateThreaded( + static std::unique_ptr<LayerTreeHost> CreateThreaded( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, InitParams* params); - static scoped_ptr<LayerTreeHost> CreateSingleThreaded( + static std::unique_ptr<LayerTreeHost> CreateSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client, InitParams* params); - static scoped_ptr<LayerTreeHost> CreateRemoteServer( + static std::unique_ptr<LayerTreeHost> CreateRemoteServer( RemoteProtoChannel* remote_proto_channel, InitParams* params); @@ -117,7 +116,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // a CompositorMessageToImpl::CloseImpl message from the server. This ensures // that the client will not send any compositor messages once the // LayerTreeHost on the server is destroyed. - static scoped_ptr<LayerTreeHost> CreateRemoteClient( + static std::unique_ptr<LayerTreeHost> CreateRemoteClient( RemoteProtoChannel* remote_proto_channel, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, InitParams* params); @@ -135,12 +134,12 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete(); - void SetOutputSurface(scoped_ptr<OutputSurface> output_surface); - scoped_ptr<OutputSurface> ReleaseOutputSurface(); + void SetOutputSurface(std::unique_ptr<OutputSurface> output_surface); + std::unique_ptr<OutputSurface> ReleaseOutputSurface(); void RequestNewOutputSurface(); void DidInitializeOutputSurface(); void DidFailToInitializeOutputSurface(); - virtual scoped_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( + virtual std::unique_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( LayerTreeHostImplClient* client); void DidLoseOutputSurface(); bool output_surface_lost() const { return output_surface_lost_; } @@ -148,6 +147,13 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void DidCompleteSwapBuffers() { client_->DidCompleteSwapBuffers(); } bool UpdateLayers(); + LayerListIterator<Layer> begin(); + LayerListIterator<Layer> end(); + const LayerListIterator<Layer> begin() const; + const LayerListIterator<Layer> end() const; + LayerListReverseIterator<Layer> rbegin(); + LayerListReverseIterator<Layer> rend(); + // Called when the compositor completed page scale animation. void DidCompletePageScaleAnimation(); @@ -167,22 +173,12 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { int source_frame_number() const { return source_frame_number_; } - int meta_information_sequence_number() { - return meta_information_sequence_number_; - } - bool gpu_rasterization_histogram_recorded() const { return gpu_rasterization_histogram_recorded_; } - void IncrementMetaInformationSequenceNumber() { - meta_information_sequence_number_++; - } - void SetNeedsDisplayOnAllLayers(); - void SetOutputIsSecure(bool output_is_secure); - void CollectRenderingStats(RenderingStats* stats) const; RenderingStatsInstrumentation* rendering_stats_instrumentation() const { @@ -206,7 +202,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void SetNextCommitForcesRedraw(); - void SetAnimationEvents(scoped_ptr<AnimationEvents> events); + void SetAnimationEvents(std::unique_ptr<AnimationEvents> events); void SetRootLayer(scoped_refptr<Layer> root_layer); Layer* root_layer() { return root_layer_.get(); } @@ -320,10 +316,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // Returns the id of the benchmark on success, 0 otherwise. int ScheduleMicroBenchmark(const std::string& benchmark_name, - scoped_ptr<base::Value> value, + std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback); // Returns true if the message was successfully delivered and handled. - bool SendMessageToMicroBenchmark(int id, scoped_ptr<base::Value> value); + bool SendMessageToMicroBenchmark(int id, std::unique_ptr<base::Value> value); // When a SwapPromiseMonitor is created on the main thread, it calls // InsertSwapPromiseMonitor() to register itself with LayerTreeHost. @@ -334,7 +330,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // Call this function when you expect there to be a swap buffer. // See swap_promise.h for how to use SwapPromise. - void QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise); + void QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise); void BreakSwapPromises(SwapPromise::DidNotSwapReason reason); @@ -343,20 +339,11 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void set_surface_id_namespace(uint32_t id_namespace); SurfaceSequence CreateSurfaceSequence(); - void SetChildrenNeedBeginFrames(bool children_need_begin_frames) const; - void SendBeginFramesToChildren(const BeginFrameArgs& args) const; - - void SetAuthoritativeVSyncInterval(const base::TimeDelta& interval); - PropertyTrees* property_trees() { return &property_trees_; } bool needs_meta_info_recomputation() { return needs_meta_info_recomputation_; } - void RecordFrameTimingEvents( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events); - Layer* LayerById(int id) const; void AddLayerShouldPushProperties(Layer* layer); @@ -366,28 +353,35 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void RegisterLayer(Layer* layer); void UnregisterLayer(Layer* layer); - // LayerTreeMutatorsClient implementation. - bool IsLayerInTree(int layer_id, LayerTreeType tree_type) const override; + // MutatorHostClient implementation. + bool IsElementInList(ElementId element_id, + ElementListType list_type) const override; void SetMutatorsNeedCommit() override; void SetMutatorsNeedRebuildPropertyTrees() 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, + void SetElementFilterMutated(ElementId element_id, + ElementListType list_type, + const FilterOperations& filters) override; + void SetElementOpacityMutated(ElementId element_id, + ElementListType list_type, + float opacity) override; + void SetElementTransformMutated(ElementId element_id, + ElementListType list_type, + const gfx::Transform& transform) override; + void SetElementScrollOffsetMutated( + ElementId element_id, + ElementListType list_type, const gfx::ScrollOffset& scroll_offset) override; - void LayerTransformIsPotentiallyAnimatingChanged(int layer_id, - LayerTreeType tree_type, - bool is_animating) override; + void ElementTransformIsAnimatingChanged(ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, + bool is_animating) override; + void ElementOpacityIsAnimatingChanged(ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, + bool is_animating) override; void ScrollOffsetAnimationFinished() override {} - gfx::ScrollOffset GetScrollOffsetForAnimation(int layer_id) const override; + gfx::ScrollOffset GetScrollOffsetForAnimation( + ElementId element_id) const override; bool ScrollOffsetAnimationWasInterrupted(const Layer* layer) const; bool IsAnimatingFilterProperty(const Layer* layer) const; @@ -425,16 +419,20 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { return image_serialization_processor_; } + void ReportFixedRasterScaleUseCounters( + bool has_fixed_raster_scale_blurry_content, + bool has_fixed_raster_scale_potential_performance_regression); + protected: LayerTreeHost(InitParams* params, CompositorMode mode); void InitializeThreaded( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<BeginFrameSource> external_begin_frame_source); void InitializeSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<BeginFrameSource> external_begin_frame_source); void InitializeRemoteServer( RemoteProtoChannel* remote_proto_channel, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); @@ -443,14 +441,14 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); void InitializeForTesting( - scoped_ptr<TaskRunnerProvider> task_runner_provider, - scoped_ptr<Proxy> proxy_for_testing, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<TaskRunnerProvider> task_runner_provider, + std::unique_ptr<Proxy> proxy_for_testing, + std::unique_ptr<BeginFrameSource> external_begin_frame_source); void SetOutputSurfaceLostForTesting(bool is_lost) { output_surface_lost_ = is_lost; } void SetTaskRunnerProviderForTesting( - scoped_ptr<TaskRunnerProvider> task_runner_provider); + std::unique_ptr<TaskRunnerProvider> task_runner_provider); // shared_bitmap_manager(), gpu_memory_buffer_manager(), and // task_graph_runner() return valid values only until the LayerTreeHostImpl is @@ -473,8 +471,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { friend class LayerTreeHostSerializationTest; void InitializeProxy( - scoped_ptr<Proxy> proxy, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<Proxy> proxy, + std::unique_ptr<BeginFrameSource> external_begin_frame_source); bool DoUpdateLayers(Layer* root_layer); void UpdateHudLayer(); @@ -506,20 +504,20 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { bool needs_meta_info_recomputation_; LayerTreeHostClient* client_; - scoped_ptr<Proxy> proxy_; - scoped_ptr<TaskRunnerProvider> task_runner_provider_; + std::unique_ptr<Proxy> proxy_; + std::unique_ptr<TaskRunnerProvider> task_runner_provider_; int source_frame_number_; - int meta_information_sequence_number_; - scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation_; + std::unique_ptr<RenderingStatsInstrumentation> + rendering_stats_instrumentation_; // |current_output_surface_| can't be updated until we've successfully // initialized a new output surface. |new_output_surface_| contains the // new output surface that is currently being initialized. If initialization // is successful then |new_output_surface_| replaces // |current_output_surface_|. - scoped_ptr<OutputSurface> new_output_surface_; - scoped_ptr<OutputSurface> current_output_surface_; + std::unique_ptr<OutputSurface> new_output_surface_; + std::unique_ptr<OutputSurface> current_output_surface_; bool output_surface_lost_; scoped_refptr<Layer> root_layer_; @@ -554,9 +552,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { EventListenerProperties event_listener_properties_[static_cast<size_t>( EventListenerClass::kNumClasses)]; - scoped_ptr<AnimationHost> animation_host_; + std::unique_ptr<AnimationHost> animation_host_; - scoped_ptr<PendingPageScaleAnimation> pending_page_scale_animation_; + std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_; // If set, then page scale animation has completed, but the client hasn't been // notified about it yet. @@ -580,7 +578,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { ImageSerializationProcessor* image_serialization_processor_; - std::vector<scoped_ptr<SwapPromise>> swap_promise_list_; + std::vector<std::unique_ptr<SwapPromise>> swap_promise_list_; std::set<SwapPromiseMonitor*> swap_promise_monitor_; PropertyTrees property_trees_; diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index e37d8e02600..f02e40ec80b 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -5,10 +5,9 @@ #ifndef CC_TREES_LAYER_TREE_HOST_CLIENT_H_ #define CC_TREES_LAYER_TREE_HOST_CLIENT_H_ +#include <memory> + #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; @@ -58,16 +57,10 @@ 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; - - // TODO(simonhong): Makes this to pure virtual function when client - // implementation is ready. - virtual void SendBeginFramesToChildren(const BeginFrameArgs& args) {} + virtual void ReportFixedRasterScaleUseCounters( + bool has_blurry_content, + bool has_potential_performance_regression) = 0; protected: virtual ~LayerTreeHostClient() {} diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc index 9485a644f32..8ed875c53f2 100644 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ b/chromium/cc/trees/layer_tree_host_common.cc @@ -8,6 +8,7 @@ #include <algorithm> +#include "base/containers/adapters.h" #include "base/trace_event/trace_event.h" #include "cc/base/math_util.h" #include "cc/layers/heads_up_display_layer_impl.h" @@ -81,8 +82,8 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( bool layers_always_allowed_lcd_text, bool can_render_to_separate_surface, bool can_adjust_raster_scales, + bool verify_clip_tree_calculations, LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id, PropertyTrees* property_trees) : root_layer(root_layer), device_viewport_size(device_viewport_size), @@ -100,17 +101,15 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( layers_always_allowed_lcd_text(layers_always_allowed_lcd_text), can_render_to_separate_surface(can_render_to_separate_surface), can_adjust_raster_scales(can_adjust_raster_scales), + verify_clip_tree_calculations(verify_clip_tree_calculations), render_surface_layer_list(render_surface_layer_list), - current_render_surface_layer_list_id( - current_render_surface_layer_list_id), property_trees(property_trees) {} LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id) + LayerImplList* render_surface_layer_list) : CalcDrawPropsImplInputs(root_layer, device_viewport_size, device_transform, @@ -126,8 +125,8 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: false, true, false, + true, render_surface_layer_list, - current_render_surface_layer_list_id, GetPropertyTrees(root_layer)) { DCHECK(root_layer); DCHECK(render_surface_layer_list); @@ -136,13 +135,11 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id) + LayerImplList* render_surface_layer_list) : CalcDrawPropsImplInputsForTesting(root_layer, device_viewport_size, gfx::Transform(), - render_surface_layer_list, - current_render_surface_layer_list_id) {} + render_surface_layer_list) {} bool LayerTreeHostCommon::ScrollUpdateInfo::operator==( const LayerTreeHostCommon::ScrollUpdateInfo& other) const { @@ -194,267 +191,42 @@ void ScrollAndScaleSet::FromProtobuf(const proto::ScrollAndScaleSet& proto) { top_controls_delta = proto.top_controls_delta(); } -inline gfx::Rect CalculateVisibleRectWithCachedLayerRect( - const gfx::Rect& target_surface_rect, - const gfx::Rect& layer_bound_rect, - const gfx::Rect& layer_rect_in_target_space, - const gfx::Transform& transform) { - if (layer_rect_in_target_space.IsEmpty()) - return gfx::Rect(); - - // Is this layer fully contained within the target surface? - if (target_surface_rect.Contains(layer_rect_in_target_space)) - return layer_bound_rect; - - // If the layer doesn't fill up the entire surface, then find the part of - // the surface rect where the layer could be visible. This avoids trying to - // project surface rect points that are behind the projection point. - gfx::Rect minimal_surface_rect = target_surface_rect; - minimal_surface_rect.Intersect(layer_rect_in_target_space); - - if (minimal_surface_rect.IsEmpty()) - return gfx::Rect(); - - // Project the corners of the target surface rect into the layer space. - // This bounding rectangle may be larger than it needs to be (being - // axis-aligned), but is a reasonable filter on the space to consider. - // Non-invertible transforms will create an empty rect here. - - gfx::Transform surface_to_layer(gfx::Transform::kSkipInitialization); - if (!transform.GetInverse(&surface_to_layer)) { - // Because we cannot use the surface bounds to determine what portion of - // the layer is visible, we must conservatively assume the full layer is - // visible. - return layer_bound_rect; +static inline void SetMaskLayersAreDrawnRenderSurfaceLayerListMembers( + LayerImpl* layer) { + if (layer->mask_layer()) + layer->mask_layer()->set_is_drawn_render_surface_layer_list_member(true); + if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { + layer->replica_layer() + ->mask_layer() + ->set_is_drawn_render_surface_layer_list_member(true); } - - gfx::Rect layer_rect = MathUtil::ProjectEnclosingClippedRect( - surface_to_layer, minimal_surface_rect); - layer_rect.Intersect(layer_bound_rect); - return layer_rect; -} - -gfx::Rect LayerTreeHostCommon::CalculateVisibleRect( - const gfx::Rect& target_surface_rect, - const gfx::Rect& layer_bound_rect, - const gfx::Transform& transform) { - gfx::Rect layer_in_surface_space = - MathUtil::MapEnclosingClippedRect(transform, layer_bound_rect); - return CalculateVisibleRectWithCachedLayerRect( - target_surface_rect, layer_bound_rect, layer_in_surface_space, transform); -} - -static inline bool IsRootLayer(const Layer* layer) { - return !layer->parent(); } -static inline bool IsRootLayer(const LayerImpl* layer) { - return layer->layer_tree_impl()->IsRootLayer(layer); -} - -template <typename LayerType> -static bool HasInvertibleOrAnimatedTransform(LayerType* layer) { - return layer->transform_is_invertible() || - layer->HasPotentiallyRunningTransformAnimation(); -} - -static inline void MarkLayerWithRenderSurfaceLayerListId( - LayerImpl* layer, - int current_render_surface_layer_list_id) { - layer->draw_properties().last_drawn_render_surface_layer_list_id = - current_render_surface_layer_list_id; - layer->set_layer_or_descendant_is_drawn( - !!current_render_surface_layer_list_id); -} - -static inline void MarkMasksWithRenderSurfaceLayerListId( - LayerImpl* layer, - int current_render_surface_layer_list_id) { - if (layer->mask_layer()) { - MarkLayerWithRenderSurfaceLayerListId(layer->mask_layer(), - current_render_surface_layer_list_id); - } +static inline void ClearLayerIsDrawnRenderSurfaceLayerListMember( + LayerImpl* layer) { + layer->set_is_drawn_render_surface_layer_list_member(false); + if (layer->mask_layer()) + layer->mask_layer()->set_is_drawn_render_surface_layer_list_member(false); if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { - MarkLayerWithRenderSurfaceLayerListId(layer->replica_layer()->mask_layer(), - current_render_surface_layer_list_id); + layer->replica_layer() + ->mask_layer() + ->set_is_drawn_render_surface_layer_list_member(false); } } -static inline void MarkLayerListWithRenderSurfaceLayerListId( +static inline void ClearIsDrawnRenderSurfaceLayerListMember( LayerImplList* layer_list, - int current_render_surface_layer_list_id) { - for (LayerImplList::iterator it = layer_list->begin(); - it != layer_list->end(); ++it) { - MarkLayerWithRenderSurfaceLayerListId(*it, - current_render_surface_layer_list_id); - MarkMasksWithRenderSurfaceLayerListId(*it, - current_render_surface_layer_list_id); - } -} - -static inline void RemoveSurfaceForEarlyExit( - LayerImpl* layer_to_remove, - LayerImplList* render_surface_layer_list) { - DCHECK(layer_to_remove->render_surface()); - // Technically, we know that the layer we want to remove should be - // at the back of the render_surface_layer_list. However, we have had - // bugs before that added unnecessary layers here - // (https://bugs.webkit.org/show_bug.cgi?id=74147), but that causes - // things to crash. So here we proactively remove any additional - // layers from the end of the list. - while (render_surface_layer_list->back() != layer_to_remove) { - MarkLayerListWithRenderSurfaceLayerListId( - &render_surface_layer_list->back()->render_surface()->layer_list(), 0); - MarkLayerWithRenderSurfaceLayerListId(render_surface_layer_list->back(), 0); - - render_surface_layer_list->back()->ClearRenderSurfaceLayerList(); - render_surface_layer_list->pop_back(); - } - DCHECK_EQ(render_surface_layer_list->back(), layer_to_remove); - MarkLayerListWithRenderSurfaceLayerListId( - &layer_to_remove->render_surface()->layer_list(), 0); - MarkLayerWithRenderSurfaceLayerListId(layer_to_remove, 0); - render_surface_layer_list->pop_back(); - layer_to_remove->ClearRenderSurfaceLayerList(); -} - -struct PreCalculateMetaInformationRecursiveData { - size_t num_unclipped_descendants; - int num_layer_or_descendants_with_copy_request; - int num_layer_or_descendants_with_touch_handler; - int num_descendants_that_draw_content; - - PreCalculateMetaInformationRecursiveData() - : num_unclipped_descendants(0), - num_layer_or_descendants_with_copy_request(0), - num_layer_or_descendants_with_touch_handler(0), - num_descendants_that_draw_content(0) {} - - void Merge(const PreCalculateMetaInformationRecursiveData& data) { - num_layer_or_descendants_with_copy_request += - data.num_layer_or_descendants_with_copy_request; - num_layer_or_descendants_with_touch_handler += - data.num_layer_or_descendants_with_touch_handler; - num_unclipped_descendants += data.num_unclipped_descendants; - num_descendants_that_draw_content += data.num_descendants_that_draw_content; - } -}; - -static bool IsMetaInformationRecomputationNeeded(Layer* layer) { - return layer->layer_tree_host()->needs_meta_info_recomputation(); -} - -static void UpdateMetaInformationSequenceNumber(Layer* root_layer) { - root_layer->layer_tree_host()->IncrementMetaInformationSequenceNumber(); -} - -// Recursively walks the layer tree(if needed) to compute any information -// that is needed before doing the main recursion. -static void PreCalculateMetaInformationInternal( - Layer* layer, - PreCalculateMetaInformationRecursiveData* recursive_data) { - if (!IsMetaInformationRecomputationNeeded(layer)) { - DCHECK(IsRootLayer(layer)); - return; - } - - if (layer->clip_parent()) - recursive_data->num_unclipped_descendants++; - - 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); - - PreCalculateMetaInformationRecursiveData data_for_child; - PreCalculateMetaInformationInternal(child_layer, &data_for_child); - recursive_data->Merge(data_for_child); - } - - if (layer->clip_children()) { - 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; - } - - if (layer->HasCopyRequest()) - recursive_data->num_layer_or_descendants_with_copy_request++; - - if (!layer->touch_event_handler_region().IsEmpty()) - recursive_data->num_layer_or_descendants_with_touch_handler++; - - layer->set_num_unclipped_descendants( - recursive_data->num_unclipped_descendants); - - if (IsRootLayer(layer)) - layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false); -} - -static void PreCalculateMetaInformationInternalForTesting( - LayerImpl* layer, - PreCalculateMetaInformationRecursiveData* recursive_data) { - if (layer->clip_parent()) - recursive_data->num_unclipped_descendants++; - - 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) { - LayerImpl* child_layer = layer->child_at(i); - - PreCalculateMetaInformationRecursiveData data_for_child; - PreCalculateMetaInformationInternalForTesting(child_layer, &data_for_child); - recursive_data->Merge(data_for_child); - } - - if (layer->clip_children()) { - 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; + ScrollTree* scroll_tree) { + for (LayerImpl* layer : *layer_list) { + if (layer->is_drawn_render_surface_layer_list_member()) { + DCHECK_GT(scroll_tree->Node(layer->scroll_tree_index()) + ->data.num_drawn_descendants, + 0); + scroll_tree->Node(layer->scroll_tree_index()) + ->data.num_drawn_descendants--; + } + ClearLayerIsDrawnRenderSurfaceLayerListMember(layer); } - - if (layer->HasCopyRequest()) - recursive_data->num_layer_or_descendants_with_copy_request++; - - if (!layer->touch_event_handler_region().IsEmpty()) - recursive_data->num_layer_or_descendants_with_touch_handler++; - - layer->draw_properties().num_unclipped_descendants = - recursive_data->num_unclipped_descendants; - layer->set_layer_or_descendant_has_touch_handler( - (recursive_data->num_layer_or_descendants_with_touch_handler != 0)); - // TODO(enne): this should be synced from the main thread, so is only - // for tests constructing layers on the compositor thread. - layer->SetNumDescendantsThatDrawContent( - recursive_data->num_descendants_that_draw_content); - - if (layer->DrawsContent()) - recursive_data->num_descendants_that_draw_content++; -} - -void LayerTreeHostCommon::PreCalculateMetaInformation(Layer* root_layer) { - PreCalculateMetaInformationRecursiveData recursive_data; - PreCalculateMetaInformationInternal(root_layer, &recursive_data); -} - -void LayerTreeHostCommon::PreCalculateMetaInformationForTesting( - LayerImpl* root_layer) { - PreCalculateMetaInformationRecursiveData recursive_data; - PreCalculateMetaInformationInternalForTesting(root_layer, &recursive_data); -} - -void LayerTreeHostCommon::PreCalculateMetaInformationForTesting( - Layer* root_layer) { - UpdateMetaInformationSequenceNumber(root_layer); - PreCalculateMetaInformationRecursiveData recursive_data; - PreCalculateMetaInformationInternal(root_layer, &recursive_data); } static bool CdpPerfTracingEnabled() { @@ -527,255 +299,202 @@ enum PropertyTreeOption { DONT_BUILD_PROPERTY_TREES }; -void CalculateRenderTarget(LayerImpl* layer, - PropertyTrees* property_trees, - bool subtree_visible_from_ancestor, - bool can_render_to_separate_surface) { - bool layer_is_drawn; - DCHECK_GE(layer->effect_tree_index(), 0); - layer_is_drawn = property_trees->effect_tree.Node(layer->effect_tree_index()) - ->data.is_drawn; - - // The root layer cannot be skipped. - if (!IsRootLayer(layer) && - draw_property_utils::LayerShouldBeSkipped(layer, layer_is_drawn, - property_trees->transform_tree, - property_trees->effect_tree)) { - layer->draw_properties().render_target = nullptr; - return; - } - - bool render_to_separate_surface = - IsRootLayer(layer) || - (can_render_to_separate_surface && layer->render_surface()); - - if (render_to_separate_surface) { - DCHECK(layer->render_surface()) << IsRootLayer(layer) - << can_render_to_separate_surface - << layer->has_render_surface(); - layer->draw_properties().render_target = layer; - - if (layer->mask_layer()) - layer->mask_layer()->draw_properties().render_target = layer; - - if (layer->replica_layer() && layer->replica_layer()->mask_layer()) - layer->replica_layer()->mask_layer()->draw_properties().render_target = - layer; - - } else { - DCHECK(!IsRootLayer(layer)); - layer->draw_properties().render_target = layer->parent()->render_target(); - } - for (size_t i = 0; i < layer->children().size(); ++i) { - CalculateRenderTarget( - LayerTreeHostCommon::get_layer_as_raw_ptr(layer->children(), i), - property_trees, layer_is_drawn, can_render_to_separate_surface); +static void ComputeLayerScrollsDrawnDescendants(LayerTreeImpl* layer_tree_impl, + ScrollTree* scroll_tree) { + for (int i = static_cast<int>(scroll_tree->size()) - 1; i > 0; --i) { + ScrollNode* node = scroll_tree->Node(i); + scroll_tree->parent(node)->data.num_drawn_descendants += + node->data.num_drawn_descendants; + } + for (LayerImpl* layer : *layer_tree_impl) { + bool scrolls_drawn_descendant = false; + if (layer->scrollable()) { + ScrollNode* node = scroll_tree->Node(layer->scroll_tree_index()); + if (node->data.num_drawn_descendants > 0) + scrolls_drawn_descendant = true; + } + layer->set_scrolls_drawn_descendant(scrolls_drawn_descendant); } } -void CalculateRenderSurfaceLayerList( - LayerImpl* layer, +static void ComputeInitialRenderSurfaceLayerList( + LayerTreeImpl* layer_tree_impl, PropertyTrees* property_trees, LayerImplList* render_surface_layer_list, - LayerImplList* descendants, - RenderSurfaceImpl* nearest_occlusion_immune_ancestor, - bool subtree_visible_from_ancestor, - const bool can_render_to_separate_surface, - const int current_render_surface_layer_list_id, - const int max_texture_size) { - // This calculates top level Render Surface Layer List, and Layer List for all - // Render Surfaces. - - // |layer| is current layer. - - // |render_surface_layer_list| is the top level RenderSurfaceLayerList. - - // |descendants| is used to determine what's in current layer's render - // surface's layer list. - - // |subtree_visible_from_ancestor| is set during recursion to affect current - // layer's subtree. - - // |can_render_to_separate_surface| and |current_render_surface_layer_list_id| - // are settings that should stay the same during recursion. - bool layer_is_drawn = false; - DCHECK_GE(layer->effect_tree_index(), 0); - layer_is_drawn = property_trees->effect_tree.Node(layer->effect_tree_index()) - ->data.is_drawn; - - // The root layer cannot be skipped. - if (!IsRootLayer(layer) && - draw_property_utils::LayerShouldBeSkipped(layer, layer_is_drawn, - property_trees->transform_tree, - property_trees->effect_tree)) { + bool can_render_to_separate_surface) { + ScrollTree* scroll_tree = &property_trees->scroll_tree; + for (int i = 0; i < static_cast<int>(scroll_tree->size()); ++i) + scroll_tree->Node(i)->data.num_drawn_descendants = 0; + + // Add all non-skipped surfaces to the initial render surface layer list. Add + // all non-skipped layers to the layer list of their target surface, and + // add their content rect to their target surface's accumulated content rect. + for (LayerImpl* layer : *layer_tree_impl) { if (layer->render_surface()) layer->ClearRenderSurfaceLayerList(); - layer->draw_properties().render_target = nullptr; - return; - } - - bool render_to_separate_surface = - IsRootLayer(layer) || - (can_render_to_separate_surface && layer->render_surface()); - - if (render_to_separate_surface) { - DCHECK(layer->render_surface()); - draw_property_utils::ComputeSurfaceDrawProperties(property_trees, - layer->render_surface()); - - - if (IsRootLayer(layer)) { - // The root surface does not contribute to any other surface, it has no - // target. - layer->render_surface()->set_contributes_to_drawn_surface(false); - } else { - bool contributes_to_drawn_surface = - property_trees->effect_tree.ContributesToDrawnSurface( - layer->effect_tree_index()); - layer->render_surface()->set_contributes_to_drawn_surface( - contributes_to_drawn_surface); - } - - // Ignore occlusion from outside the surface when surface contents need to - // be fully drawn. Layers with copy-request need to be complete. - // We could be smarter about layers with replica and exclude regions - // where both layer and the replica are occluded, but this seems like an - // overkill. The same is true for layers with filters that move pixels. - // TODO(senorblanco): make this smarter for the SkImageFilter case (check - // for pixel-moving filters) - if (layer->HasCopyRequest() || layer->has_replica() || - layer->filters().HasReferenceFilter() || - layer->filters().HasFilterThatMovesPixels()) { - nearest_occlusion_immune_ancestor = layer->render_surface(); - } - layer->render_surface()->SetNearestOcclusionImmuneAncestor( - nearest_occlusion_immune_ancestor); - layer->ClearRenderSurfaceLayerList(); - - render_surface_layer_list->push_back(layer); - - descendants = &(layer->render_surface()->layer_list()); - } - - size_t descendants_size = descendants->size(); - - bool layer_should_be_skipped = !draw_property_utils::LayerNeedsUpdate( - layer, layer_is_drawn, property_trees->transform_tree); - if (!layer_should_be_skipped) { - MarkLayerWithRenderSurfaceLayerListId(layer, - current_render_surface_layer_list_id); - descendants->push_back(layer); - } + ClearLayerIsDrawnRenderSurfaceLayerListMember(layer); + + bool layer_is_drawn = + property_trees->effect_tree.Node(layer->effect_tree_index()) + ->data.is_drawn; + bool is_root = layer_tree_impl->IsRootLayer(layer); + bool skip_layer = + !is_root && draw_property_utils::LayerShouldBeSkipped( + layer, layer_is_drawn, property_trees->transform_tree, + property_trees->effect_tree); + if (skip_layer) + continue; + + bool render_to_separate_surface = + is_root || (can_render_to_separate_surface && layer->render_surface()); + if (render_to_separate_surface) { + DCHECK(layer->render_surface()); + DCHECK(layer->render_target() == layer->render_surface()); + RenderSurfaceImpl* surface = layer->render_surface(); + surface->ClearAccumulatedContentRect(); + render_surface_layer_list->push_back(layer); + if (is_root) { + // The root surface does not contribute to any other surface, it has no + // target. + layer->render_surface()->set_contributes_to_drawn_surface(false); + } else { + surface->render_target()->layer_list().push_back(layer); + bool contributes_to_drawn_surface = + property_trees->effect_tree.ContributesToDrawnSurface( + layer->effect_tree_index()); + layer->render_surface()->set_contributes_to_drawn_surface( + contributes_to_drawn_surface); + } - // Clear the old accumulated content rect of surface. - if (render_to_separate_surface) - layer->render_surface()->SetAccumulatedContentRect(gfx::Rect()); - - for (auto* child_layer : layer->children()) { - CalculateRenderSurfaceLayerList( - child_layer, property_trees, render_surface_layer_list, descendants, - nearest_occlusion_immune_ancestor, layer_is_drawn, - can_render_to_separate_surface, current_render_surface_layer_list_id, - max_texture_size); - - // If the child is its own render target, then it has a render surface. - if (child_layer->render_target() == child_layer && - !child_layer->render_surface()->layer_list().empty() && - !child_layer->render_surface()->content_rect().IsEmpty()) { - // This child will contribute its render surface, which means - // we need to mark just the mask layer (and replica mask layer) - // with the id. - MarkMasksWithRenderSurfaceLayerListId( - child_layer, current_render_surface_layer_list_id); - descendants->push_back(child_layer); + draw_property_utils::ComputeSurfaceDrawProperties(property_trees, + surface); + + // Ignore occlusion from outside the surface when surface contents need to + // be fully drawn. Layers with copy-request need to be complete. We could + // be smarter about layers with replica and exclude regions where both + // layer and the replica are occluded, but this seems like overkill. The + // same is true for layers with filters that move pixels. + // TODO(senorblanco): make this smarter for the SkImageFilter case (check + // for pixel-moving filters) + bool is_occlusion_immune = layer->HasCopyRequest() || + layer->has_replica() || + layer->filters().HasReferenceFilter() || + layer->filters().HasFilterThatMovesPixels(); + if (is_occlusion_immune) { + surface->SetNearestOcclusionImmuneAncestor(surface); + } else if (is_root) { + surface->SetNearestOcclusionImmuneAncestor(nullptr); + } else { + surface->SetNearestOcclusionImmuneAncestor( + surface->render_target()->nearest_occlusion_immune_ancestor()); + } } - - if (child_layer->layer_or_descendant_is_drawn()) { - bool layer_or_descendant_is_drawn = true; - layer->set_layer_or_descendant_is_drawn(layer_or_descendant_is_drawn); + bool layer_should_be_drawn = draw_property_utils::LayerNeedsUpdate( + layer, layer_is_drawn, property_trees->transform_tree); + if (!layer_should_be_drawn) + continue; + + layer->set_is_drawn_render_surface_layer_list_member(true); + scroll_tree->Node(layer->scroll_tree_index())->data.num_drawn_descendants++; + layer->render_target()->layer_list().push_back(layer); + + // The layer contributes its drawable content rect to its render target. + layer->render_target()->AccumulateContentRectFromContributingLayer(layer); + } +} + +static void ComputeSurfaceContentRects(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + LayerImplList* render_surface_layer_list, + int max_texture_size) { + // Walk the list backwards, accumulating each surface's content rect into its + // target's content rect. + for (LayerImpl* layer : base::Reversed(*render_surface_layer_list)) { + if (layer_tree_impl->IsRootLayer(layer)) { + // The root layer's surface content rect is always the entire viewport. + layer->render_surface()->SetContentRectToViewport(); + continue; } - } - - if (render_to_separate_surface && !IsRootLayer(layer) && - layer->render_surface()->layer_list().empty()) { - RemoveSurfaceForEarlyExit(layer, render_surface_layer_list); - return; - } - - // The render surface's content rect is the union of drawable content rects - // of the layers that draw into the surface. If the render surface is clipped, - // it is also intersected with the render's surface clip rect. - if (!IsRootLayer(layer)) { - if (render_to_separate_surface) { - gfx::Rect surface_content_rect = - layer->render_surface()->accumulated_content_rect(); - // If the owning layer of a render surface draws content, the content - // rect of the render surface is expanded to include the drawable - // content rect of the layer. - if (layer->DrawsContent()) - surface_content_rect.Union(layer->drawable_content_rect()); - - if (!layer->replica_layer() && !layer->HasCopyRequest() && - layer->render_surface()->is_clipped()) { - // Here, we clip the render surface's content rect with its clip rect. - // As the clip rect of render surface is in the surface's target - // space, we first map the content rect into the target space, - // intersect it with clip rect and project back the result to the - // surface space. - if (!surface_content_rect.IsEmpty()) { - gfx::Rect surface_clip_rect = - LayerTreeHostCommon::CalculateVisibleRect( - layer->render_surface()->clip_rect(), surface_content_rect, - layer->render_surface()->draw_transform()); - surface_content_rect.Intersect(surface_clip_rect); + RenderSurfaceImpl* surface = layer->render_surface(); + // Now all contributing drawable content rect has been accumulated to this + // render surface, calculate the content rect. + surface->CalculateContentRectFromAccumulatedContentRect(max_texture_size); + + // Now the render surface's content rect is calculated correctly, it could + // contribute to its render target. + surface->render_target() + ->AccumulateContentRectFromContributingRenderSurface(surface); + } +} + +static void ComputeListOfNonEmptySurfaces(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + LayerImplList* initial_surface_list, + LayerImplList* final_surface_list) { + // Walk the initial surface list forwards. The root surface and each + // surface with a non-empty content rect go into the final render surface + // layer list. Surfaces with empty content rects or whose target isn't in + // the final list do not get added to the final list. + for (LayerImpl* layer : *initial_surface_list) { + bool is_root = layer_tree_impl->IsRootLayer(layer); + RenderSurfaceImpl* surface = layer->render_surface(); + RenderSurfaceImpl* target_surface = surface->render_target(); + if (!is_root && (surface->content_rect().IsEmpty() || + target_surface->layer_list().empty())) { + ClearIsDrawnRenderSurfaceLayerListMember(&surface->layer_list(), + &property_trees->scroll_tree); + surface->ClearLayerLists(); + if (!is_root) { + LayerImplList& target_list = target_surface->layer_list(); + auto it = std::find(target_list.begin(), target_list.end(), layer); + if (it != target_list.end()) { + target_list.erase(it); + // This surface has an empty content rect. If its target's layer list + // had no other layers, then its target would also have had an empty + // content rect, meaning it would have been removed and had its layer + // list cleared when we visited it, unless the target surface is the + // root surface. + DCHECK(!target_surface->layer_list().empty() || + target_surface->render_target() == target_surface); + } else { + // This layer was removed when the target itself was cleared. + DCHECK(target_surface->layer_list().empty()); } } - // The RenderSurfaceImpl backing texture cannot exceed the maximum - // supported texture size. - surface_content_rect.set_width( - std::min(surface_content_rect.width(), max_texture_size)); - surface_content_rect.set_height( - std::min(surface_content_rect.height(), max_texture_size)); - layer->render_surface()->SetContentRect(surface_content_rect); + continue; } - const LayerImpl* parent_target = layer->parent()->render_target(); - if (!IsRootLayer(parent_target)) { - gfx::Rect surface_content_rect = - parent_target->render_surface()->accumulated_content_rect(); - if (render_to_separate_surface) { - // If the layer owns a surface, then the content rect is in the wrong - // space. Instead, we will use the surface's DrawableContentRect which - // is in target space as required. We also need to clip it with the - // target's clip if the target is clipped. - surface_content_rect.Union(gfx::ToEnclosedRect( - layer->render_surface()->DrawableContentRect())); - if (parent_target->is_clipped()) - surface_content_rect.Intersect(parent_target->clip_rect()); - } else if (layer->DrawsContent()) { - surface_content_rect.Union(layer->drawable_content_rect()); - } - parent_target->render_surface()->SetAccumulatedContentRect( - surface_content_rect); - } - } else { - // The root layer's surface content rect is always the entire viewport. - gfx::Rect viewport = - gfx::ToEnclosingRect(property_trees->clip_tree.ViewportClip()); - layer->render_surface()->SetContentRect(viewport); + SetMaskLayersAreDrawnRenderSurfaceLayerListMembers(layer); + final_surface_list->push_back(layer); } +} - if (render_to_separate_surface && !IsRootLayer(layer) && - layer->render_surface()->DrawableContentRect().IsEmpty()) { - RemoveSurfaceForEarlyExit(layer, render_surface_layer_list); - return; - } +static void CalculateRenderSurfaceLayerList( + LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + LayerImplList* render_surface_layer_list, + const bool can_render_to_separate_surface, + const int max_texture_size) { + // This calculates top level Render Surface Layer List, and Layer List for all + // Render Surfaces. + // |render_surface_layer_list| is the top level RenderSurfaceLayerList. - // If neither this layer nor any of its children were added, early out. - if (descendants_size == descendants->size()) { - DCHECK(!render_to_separate_surface || IsRootLayer(layer)); - return; - } + LayerImplList initial_render_surface_list; + + // First compute an RSLL that might include surfaces that later turn out to + // have an empty content rect. After surface content rects are computed, + // produce a final RSLL that omits empty surfaces. + ComputeInitialRenderSurfaceLayerList(layer_tree_impl, property_trees, + &initial_render_surface_list, + can_render_to_separate_surface); + ComputeSurfaceContentRects(layer_tree_impl, property_trees, + &initial_render_surface_list, max_texture_size); + ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, + &initial_render_surface_list, + render_surface_layer_list); + + ComputeLayerScrollsDrawnDescendants(layer_tree_impl, + &property_trees->scroll_tree); } static void ComputeMaskLayerDrawProperties(const LayerImpl* layer, @@ -874,12 +593,6 @@ void CalculateDrawPropertiesInternal( DCHECK(inputs->can_render_to_separate_surface == inputs->property_trees->non_root_surfaces_enabled); - const bool subtree_visible_from_ancestor = true; - for (auto* layer : *inputs->root_layer->layer_tree_impl()) - layer->draw_properties().render_target = nullptr; - CalculateRenderTarget(inputs->root_layer, inputs->property_trees, - subtree_visible_from_ancestor, - inputs->can_render_to_separate_surface); for (LayerImpl* layer : visible_layer_list) { draw_property_utils::ComputeLayerDrawProperties( layer, inputs->property_trees, inputs->layers_always_allowed_lcd_text, @@ -892,14 +605,14 @@ void CalculateDrawPropertiesInternal( ComputeMaskLayerDrawProperties(layer, replica_mask_layer); } - DCHECK_EQ( - inputs->current_render_surface_layer_list_id, - inputs->root_layer->layer_tree_impl()->current_render_surface_list_id()); CalculateRenderSurfaceLayerList( - inputs->root_layer, inputs->property_trees, - inputs->render_surface_layer_list, nullptr, nullptr, - subtree_visible_from_ancestor, inputs->can_render_to_separate_surface, - inputs->current_render_surface_layer_list_id, inputs->max_texture_size); + inputs->root_layer->layer_tree_impl(), inputs->property_trees, + inputs->render_surface_layer_list, inputs->can_render_to_separate_surface, + inputs->max_texture_size); + + if (inputs->verify_clip_tree_calculations) + draw_property_utils::VerifyClipTreeCalculations(visible_layer_list, + inputs->property_trees); if (should_measure_property_tree_performance) { TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), @@ -926,7 +639,6 @@ void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( inputs->page_scale_factor, inputs->device_scale_factor, gfx::Rect(inputs->device_viewport_size), inputs->device_transform, property_trees); - draw_property_utils::UpdateRenderSurfaces(inputs->root_layer, property_trees); draw_property_utils::UpdatePropertyTrees(property_trees, can_render_to_separate_surface); draw_property_utils::FindLayersThatNeedUpdates( @@ -983,11 +695,10 @@ void LayerTreeHostCommon::CalculateDrawProperties( } } -void LayerTreeHostCommon::CalculateDrawProperties( +void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( CalcDrawPropsImplInputsForTesting* inputs) { - PreCalculateMetaInformationRecursiveData recursive_data; - PreCalculateMetaInformationInternalForTesting(inputs->root_layer, - &recursive_data); + PropertyTreeBuilder::PreCalculateMetaInformationForTesting( + inputs->root_layer); CalculateDrawPropertiesInternal(inputs, BUILD_PROPERTY_TREES_IF_NEEDED); } diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h index fa1e6005279..c000e279d70 100644 --- a/chromium/cc/trees/layer_tree_host_common.h +++ b/chromium/cc/trees/layer_tree_host_common.h @@ -36,19 +36,8 @@ class Layer; class SwapPromise; class PropertyTrees; -enum CallFunctionLayerType : uint32_t { - BASIC_LAYER = 0, - MASK_LAYER = 1, - REPLICA_LAYER = 2, - ALL_LAYERS = MASK_LAYER | REPLICA_LAYER -}; - class CC_EXPORT LayerTreeHostCommon { public: - static gfx::Rect CalculateVisibleRect(const gfx::Rect& target_surface_rect, - const gfx::Rect& layer_bound_rect, - const gfx::Transform& transform); - struct CC_EXPORT CalcDrawPropsMainInputsForTesting { public: CalcDrawPropsMainInputsForTesting(Layer* root_layer, @@ -92,8 +81,8 @@ class CC_EXPORT LayerTreeHostCommon { bool layers_always_allowed_lcd_text, bool can_render_to_separate_surface, bool can_adjust_raster_scales, + bool verify_clip_tree_calculations, LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id, PropertyTrees* property_trees); LayerImpl* root_layer; @@ -111,8 +100,8 @@ class CC_EXPORT LayerTreeHostCommon { bool layers_always_allowed_lcd_text; bool can_render_to_separate_surface; bool can_adjust_raster_scales; + bool verify_clip_tree_calculations; LayerImplList* render_surface_layer_list; - int current_render_surface_layer_list_id; PropertyTrees* property_trees; }; @@ -121,47 +110,27 @@ class CC_EXPORT LayerTreeHostCommon { CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id); + LayerImplList* render_surface_layer_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id); + LayerImplList* render_surface_layer_list); }; static int CalculateLayerJitter(LayerImpl* scrolling_layer); static void CalculateDrawPropertiesForTesting( CalcDrawPropsMainInputsForTesting* inputs); - static void PreCalculateMetaInformation(Layer* root_layer); - static void PreCalculateMetaInformationForTesting(LayerImpl* root_layer); - static void PreCalculateMetaInformationForTesting(Layer* root_layer); static void CalculateDrawProperties(CalcDrawPropsImplInputs* inputs); - static void CalculateDrawProperties( + static void CalculateDrawPropertiesForTesting( CalcDrawPropsImplInputsForTesting* inputs); - template <typename LayerType> - static bool RenderSurfaceContributesToTarget(LayerType*, - int target_surface_layer_id); - template <typename Function> static void CallFunctionForEveryLayer(LayerTreeHost* layer, - const Function& function, - const CallFunctionLayerType& type); + const Function& function); template <typename Function> static void CallFunctionForEveryLayer(LayerTreeImpl* layer, - const Function& function, - const CallFunctionLayerType& type); - - static Layer* get_layer_as_raw_ptr(const LayerList& layers, size_t index) { - return layers[index].get(); - } - - static LayerImpl* get_layer_as_raw_ptr(const LayerImplList& layers, - size_t index) { - return layers[index]; - } + const Function& function); struct CC_EXPORT ScrollUpdateInfo { int layer_id; @@ -184,7 +153,7 @@ struct CC_EXPORT ScrollAndScaleSet { float page_scale_delta; gfx::Vector2dF elastic_overscroll_delta; float top_controls_delta; - std::vector<scoped_ptr<SwapPromise>> swap_promises; + std::vector<std::unique_ptr<SwapPromise>> swap_promises; bool EqualsForTesting(const ScrollAndScaleSet& other) const; void ToProtobuf(proto::ScrollAndScaleSet* proto) const; @@ -194,69 +163,31 @@ struct CC_EXPORT ScrollAndScaleSet { DISALLOW_COPY_AND_ASSIGN(ScrollAndScaleSet); }; -template <typename LayerType> -bool LayerTreeHostCommon::RenderSurfaceContributesToTarget( - LayerType* layer, - int target_surface_layer_id) { - // A layer will either contribute its own content, or its render surface's - // content, to the target surface. The layer contributes its surface's content - // when both the following are true: - // (1) The layer actually has a render surface and rendering into that - // surface, and - // (2) The layer's render surface is not the same as the target surface. - // - // Otherwise, the layer just contributes itself to the target surface. - - return layer->render_target() == layer && - layer->id() != target_surface_layer_id; -} - template <typename LayerType, typename Function> -static void CallFunctionForLayer(LayerType* layer, - const Function& function, - const CallFunctionLayerType& type) { +static void CallFunctionForLayer(LayerType* layer, const Function& function) { function(layer); - LayerType* mask_layer = layer->mask_layer(); - if ((type & CallFunctionLayerType::MASK_LAYER) && mask_layer) + if (LayerType* mask_layer = layer->mask_layer()) function(mask_layer); - LayerType* replica_layer = layer->replica_layer(); - if ((type & CallFunctionLayerType::REPLICA_LAYER) && replica_layer) { + if (LayerType* replica_layer = layer->replica_layer()) { function(replica_layer); - mask_layer = replica_layer->mask_layer(); - if ((type & CallFunctionLayerType::MASK_LAYER) && mask_layer) + if (LayerType* mask_layer = replica_layer->mask_layer()) function(mask_layer); } } template <typename Function> -static void CallFunctionForEveryLayerInternal( - Layer* layer, - const Function& function, - const CallFunctionLayerType& type) { - CallFunctionForLayer(layer, function, type); - - for (size_t i = 0; i < layer->children().size(); ++i) { - CallFunctionForEveryLayerInternal(layer->children()[i].get(), function, - type); - } -} - -template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer( - LayerTreeHost* host, - const Function& function, - const CallFunctionLayerType& type) { - CallFunctionForEveryLayerInternal(host->root_layer(), function, type); +void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeHost* host, + const Function& function) { + for (auto* layer : *host) + CallFunctionForLayer(layer, function); } template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer( - LayerTreeImpl* host_impl, - const Function& function, - const CallFunctionLayerType& type) { +void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeImpl* host_impl, + const Function& function) { for (auto* layer : *host_impl) - CallFunctionForLayer(layer, function, type); + CallFunctionForLayer(layer, function); } CC_EXPORT PropertyTrees* GetPropertyTrees(Layer* layer); diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc index 3b6176814af..68fd82dfe9b 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc @@ -2,16 +2,14 @@ // 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_common.h" - #include <stddef.h> #include <deque> +#include <memory> #include <sstream> #include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/memory/scoped_ptr.h" #include "base/path_service.h" #include "base/strings/string_piece.h" #include "base/threading/thread.h" @@ -26,6 +24,7 @@ #include "cc/test/layer_tree_json_parser.h" #include "cc/test/layer_tree_test.h" #include "cc/test/paths.h" +#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "testing/perf/perf_test.h" @@ -108,7 +107,6 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { LayerTreeImpl* active_tree, LayerTreeHostImpl* host_impl) { LayerImplList update_list; - active_tree->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( active_tree->root_layer(), active_tree->DrawViewportSize(), host_impl->DrawTransform(), active_tree->device_scale_factor(), @@ -122,8 +120,8 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { host_impl->settings().layers_always_allowed_lcd_text, can_render_to_separate_surface, host_impl->settings().layer_transforms_should_scale_layer_contents, - &update_list, active_tree->current_render_surface_list_id(), - active_tree->property_trees()); + false, // do not verify_clip_tree_calculation for perf tests + &update_list, active_tree->property_trees()); LayerTreeHostCommon::CalculateDrawProperties(&inputs); } }; @@ -154,18 +152,18 @@ class BspTreePerfTest : public CalcDrawPropsTest { BuildLayerImplList(active_tree->root_layer(), &base_list); int polygon_counter = 0; - std::vector<scoped_ptr<DrawPolygon>> polygon_list; + std::vector<std::unique_ptr<DrawPolygon>> polygon_list; for (LayerImplList::iterator it = base_list.begin(); it != base_list.end(); ++it) { DrawPolygon* draw_polygon = new DrawPolygon( NULL, gfx::RectF(gfx::SizeF((*it)->bounds())), (*it)->draw_properties().target_space_transform, polygon_counter++); - polygon_list.push_back(scoped_ptr<DrawPolygon>(draw_polygon)); + polygon_list.push_back(std::unique_ptr<DrawPolygon>(draw_polygon)); } timer_.Reset(); do { - std::deque<scoped_ptr<DrawPolygon>> test_list; + std::deque<std::unique_ptr<DrawPolygon>> test_list; for (int i = 0; i < num_duplicates_; i++) { for (size_t i = 0; i < polygon_list.size(); i++) { test_list.push_back(polygon_list[i]->CreateCopy()); @@ -179,12 +177,10 @@ class BspTreePerfTest : public CalcDrawPropsTest { } void BuildLayerImplList(LayerImpl* layer, LayerImplList* list) { - if (layer->Is3dSorted() && !layer->bounds().IsEmpty()) { - list->push_back(layer); - } - - for (size_t i = 0; i < layer->children().size(); i++) { - BuildLayerImplList(layer->children()[i], list); + for (auto* layer_impl : *layer->layer_tree_impl()) { + if (layer_impl->Is3dSorted() && !layer_impl->bounds().IsEmpty()) { + list->push_back(layer_impl); + } } } diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc index 99b54737886..df445f61f59 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc @@ -7,14 +7,15 @@ #include <stddef.h> #include <algorithm> +#include <memory> #include <set> #include <vector> +#include "base/memory/ptr_util.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" #include "cc/animation/animation_player.h" #include "cc/animation/keyframed_animation_curve.h" -#include "cc/animation/layer_animation_controller.h" #include "cc/animation/transform_operations.h" #include "cc/base/math_util.h" #include "cc/input/main_thread_scrolling_reason.h" @@ -102,6 +103,41 @@ class LayerTreeHostCommonScalingTest : public LayerTreeHostCommonTest { : LayerTreeHostCommonTest(LayerTreeSettingsScaleContent()) {} }; +class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { + public: + LayerTreeHostCommonDrawRectsTest() : LayerTreeHostCommonTest() {} + + LayerImpl* TestVisibleRectAndDrawableContentRect( + const gfx::Rect& target_rect, + const gfx::Transform& layer_transform, + const gfx::Rect& layer_rect) { + LayerImpl* root = root_layer(); + LayerImpl* target = AddChild<LayerImpl>(root); + LayerImpl* drawing_layer = AddChild<LayerImpl>(target); + + root->SetDrawsContent(true); + target->SetDrawsContent(true); + target->SetMasksToBounds(true); + drawing_layer->SetDrawsContent(true); + + gfx::Transform identity; + + SetLayerPropertiesForTesting(root, identity, gfx::Point3F(), gfx::PointF(), + gfx::Size(500, 500), true, false, true); + SetLayerPropertiesForTesting(target, identity, gfx::Point3F(), + gfx::PointF(target_rect.origin()), + target_rect.size(), true, false, true); + SetLayerPropertiesForTesting(drawing_layer, layer_transform, gfx::Point3F(), + gfx::PointF(layer_rect.origin()), + layer_rect.size(), true, false, false); + + host_impl()->active_tree()->property_trees()->needs_rebuild = true; + ExecuteCalculateDrawProperties(root); + + return drawing_layer; + } +}; + TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { // Sanity check: For layers positioned at zero, with zero size, // and with identity transforms, then the draw transform, @@ -266,7 +302,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { &task_graph_runner); gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> sublayer_scoped_ptr( + std::unique_ptr<LayerImpl> sublayer_scoped_ptr( LayerImpl::Create(host_impl.active_tree(), 1)); LayerImpl* sublayer = sublayer_scoped_ptr.get(); sublayer->SetDrawsContent(true); @@ -274,13 +310,13 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { gfx::PointF(), gfx::Size(500, 500), true, false, false); - scoped_ptr<LayerImpl> scroll_layer_scoped_ptr( + std::unique_ptr<LayerImpl> scroll_layer_scoped_ptr( LayerImpl::Create(host_impl.active_tree(), 2)); LayerImpl* scroll_layer = scroll_layer_scoped_ptr.get(); SetLayerPropertiesForTesting(scroll_layer, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(10, 20), true, false, false); - scoped_ptr<LayerImpl> clip_layer_scoped_ptr( + std::unique_ptr<LayerImpl> clip_layer_scoped_ptr( LayerImpl::Create(host_impl.active_tree(), 4)); LayerImpl* clip_layer = clip_layer_scoped_ptr.get(); @@ -299,7 +335,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer_raw_ptr->id(), kScrollOffset); - scoped_ptr<LayerImpl> root(LayerImpl::Create(host_impl.active_tree(), 3)); + std::unique_ptr<LayerImpl> root( + LayerImpl::Create(host_impl.active_tree(), 3)); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(3, 4), true, false, false); @@ -460,35 +497,6 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { draw_property_utils::ScreenSpaceTransform(grand_child, tree)); } -// Render target should get cleared when subtree is skipped. -TEST_F(LayerTreeHostCommonTest, ClearRenderTargetForSkippedLayers) { - LayerImpl* root = root_layer(); - LayerImpl* parent = AddChildToRoot<LayerImpl>(); - LayerImpl* child = AddChild<LayerImpl>(parent); - child->SetDrawsContent(true); - - gfx::Transform identity_matrix; - SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(1, 2), true, false, - true); - SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(1, 2), true, false, - true); - SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(1, 2), true, false, - false); - - ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(parent->render_surface()); - EXPECT_EQ(parent, child->render_target()); - - // child is skipped when root's opacity is set to 0. So, its render target - // should be reset. - root->OnOpacityAnimated(0.0f); - ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(child->render_target()); -} - TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { LayerImpl* root = root_layer(); LayerImpl* parent = AddChildToRoot<LayerImpl>(); @@ -535,7 +543,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { // Render surface should have been created now. ASSERT_TRUE(child->render_surface()); - ASSERT_EQ(child, child->render_target()); + ASSERT_EQ(child->render_surface(), child->render_target()); // The child layer's draw transform should refer to its new render surface. // The screen-space transform, however, should still refer to the root. @@ -547,15 +555,14 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { // Because the grand_child is the only drawable content, the child's render // surface will tighten its bounds to the grand_child. The scale at which the // surface's subtree is drawn must be removed from the composite transform. - EXPECT_TRANSFORMATION_MATRIX_EQ( - surface_sublayer_composite_transform, - child->render_target()->render_surface()->draw_transform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(surface_sublayer_composite_transform, + child->render_target()->draw_transform()); // The screen space is the same as the target since the child surface draws // into the root. EXPECT_TRANSFORMATION_MATRIX_EQ( surface_sublayer_composite_transform, - child->render_target()->render_surface()->screen_space_transform()); + child->render_target()->screen_space_transform()); } TEST_F(LayerTreeHostCommonTest, TransformsWhenCannotRenderToSeparateSurface) { @@ -619,7 +626,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForReplica) { LayerImpl* child = AddChild<LayerImpl>(parent); LayerImpl* grand_child = AddChild<LayerImpl>(child); grand_child->SetDrawsContent(true); - scoped_ptr<LayerImpl> child_replica = + std::unique_ptr<LayerImpl> child_replica = LayerImpl::Create(host_impl()->active_tree(), 100); // One-time setup of root layer @@ -671,14 +678,13 @@ TEST_F(LayerTreeHostCommonTest, TransformsForReplica) { // Render surface should have been created now. ASSERT_TRUE(child->render_surface()); - ASSERT_EQ(child, child->render_target()); + ASSERT_EQ(child->render_surface(), child->render_target()); EXPECT_TRANSFORMATION_MATRIX_EQ( replica_composite_transform, - child->render_target()->render_surface()->replica_draw_transform()); + child->render_target()->replica_draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(replica_composite_transform, child->render_target() - ->render_surface() ->replica_screen_space_transform()); } @@ -716,9 +722,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { LayerImpl* grand_child_of_rs2 = AddChild<LayerImpl>(child_of_rs2); grand_child_of_rs2->SetDrawsContent(true); - scoped_ptr<LayerImpl> replica_of_rs1 = + std::unique_ptr<LayerImpl> replica_of_rs1 = LayerImpl::Create(host_impl()->active_tree(), 101); - scoped_ptr<LayerImpl> replica_of_rs2 = + std::unique_ptr<LayerImpl> replica_of_rs2 = LayerImpl::Create(host_impl()->active_tree(), 102); // In combination with descendant draws content, opacity != 1 forces the layer @@ -827,17 +833,21 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { ASSERT_FALSE(grand_child_of_rs2->render_surface()); // Verify all render target accessors - EXPECT_EQ(root, parent->render_target()); - EXPECT_EQ(root, child_of_root->render_target()); - EXPECT_EQ(root, grand_child_of_root->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, render_surface2->render_target()); - EXPECT_EQ(render_surface2, child_of_rs2->render_target()); - EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target()); + EXPECT_EQ(root->render_surface(), parent->render_target()); + EXPECT_EQ(root->render_surface(), child_of_root->render_target()); + EXPECT_EQ(root->render_surface(), grand_child_of_root->render_target()); + + EXPECT_EQ(render_surface1->render_surface(), + render_surface1->render_target()); + EXPECT_EQ(render_surface1->render_surface(), child_of_rs1->render_target()); + EXPECT_EQ(render_surface1->render_surface(), + grand_child_of_rs1->render_target()); + + EXPECT_EQ(render_surface2->render_surface(), + render_surface2->render_target()); + EXPECT_EQ(render_surface2->render_surface(), child_of_rs2->render_target()); + EXPECT_EQ(render_surface2->render_surface(), + grand_child_of_rs2->render_target()); // Verify layer draw transforms note that draw transforms are described with // respect to the nearest ancestor render surface but screen space transforms @@ -958,10 +968,10 @@ TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) { true, false, false); // No layers in this test should preserve 3d. - ASSERT_TRUE(root->should_flatten_transform()); - ASSERT_TRUE(child->should_flatten_transform()); - ASSERT_TRUE(grand_child->should_flatten_transform()); - ASSERT_TRUE(great_grand_child->should_flatten_transform()); + ASSERT_TRUE(root->test_properties()->should_flatten_transform); + ASSERT_TRUE(child->test_properties()->should_flatten_transform); + ASSERT_TRUE(grand_child->test_properties()->should_flatten_transform); + ASSERT_TRUE(great_grand_child->test_properties()->should_flatten_transform); gfx::Transform expected_child_draw_transform = rotation_about_y_axis; gfx::Transform expected_child_screen_space_transform = rotation_about_y_axis; @@ -1022,7 +1032,7 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, false, false); - grand_child->SetShouldFlattenTransform(false); + grand_child->test_properties()->should_flatten_transform = false; grand_child->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); @@ -1098,13 +1108,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { // render_surface will have a sublayer scale because of device scale factor. float device_scale_factor = 2.0f; LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.device_scale_factor = device_scale_factor; inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // Between grand_child and render_surface, we translate by (10, 10) and scale // by a factor of 2. @@ -1135,12 +1143,10 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { translate.Translate(50, 50); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); 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()); @@ -1150,12 +1156,10 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { scale.Scale(2, 2); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), scale, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), scale, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); 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()); @@ -1165,12 +1169,10 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { rotate.Rotate(2); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), rotate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), rotate, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); 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()); @@ -1182,12 +1184,10 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { composite.ConcatTransform(rotate); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), composite, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(composite, root->draw_properties().target_space_transform); EXPECT_EQ(composite, child->draw_properties().target_space_transform); EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); @@ -1198,13 +1198,11 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.device_scale_factor = device_scale_factor; inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); gfx::Transform device_scaled_translate = translate; device_scaled_translate.Scale(device_scale_factor, device_scale_factor); EXPECT_EQ(device_scaled_translate, @@ -1219,14 +1217,12 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = root; inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); gfx::Transform page_scaled_translate = translate; page_scaled_translate.Scale(page_scale_factor, page_scale_factor); EXPECT_EQ(page_scaled_translate, @@ -1241,12 +1237,10 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), composite, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); gfx::Transform compositeSquared = composite; compositeSquared.ConcatTransform(composite); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1303,12 +1297,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { render_surface1->SetOpacity(0.f); LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - parent, parent->bounds(), &render_surface_layer_list, - parent->layer_tree_impl()->current_render_surface_list_id()); + parent, parent->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // Since the layer is transparent, render_surface1->render_surface() should // not have gotten added anywhere. Also, the drawable content rect should not @@ -1346,12 +1338,10 @@ TEST_F(LayerTreeHostCommonTest, { LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - parent, parent->bounds(), &render_surface_layer_list, - parent->layer_tree_impl()->current_render_surface_list_id()); + parent, parent->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(2U, render_surface_layer_list.size()); } // The layer is fully transparent, but has a background filter, so it @@ -1368,18 +1358,18 @@ TEST_F(LayerTreeHostCommonTest, // When parent is transparent, the layer should not be drawn. parent->OnOpacityAnimated(0.f); render_surface1->OnOpacityAnimated(1.f); + render_surface1->set_visible_layer_rect(gfx::Rect()); { LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - parent, parent->bounds(), &render_surface_layer_list, - parent->layer_tree_impl()->current_render_surface_list_id()); + parent, parent->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } node = effect_tree.Node(render_surface1->effect_tree_index()); EXPECT_FALSE(node->data.is_drawn); + EXPECT_EQ(gfx::Rect(), render_surface1->visible_layer_rect()); } TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForFilter) { @@ -1409,12 +1399,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForFilter) { parent->SetFilters(filters); LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(parent->render_surface()); EXPECT_EQ(2U, parent->render_surface()->layer_list().size()); @@ -1580,7 +1568,7 @@ TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { gfx::PointF(), gfx::Size(10, 10), true, false); child->SetDrawsContent(true); - render_surface1->SetForceRenderSurface(true); + render_surface1->test_properties()->force_render_surface = true; { ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); @@ -1591,7 +1579,7 @@ TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { } { - render_surface1->SetForceRenderSurface(false); + render_surface1->test_properties()->force_render_surface = false; render_surface1->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); EXPECT_TRUE(parent->has_render_surface()); @@ -1630,13 +1618,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfacesFlattenScreenSpaceTransform) { gfx::PointF(), gfx::Size(10, 10), true, false, false); - grand_child->SetShouldFlattenTransform(false); + grand_child->test_properties()->should_flatten_transform = false; // Only grand_child should preserve 3d. - EXPECT_TRUE(root->should_flatten_transform()); - EXPECT_TRUE(parent->should_flatten_transform()); - EXPECT_TRUE(child->should_flatten_transform()); - EXPECT_FALSE(grand_child->should_flatten_transform()); + EXPECT_TRUE(root->test_properties()->should_flatten_transform); + EXPECT_TRUE(parent->test_properties()->should_flatten_transform); + EXPECT_TRUE(child->test_properties()->should_flatten_transform); + EXPECT_FALSE(grand_child->test_properties()->should_flatten_transform); gfx::Transform expected_child_draw_transform = identity_matrix; gfx::Transform expected_grand_child_draw_transform = identity_matrix; @@ -2299,9 +2287,9 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { // Case 1: Nothing is clipped. In this case, each layer's clip rect is its // bounds in target space. The only thing that changes when surfaces are // disabled is that target space is always screen space. - root->SetForceRenderSurface(true); - child1->SetForceRenderSurface(true); - grand_child->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; + child1->test_properties()->force_render_surface = true; + grand_child->test_properties()->force_render_surface = true; ExecuteCalculateDrawProperties(root); EXPECT_TRUE(root->has_render_surface()); EXPECT_FALSE(parent->has_render_surface()); @@ -2337,9 +2325,9 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { // render surface are clipped by the root's bounds. root->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; - root->SetForceRenderSurface(true); - child1->SetForceRenderSurface(true); - grand_child->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; + child1->test_properties()->force_render_surface = true; + grand_child->test_properties()->force_render_surface = true; ExecuteCalculateDrawProperties(root); EXPECT_TRUE(root->has_render_surface()); EXPECT_FALSE(parent->has_render_surface()); @@ -2390,9 +2378,9 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { parent->SetMasksToBounds(true); child1->SetMasksToBounds(true); host_impl()->active_tree()->property_trees()->needs_rebuild = true; - root->SetForceRenderSurface(true); - child1->SetForceRenderSurface(true); - grand_child->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; + child1->test_properties()->force_render_surface = true; + grand_child->test_properties()->force_render_surface = true; ExecuteCalculateDrawProperties(root); EXPECT_TRUE(root->has_render_surface()); EXPECT_FALSE(parent->has_render_surface()); @@ -2435,6 +2423,54 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { EXPECT_EQ(gfx::Rect(2, 2, 400, 400), leaf_node2->clip_rect()); } +TEST_F(LayerTreeHostCommonTest, HitTestingWhenSurfacesDisabled) { + LayerImpl* root = root_layer(); + LayerImpl* parent = AddChild<LayerImpl>(root); + LayerImpl* child = AddChild<LayerImpl>(parent); + LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* leaf_node = AddChild<LayerImpl>(grand_child); + + root->SetDrawsContent(true); + parent->SetDrawsContent(true); + child->SetDrawsContent(true); + grand_child->SetDrawsContent(true); + leaf_node->SetDrawsContent(true); + + const gfx::Transform identity_matrix; + + // child and grand_child will get render surfaces if surfaces are enabled. + SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false, + true); + SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), + gfx::PointF(2.f, 2.f), gfx::Size(400, 400), true, + false, false); + SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(), + gfx::PointF(4.f, 4.f), gfx::Size(800, 800), true, + false, true); + SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(), + gfx::PointF(8.f, 8.f), gfx::Size(1500, 1500), + true, false, true); + SetLayerPropertiesForTesting(leaf_node, identity_matrix, gfx::Point3F(), + gfx::PointF(16.f, 16.f), gfx::Size(2000, 2000), + true, false, false); + + parent->SetMasksToBounds(true); + child->SetMasksToBounds(true); + + root->SetHasRenderSurface(true); + child->SetHasRenderSurface(true); + grand_child->SetHasRenderSurface(true); + + host_impl()->set_resourceless_software_draw_for_testing(); + ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); + gfx::PointF test_point(90.f, 90.f); + LayerImpl* result_layer = + root->layer_tree_impl()->FindLayerThatIsHitByPoint(test_point); + ASSERT_TRUE(result_layer); + EXPECT_EQ(leaf_node, result_layer); +} + TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) { // Tests that draw properties are computed correctly when we disable and then // re-enable separate surfaces. @@ -2484,7 +2520,7 @@ TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) { ExecuteCalculateDrawProperties(root); EXPECT_FALSE(leaf_node->is_clipped()); - EXPECT_TRUE(leaf_node->render_target()->render_surface()->is_clipped()); + EXPECT_TRUE(leaf_node->render_target()->is_clipped()); EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect()); EXPECT_EQ(expected_leaf_draw_transform_with_surfaces, leaf_node->DrawTransform()); @@ -2506,7 +2542,7 @@ TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) { ExecuteCalculateDrawProperties(root); EXPECT_FALSE(leaf_node->is_clipped()); - EXPECT_TRUE(leaf_node->render_target()->render_surface()->is_clipped()); + EXPECT_TRUE(leaf_node->render_target()->is_clipped()); EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect()); EXPECT_EQ(expected_leaf_draw_transform_with_surfaces, leaf_node->DrawTransform()); @@ -2564,6 +2600,8 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { 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); + parent->layer_tree_impl()->BuildPropertyTreesForTesting(); + // Put an animated opacity on the render surface. AddOpacityTransitionToLayerWithPlayer(render_surface1->id(), timeline_impl(), 10.0, 1.f, 0.f, false); @@ -2583,6 +2621,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { AddAnimatedTransformToLayerWithPlayer(grand_child_of_rs2->id(), timeline_impl(), 10.0, 30, 0); + parent->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(parent); // Only layers that are associated with render surfaces should have an actual @@ -2600,17 +2639,21 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { ASSERT_FALSE(grand_child_of_rs2->render_surface()); // Verify all render target accessors - 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, 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, render_surface2->render_target()); - EXPECT_EQ(render_surface2, child_of_rs2->render_target()); - EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target()); + EXPECT_EQ(parent->render_surface(), parent->render_target()); + EXPECT_EQ(parent->render_surface(), child_of_root->render_target()); + EXPECT_EQ(parent->render_surface(), grand_child_of_root->render_target()); + + EXPECT_EQ(render_surface1->render_surface(), + render_surface1->render_target()); + EXPECT_EQ(render_surface1->render_surface(), child_of_rs1->render_target()); + EXPECT_EQ(render_surface1->render_surface(), + grand_child_of_rs1->render_target()); + + EXPECT_EQ(render_surface2->render_surface(), + render_surface2->render_target()); + EXPECT_EQ(render_surface2->render_surface(), child_of_rs2->render_target()); + EXPECT_EQ(render_surface2->render_surface(), + grand_child_of_rs2->render_target()); // Verify screen_space_transform_is_animating values EXPECT_FALSE(parent->screen_space_transform_is_animating()); @@ -2696,10 +2739,10 @@ TEST_F(LayerTreeHostCommonTest, false); // Add a transform animation with a start delay to |grand_child|. - scoped_ptr<Animation> animation = Animation::Create( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 0, 1, + std::unique_ptr<Animation> animation = Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 0, 1, TargetProperty::TRANSFORM); - animation->set_fill_mode(Animation::FILL_MODE_NONE); + animation->set_fill_mode(Animation::FillMode::NONE); animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddAnimationToLayerWithPlayer(grand_child->id(), timeline_impl(), std::move(animation)); @@ -2714,70 +2757,47 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_TRUE(great_grand_child->screen_space_transform_is_animating()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectForIdentityTransform) { - // Test the calculateVisibleRect() function works correctly for identity - // transforms. +TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForIdentityTransform) { + // Test visible layer rect and drawable content rect are calculated correctly + // correctly for identity transforms. gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; // Case 1: Layer is contained within the surface. gfx::Rect layer_content_rect = gfx::Rect(10, 10, 30, 30); - gfx::Rect expected = gfx::Rect(10, 10, 30, 30); - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + gfx::Rect expected_visible_layer_rect = gfx::Rect(30, 30); + gfx::Rect expected_drawable_content_rect = gfx::Rect(10, 10, 30, 30); + LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); // Case 2: Layer is outside the surface rect. layer_content_rect = gfx::Rect(120, 120, 30, 30); - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_TRUE(actual.IsEmpty()); + expected_visible_layer_rect = gfx::Rect(); + expected_drawable_content_rect = gfx::Rect(); + drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); // Case 3: Layer is partially overlapping the surface rect. layer_content_rect = gfx::Rect(80, 80, 30, 30); - expected = gfx::Rect(80, 80, 20, 20); - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); -} - -TEST_F(LayerTreeHostCommonTest, VisibleRectForTranslations) { - // Test the calculateVisibleRect() function works correctly for scaling - // transforms. - - gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); - gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30); - gfx::Transform layer_to_surface_transform; - - // Case 1: Layer is contained within the surface. - layer_to_surface_transform.MakeIdentity(); - layer_to_surface_transform.Translate(10.0, 10.0); - gfx::Rect expected = gfx::Rect(0, 0, 30, 30); - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); - - // Case 2: Layer is outside the surface rect. - layer_to_surface_transform.MakeIdentity(); - layer_to_surface_transform.Translate(120.0, 120.0); - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_TRUE(actual.IsEmpty()); - - // Case 3: Layer is partially overlapping the surface rect. - layer_to_surface_transform.MakeIdentity(); - layer_to_surface_transform.Translate(80.0, 80.0); - expected = gfx::Rect(0, 0, 20, 20); - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + expected_visible_layer_rect = gfx::Rect(20, 20); + expected_drawable_content_rect = gfx::Rect(80, 80, 20, 20); + drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectFor2DRotations) { - // Test the calculateVisibleRect() function works correctly for rotations - // about z-axis (i.e. 2D rotations). Remember that calculateVisibleRect() - // should return the g in the layer's space. +TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor2DRotations) { + // Test visible layer rect and drawable content rect are calculated correctly + // for rotations about z-axis (i.e. 2D rotations). gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30); @@ -2787,18 +2807,25 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor2DRotations) { layer_to_surface_transform.MakeIdentity(); layer_to_surface_transform.Translate(50.0, 50.0); layer_to_surface_transform.Rotate(45.0); - gfx::Rect expected = gfx::Rect(0, 0, 30, 30); - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + gfx::Rect expected_visible_layer_rect = gfx::Rect(30, 30); + gfx::Rect expected_drawable_content_rect = gfx::Rect(28, 50, 44, 43); + LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); // Case 2: Layer is outside the surface rect. layer_to_surface_transform.MakeIdentity(); layer_to_surface_transform.Translate(-50.0, 0.0); layer_to_surface_transform.Rotate(45.0); - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_TRUE(actual.IsEmpty()); + expected_visible_layer_rect = gfx::Rect(); + expected_drawable_content_rect = gfx::Rect(); + drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); // Case 3: The layer is rotated about its top-left corner. In surface space, // the layer is oriented diagonally, with the left half outside of the render @@ -2807,10 +2834,13 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor2DRotations) { // and bottom-right corners of the layer are still visible. layer_to_surface_transform.MakeIdentity(); layer_to_surface_transform.Rotate(45.0); - expected = gfx::Rect(0, 0, 30, 30); - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + expected_visible_layer_rect = gfx::Rect(30, 30); + expected_drawable_content_rect = gfx::Rect(22, 43); + drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); // Case 4: The layer is rotated about its top-left corner, and translated // upwards. In surface space, the layer is oriented diagonally, with only the @@ -2820,15 +2850,19 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor2DRotations) { layer_to_surface_transform.MakeIdentity(); layer_to_surface_transform.Translate(0.0, -sqrt(2.0) * 15.0); layer_to_surface_transform.Rotate(45.0); - expected = gfx::Rect(15, 0, 15, 30); // Right half of layer bounds. - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + // Right half of layer bounds. + expected_visible_layer_rect = gfx::Rect(15, 0, 15, 30); + expected_drawable_content_rect = gfx::Rect(22, 22); + drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dOrthographicTransform) { - // Test that the calculateVisibleRect() function works correctly for 3d - // transforms. +TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicTransform) { + // Test visible layer rect and drawable content rect are calculated correctly + // for 3d transforms. gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); @@ -2836,32 +2870,40 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dOrthographicTransform) { // Case 1: Orthographic projection of a layer rotated about y-axis by 45 // degrees, should be fully contained in the render surface. + // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width. layer_to_surface_transform.MakeIdentity(); layer_to_surface_transform.RotateAboutYAxis(45.0); - gfx::Rect expected = gfx::Rect(0, 0, 100, 100); - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + gfx::Rect expected_visible_layer_rect = gfx::Rect(100, 100); + gfx::Rect expected_drawable_content_rect = gfx::Rect(71, 100); + LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); // Case 2: Orthographic projection of a layer rotated about y-axis by 45 // degrees, but shifted to the side so only the right-half the layer would be // visible on the surface. - // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width. + // 50 is the un-rotated layer width; divided by sqrt(2) is the rotated width. SkMScalar half_width_of_rotated_layer = SkDoubleToMScalar((100.0 / sqrt(2.0)) * 0.5); layer_to_surface_transform.MakeIdentity(); layer_to_surface_transform.Translate(-half_width_of_rotated_layer, 0.0); layer_to_surface_transform.RotateAboutYAxis(45.0); // Rotates about the left // edge of the layer. - expected = gfx::Rect(50, 0, 50, 100); // Tight half of the layer. - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + // Tight half of the layer. + expected_visible_layer_rect = gfx::Rect(50, 0, 50, 100); + expected_drawable_content_rect = gfx::Rect(36, 100); + drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveTransform) { - // Test the calculateVisibleRect() function works correctly when the layer has - // a perspective projection onto the target surface. +TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { + // Test visible layer rect and drawable content rect are calculated correctly + // when the layer has a perspective projection onto the target surface. gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200); @@ -2881,10 +2923,15 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveTransform) { // This translate places the layer in front of the surface's projection plane. layer_to_surface_transform.Translate3d(0.0, 0.0, -27.0); - gfx::Rect expected = gfx::Rect(-50, -50, 200, 200); - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + // Layer position is (-50, -50), visible rect in layer space is layer bounds + // offset by layer position. + gfx::Rect expected_visible_layer_rect = gfx::Rect(50, 50, 150, 150); + gfx::Rect expected_drawable_content_rect = gfx::Rect(38, 38); + LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); // Case 2: same projection as before, except that the layer is also translated // to the side, so that only the right half of the layer should be visible. @@ -2892,20 +2939,23 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveTransform) { // Explanation of expected result: The perspective ratio is (z distance // between layer and camera origin) / (z distance between projection plane and // camera origin) == ((-27 - 9) / 9) Then, by similar triangles, if we want to - // move a layer by translating -50 units in projected surface units (so that + // move a layer by translating -25 units in projected surface units (so that // only half of it is visible), then we would need to translate by (-36 / 9) * - // -50 == -200 in the layer's units. - layer_to_surface_transform.Translate3d(-200.0, 0.0, 0.0); - expected = gfx::Rect(gfx::Point(50, -50), - gfx::Size(100, 200)); // The right half of the layer's - // bounding rect. - actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); -} - -TEST_F(LayerTreeHostCommonTest, - VisibleRectFor3dOrthographicIsNotClippedBehindSurface) { + // -25 == -100 in the layer's units. + layer_to_surface_transform.Translate3d(-100.0, 0.0, 0.0); + // Visible layer rect is moved by 100, and drawable content rect is in target + // space and is moved by 25. + expected_visible_layer_rect = gfx::Rect(150, 50, 50, 150); + expected_drawable_content_rect = gfx::Rect(13, 38); + drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); +} + +TEST_F(LayerTreeHostCommonDrawRectsTest, + DrawRectsFor3dOrthographicIsNotClippedBehindSurface) { // There is currently no explicit concept of an orthographic projection plane // in our code (nor in the CSS spec to my knowledge). Therefore, layers that // are technically behind the surface in an orthographic world should not be @@ -2922,22 +2972,30 @@ TEST_F(LayerTreeHostCommonTest, layer_to_surface_transform.RotateAboutYAxis(45.0); layer_to_surface_transform.Translate(-50.0, 0.0); - gfx::Rect expected = gfx::Rect(0, 0, 100, 100); - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); -} - -TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveWhenClippedByW) { - // Test the calculateVisibleRect() function works correctly when projecting a - // surface onto a layer, but the layer is partially behind the camera (not - // just behind the projection plane). In this case, the cartesian coordinates - // may seem to be valid, but actually they are not. The visible rect needs to - // be properly clipped by the w = 0 plane in homogeneous coordinates before - // converting to cartesian coordinates. - - gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100); - gfx::Rect layer_content_rect = gfx::Rect(-10, -1, 20, 2); + // Layer is rotated about Y Axis, and its width is 100/sqrt(2) in surface + // space. + gfx::Rect expected_visible_layer_rect = gfx::Rect(100, 100); + gfx::Rect expected_drawable_content_rect = gfx::Rect(14, 0, 72, 100); + LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); +} + +TEST_F(LayerTreeHostCommonDrawRectsTest, + DrawRectsFor3dPerspectiveWhenClippedByW) { + // Test visible layer rect and drawable content rect are calculated correctly + // when projecting a surface onto a layer, but the layer is partially behind + // the camera (not just behind the projection plane). In this case, the + // cartesian coordinates may seem to be valid, but actually they are not. The + // visible rect needs to be properly clipped by the w = 0 plane in homogeneous + // coordinates before converting to cartesian coordinates. The drawable + // content rect would be entire surface rect because layer is rotated at the + // camera position. + + gfx::Rect target_surface_rect = gfx::Rect(0, 0, 200, 200); + gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 2); gfx::Transform layer_to_surface_transform; // The layer is positioned so that the right half of the layer should be in @@ -2946,8 +3004,9 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveWhenClippedByW) { // perspective and rotation about the center of the layer. layer_to_surface_transform.MakeIdentity(); layer_to_surface_transform.ApplyPerspectiveDepth(1.0); - layer_to_surface_transform.Translate3d(-2.0, 0.0, 1.0); - layer_to_surface_transform.RotateAboutYAxis(45.0); + layer_to_surface_transform.Translate3d(10.0, 0.0, 1.0); + layer_to_surface_transform.RotateAboutYAxis(-45.0); + layer_to_surface_transform.Translate(-10, -1); // Sanity check that this transform does indeed cause w < 0 when applying the // transform, otherwise this code is not testing the intended scenario. @@ -2957,15 +3016,16 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveWhenClippedByW) { &clipped); ASSERT_TRUE(clipped); - int expected_x_position = 0; - int expected_width = 10; - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected_x_position, actual.x()); - EXPECT_EQ(expected_width, actual.width()); + gfx::Rect expected_visible_layer_rect = gfx::Rect(0, 1, 10, 1); + gfx::Rect expected_drawable_content_rect = target_surface_rect; + LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectForPerspectiveUnprojection) { +TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) { // To determine visible rect in layer space, there needs to be an // un-projection from surface space to layer space. When the original // transform was a perspective projection that was clipped, it returns a rect @@ -2974,14 +3034,16 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForPerspectiveUnprojection) { // This sequence of transforms causes one corner of the layer to protrude // across the w = 0 plane, and should be clipped. - gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100); - gfx::Rect layer_content_rect = gfx::Rect(-10, -10, 20, 20); + gfx::Rect target_surface_rect = gfx::Rect(0, 0, 150, 150); + gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 20); gfx::Transform layer_to_surface_transform; layer_to_surface_transform.MakeIdentity(); + layer_to_surface_transform.Translate(10, 10); layer_to_surface_transform.ApplyPerspectiveDepth(1.0); layer_to_surface_transform.Translate3d(0.0, 0.0, -5.0); layer_to_surface_transform.RotateAboutYAxis(45.0); layer_to_surface_transform.RotateAboutXAxis(80.0); + layer_to_surface_transform.Translate(-10, -10); // Sanity check that un-projection does indeed cause w < 0, otherwise this // code is not testing the intended scenario. @@ -2995,10 +3057,13 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForPerspectiveUnprojection) { // Only the corner of the layer is not visible on the surface because of being // clipped. But, the net result of rounding visible region to an axis-aligned // rect is that the entire layer should still be considered visible. - gfx::Rect expected = gfx::Rect(-10, -10, 20, 20); - gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( - target_surface_rect, layer_content_rect, layer_to_surface_transform); - EXPECT_EQ(expected, actual); + gfx::Rect expected_visible_layer_rect = layer_content_rect; + gfx::Rect expected_drawable_content_rect = target_surface_rect; + LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect( + target_surface_rect, layer_to_surface_transform, layer_content_rect); + EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect()); + EXPECT_EQ(expected_drawable_content_rect, + drawing_layer->drawable_content_rect()); } TEST_F(LayerTreeHostCommonTest, @@ -3420,13 +3485,11 @@ TEST_F(LayerTreeHostCommonTest, true, false, false); LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); // Now set the root render surface an empty clip. LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Size(), &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, gfx::Size(), &render_surface_layer_list_impl); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(root->render_surface()); EXPECT_FALSE(root->is_clipped()); @@ -3541,14 +3604,16 @@ TEST_F(LayerTreeHostCommonTest, FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.active_tree(), 2); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl.active_tree(), 2); + std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl.active_tree(), 3); - scoped_ptr<LayerImpl> occluding_child = + std::unique_ptr<LayerImpl> occluding_child = LayerImpl::Create(host_impl.active_tree(), 4); child->SetDrawsContent(true); grand_child->SetDrawsContent(true); @@ -3772,39 +3837,6 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(100, 100), render_surface2->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipChildWithSingularTransform) { - LayerImpl* root = root_layer(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* intervening = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(intervening); - - clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); - clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); - - gfx::Transform identity_matrix; - gfx::Transform singular_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - ASSERT_FALSE(singular_matrix.IsInvertible()); - - SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(100, 100), true, false, - true); - SetLayerPropertiesForTesting(clip_parent, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(50, 50), true, false, - false); - SetLayerPropertiesForTesting(intervening, identity_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(50, 50), true, false, - false); - SetLayerPropertiesForTesting(clip_child, singular_matrix, gfx::Point3F(), - gfx::PointF(), gfx::Size(60, 60), true, false, - false); - - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(intervening->num_unclipped_descendants(), 1u); -} - TEST_F(LayerTreeHostCommonTest, VisibleRectsWhenClipChildIsBetweenTwoRenderSurfaces) { LayerImpl* root = root_layer(); @@ -3816,10 +3848,10 @@ TEST_F(LayerTreeHostCommonTest, render_surface1->SetDrawsContent(true); render_surface2->SetDrawsContent(true); clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); gfx::Transform identity_matrix; SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), @@ -3856,10 +3888,10 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { render_surface1->SetDrawsContent(true); render_surface2->SetDrawsContent(true); clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); gfx::Transform identity_matrix; SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), @@ -3926,10 +3958,10 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { unclipped_surface->SetDrawsContent(true); unclipped_desc_surface->SetDrawsContent(true); clipped_surface->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); gfx::Transform identity_matrix; SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), @@ -3972,10 +4004,10 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { unclipped_surface->SetDrawsContent(true); unclipped_desc_surface->SetDrawsContent(true); clipped_surface->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); gfx::Transform identity_matrix; SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), @@ -4187,48 +4219,43 @@ 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<LayerWithForcedDrawsContent> front_facing_child = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> back_facing_child = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> - front_facing_child_of_front_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> - back_facing_child_of_front_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> - front_facing_child_of_back_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> - back_facing_child_of_back_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - - parent->AddChild(front_facing_child); - parent->AddChild(back_facing_child); - parent->AddChild(front_facing_surface); - parent->AddChild(back_facing_surface); - front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); - front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); - back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); - back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - - host()->SetRootLayer(parent); + LayerImpl* parent = root_layer(); + LayerImpl* front_facing_child = AddChildToRoot<LayerImpl>(); + LayerImpl* back_facing_child = AddChildToRoot<LayerImpl>(); + LayerImpl* front_facing_surface = AddChildToRoot<LayerImpl>(); + LayerImpl* back_facing_surface = AddChildToRoot<LayerImpl>(); + LayerImpl* front_facing_child_of_front_facing_surface = + AddChild<LayerImpl>(front_facing_surface); + LayerImpl* back_facing_child_of_front_facing_surface = + AddChild<LayerImpl>(front_facing_surface); + LayerImpl* front_facing_child_of_back_facing_surface = + AddChild<LayerImpl>(back_facing_surface); + LayerImpl* back_facing_child_of_back_facing_surface = + AddChild<LayerImpl>(back_facing_surface); // Nothing is double-sided - front_facing_child->SetDoubleSided(false); - back_facing_child->SetDoubleSided(false); - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - front_facing_child_of_front_facing_surface->SetDoubleSided(false); - back_facing_child_of_front_facing_surface->SetDoubleSided(false); - front_facing_child_of_back_facing_surface->SetDoubleSided(false); - back_facing_child_of_back_facing_surface->SetDoubleSided(false); + front_facing_child->test_properties()->double_sided = false; + back_facing_child->test_properties()->double_sided = false; + front_facing_surface->test_properties()->double_sided = false; + back_facing_surface->test_properties()->double_sided = false; + front_facing_child_of_front_facing_surface->test_properties()->double_sided = + false; + back_facing_child_of_front_facing_surface->test_properties()->double_sided = + false; + front_facing_child_of_back_facing_surface->test_properties()->double_sided = + false; + back_facing_child_of_back_facing_surface->test_properties()->double_sided = + false; + + // Everything draws content. + front_facing_child->SetDrawsContent(true); + back_facing_child->SetDrawsContent(true); + front_facing_surface->SetDrawsContent(true); + back_facing_surface->SetDrawsContent(true); + front_facing_child_of_front_facing_surface->SetDrawsContent(true); + back_facing_child_of_front_facing_surface->SetDrawsContent(true); + front_facing_child_of_back_facing_surface->SetDrawsContent(true); + back_facing_child_of_back_facing_surface->SetDrawsContent(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); @@ -4242,71 +4269,34 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { // Nothing preserves 3d. According to current W3C CSS gfx::Transforms spec, // these layers should blindly use their own local transforms to determine // back-face culling. - SetLayerPropertiesForTesting(parent.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(front_facing_child.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(back_facing_child.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(front_facing_surface.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(back_facing_surface.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); + SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(front_facing_child, identity_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(back_facing_child, backface_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(front_facing_surface, identity_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(back_facing_surface, backface_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface, + identity_matrix, gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface, + backface_matrix, gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface, + identity_matrix, gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface, + backface_matrix, gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); - ExecuteCalculateDrawPropertiesWithPropertyTrees(parent.get()); + ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); // Verify which render surfaces were created. EXPECT_FALSE(front_facing_child->has_render_surface()); @@ -4319,13 +4309,13 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { EXPECT_FALSE(front_facing_child_of_back_facing_surface->has_render_surface()); EXPECT_FALSE(back_facing_child_of_back_facing_surface->has_render_surface()); - EXPECT_EQ(4u, update_layer_list().size()); - EXPECT_TRUE(UpdateLayerListContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerListContains( + EXPECT_EQ(4u, update_layer_list_impl()->size()); + EXPECT_TRUE(UpdateLayerListImplContains(front_facing_child->id())); + EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerListImplContains( front_facing_child_of_front_facing_surface->id())); - EXPECT_TRUE( - UpdateLayerListContains(front_facing_child_of_back_facing_surface->id())); + EXPECT_TRUE(UpdateLayerListImplContains( + front_facing_child_of_back_facing_surface->id())); } TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { @@ -4355,14 +4345,18 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { AddReplicaLayer<LayerImpl>(back_facing_surface); // Nothing is double-sided - front_facing_child->SetDoubleSided(false); - back_facing_child->SetDoubleSided(false); - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - front_facing_child_of_front_facing_surface->SetDoubleSided(false); - back_facing_child_of_front_facing_surface->SetDoubleSided(false); - front_facing_child_of_back_facing_surface->SetDoubleSided(false); - back_facing_child_of_back_facing_surface->SetDoubleSided(false); + front_facing_child->test_properties()->double_sided = false; + back_facing_child->test_properties()->double_sided = false; + front_facing_surface->test_properties()->double_sided = false; + back_facing_surface->test_properties()->double_sided = false; + front_facing_child_of_front_facing_surface->test_properties()->double_sided = + false; + back_facing_child_of_front_facing_surface->test_properties()->double_sided = + false; + front_facing_child_of_back_facing_surface->test_properties()->double_sided = + false; + back_facing_child_of_back_facing_surface->test_properties()->double_sided = + false; // Everything draws content. front_facing_child->SetDrawsContent(true); @@ -4442,98 +4436,59 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) { // Verify that layers are appropriately culled when their back face is showing // and they are not double sided, while animations are going on. // - // Layers that are animating do not get culled on the main thread, as their - // transforms should be treated as "unknown" so we can not be sure that their - // back face is really showing. + // Even layers that are animating get culled if their back face is showing and + // they are not double sided. const gfx::Transform identity_matrix; - scoped_refptr<Layer> parent = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> child = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> animating_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> child_of_animating_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> animating_child = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> child2 = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - - parent->AddChild(child); - parent->AddChild(animating_surface); - animating_surface->AddChild(child_of_animating_surface); - parent->AddChild(animating_child); - parent->AddChild(child2); - - host()->SetRootLayer(parent); + LayerImpl* parent = root_layer(); + LayerImpl* child = AddChildToRoot<LayerImpl>(); + LayerImpl* animating_surface = AddChildToRoot<LayerImpl>(); + LayerImpl* child_of_animating_surface = + AddChild<LayerImpl>(animating_surface); + LayerImpl* animating_child = AddChildToRoot<LayerImpl>(); + LayerImpl* child2 = AddChildToRoot<LayerImpl>(); // Nothing is double-sided - child->SetDoubleSided(false); - child2->SetDoubleSided(false); - animating_surface->SetDoubleSided(false); - child_of_animating_surface->SetDoubleSided(false); - animating_child->SetDoubleSided(false); + child->test_properties()->double_sided = false; + child2->test_properties()->double_sided = false; + animating_surface->test_properties()->double_sided = false; + child_of_animating_surface->test_properties()->double_sided = false; + animating_child->test_properties()->double_sided = false; + + // Everything draws content. + child->SetDrawsContent(true); + child2->SetDrawsContent(true); + animating_surface->SetDrawsContent(true); + child_of_animating_surface->SetDrawsContent(true); + animating_child->SetDrawsContent(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); backface_matrix.RotateAboutYAxis(180.0); backface_matrix.Translate(-50.0, -50.0); - // Make our render surface. - animating_surface->SetForceRenderSurface(true); - // Animate the transform on the render surface. - AddAnimatedTransformToLayerWithPlayer(animating_surface->id(), timeline(), - 10.0, 30, 0); + AddAnimatedTransformToLayerWithPlayer(animating_surface->id(), + timeline_impl(), 10.0, 30, 0); // This is just an animating layer, not a surface. - AddAnimatedTransformToLayerWithPlayer(animating_child->id(), timeline(), 10.0, - 30, 0); + AddAnimatedTransformToLayerWithPlayer(animating_child->id(), timeline_impl(), + 10.0, 30, 0); - SetLayerPropertiesForTesting(parent.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(child.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(animating_surface.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(child_of_animating_surface.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(animating_child.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(child2.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); + SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(child, backface_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(animating_surface, backface_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false, true); + SetLayerPropertiesForTesting(child_of_animating_surface, backface_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(animating_child, backface_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(child2, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - parent.get(), parent->bounds()); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); EXPECT_FALSE(child->has_render_surface()); EXPECT_TRUE(animating_surface->has_render_surface()); @@ -4541,29 +4496,17 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) { EXPECT_FALSE(animating_child->has_render_surface()); EXPECT_FALSE(child2->has_render_surface()); - ExecuteCalculateDrawPropertiesWithPropertyTrees(parent.get()); - - EXPECT_EQ(4u, update_layer_list().size()); - - // The non-animating child be culled from the layer list for the parent render - // surface. - EXPECT_TRUE(UpdateLayerListContains(animating_surface->id())); - EXPECT_TRUE(UpdateLayerListContains(animating_child->id())); - EXPECT_TRUE(UpdateLayerListContains(child2->id())); - EXPECT_TRUE(UpdateLayerListContains(child_of_animating_surface->id())); + EXPECT_EQ(1u, update_layer_list_impl()->size()); - EXPECT_FALSE(child2->visible_layer_rect_for_testing().IsEmpty()); + // The back facing layers are culled from the layer list, and have an empty + // visible rect. + EXPECT_TRUE(UpdateLayerListImplContains(child2->id())); + EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(animating_surface->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(child_of_animating_surface->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(animating_child->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_layer_rect_for_testing(), - gfx::Rect(animating_child->bounds())); - EXPECT_EQ(animating_surface->visible_layer_rect_for_testing(), - 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_layer_rect_for_testing(), - gfx::Rect(child_of_animating_surface->bounds())); + EXPECT_EQ(gfx::Rect(100, 100), child2->visible_layer_rect()); } TEST_F(LayerTreeHostCommonTest, @@ -4572,72 +4515,47 @@ 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<LayerWithForcedDrawsContent> front_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> child1 = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_refptr<LayerWithForcedDrawsContent> child2 = - make_scoped_refptr(new LayerWithForcedDrawsContent()); - - parent->AddChild(front_facing_surface); - parent->AddChild(back_facing_surface); - front_facing_surface->AddChild(child1); - back_facing_surface->AddChild(child2); - - host()->SetRootLayer(parent); + LayerImpl* parent = root_layer(); + LayerImpl* front_facing_surface = AddChildToRoot<LayerImpl>(); + LayerImpl* back_facing_surface = AddChildToRoot<LayerImpl>(); + LayerImpl* child1 = AddChild<LayerImpl>(front_facing_surface); + LayerImpl* child2 = AddChild<LayerImpl>(back_facing_surface); // RenderSurfaces are not double-sided - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); + front_facing_surface->test_properties()->double_sided = false; + back_facing_surface->test_properties()->double_sided = false; + + // Everything draws content. + front_facing_surface->SetDrawsContent(true); + back_facing_surface->SetDrawsContent(true); + child1->SetDrawsContent(true); + child2->SetDrawsContent(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); backface_matrix.RotateAboutYAxis(180.0); backface_matrix.Translate(-50.0, -50.0); - SetLayerPropertiesForTesting(parent.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - false, + SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), false, true); // parent transform style is preserve3d. - SetLayerPropertiesForTesting(front_facing_surface.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, + SetLayerPropertiesForTesting(front_facing_surface, identity_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, true); // surface transform style is flat. - SetLayerPropertiesForTesting(back_facing_surface.get(), - backface_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, + SetLayerPropertiesForTesting(back_facing_surface, backface_matrix, + gfx::Point3F(), gfx::PointF(), + gfx::Size(100, 100), true, true); // surface transform style is flat. - SetLayerPropertiesForTesting(child1.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); - SetLayerPropertiesForTesting(child2.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(100, 100), - true, - false); + SetLayerPropertiesForTesting(child1, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(child2, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); front_facing_surface->Set3dSortingContextId(1); back_facing_surface->Set3dSortingContextId(1); - ExecuteCalculateDrawPropertiesWithPropertyTrees(parent.get()); + ExecuteCalculateDrawPropertiesWithPropertyTrees(parent); // Verify which render surfaces were created and used. EXPECT_TRUE(front_facing_surface->has_render_surface()); @@ -4647,9 +4565,9 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_FALSE(child1->has_render_surface()); EXPECT_FALSE(child2->has_render_surface()); - EXPECT_EQ(2u, update_layer_list().size()); - EXPECT_TRUE(UpdateLayerListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerListContains(child1->id())); + EXPECT_EQ(2u, update_layer_list_impl()->size()); + EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerListImplContains(child1->id())); } TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { @@ -4931,7 +4849,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { gfx::Transform replica_transform; replica_transform.Scale(1.0, -1.0); - scoped_ptr<LayerImpl> replica = + std::unique_ptr<LayerImpl> replica = LayerImpl::Create(host_impl()->active_tree(), 7); SetLayerPropertiesForTesting(replica.get(), replica_transform, gfx::Point3F(), gfx::PointF(2.f, 2.f), gfx::Size(10, 10), false, @@ -5044,7 +4962,7 @@ TEST_F(LayerTreeHostCommonTest, gfx::Transform replica_transform; replica_transform.Scale(1.0, -1.0); - scoped_ptr<LayerImpl> replica = + std::unique_ptr<LayerImpl> replica = LayerImpl::Create(host_impl()->active_tree(), 7); SetLayerPropertiesForTesting(replica.get(), replica_transform, gfx::Point3F(), gfx::PointF(), gfx::Size(13, 11), false, true, @@ -5103,41 +5021,22 @@ TEST_F(LayerTreeHostCommonTest, LayerSearch) { } TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> child = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> grand_child = - make_scoped_refptr(new LayerWithForcedDrawsContent()); + LayerImpl* root = root_layer(); + LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* grand_child = AddChild<LayerImpl>(child); + grand_child->SetDrawsContent(true); const 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(10, 10), - true, - false); - SetLayerPropertiesForTesting(grand_child.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(10, 10), - true, - false); + SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(10, 10), true, false); + SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(10, 10), true, false); - root->AddChild(child); - child->AddChild(grand_child); child->SetOpacity(0.5f); - host()->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); + ExecuteCalculateDrawProperties(root); EXPECT_FALSE(child->has_render_surface()); } @@ -5149,7 +5048,8 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { FakeLayerTreeHostImpl host_impl(host()->settings(), &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.CreatePendingTree(); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.pending_tree(), 1); const gfx::Transform identity_matrix; SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), @@ -5157,33 +5057,33 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { false); root->SetDrawsContent(true); - scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl.pending_tree(), 2); SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false, false); child->SetDrawsContent(true); child->SetOpacity(0.0f); + const int child_id = child->id(); + root->AddChild(std::move(child)); + root->SetHasRenderSurface(true); + LayerImpl* root_layer = root.get(); + host_impl.pending_tree()->SetRootLayer(std::move(root)); + host_impl.pending_tree()->BuildPropertyTreesForTesting(); // Add opacity animation. scoped_refptr<AnimationTimeline> timeline = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); host_impl.animation_host()->AddAnimationTimeline(timeline); - AddOpacityTransitionToLayerWithPlayer(child->id(), timeline, 10.0, 0.0f, 1.0f, + AddOpacityTransitionToLayerWithPlayer(child_id, timeline, 10.0, 0.0f, 1.0f, false); - root->AddChild(std::move(child)); - root->SetHasRenderSurface(true); - LayerImpl* root_layer = root.get(); - host_impl.pending_tree()->SetRootLayer(std::move(root)); - LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // We should have one render surface and two layers. The child // layer should be included even though it is transparent. @@ -5195,15 +5095,13 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { root_layer->SetOpacity(0.0f); root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; LayerImplList render_surface_layer_list2; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs2( - root_layer, root_layer->bounds(), &render_surface_layer_list2, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list2); inputs2.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs2); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs2); LayerImpl* child_ptr = root_layer->layer_tree_impl()->LayerById(2); - EffectTree tree = + EffectTree& tree = root_layer->layer_tree_impl()->property_trees()->effect_tree; EffectNode* node = tree.Node(child_ptr->effect_tree_index()); EXPECT_FALSE(node->data.is_drawn); @@ -5214,18 +5112,33 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { child_ptr->SetOpacity(0.0f); root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; LayerImplList render_surface_layer_list3; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs3( - root_layer, root_layer->bounds(), &render_surface_layer_list3, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list3); inputs3.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs3); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs3); child_ptr = root_layer->layer_tree_impl()->LayerById(2); tree = root_layer->layer_tree_impl()->property_trees()->effect_tree; node = tree.Node(child_ptr->effect_tree_index()); EXPECT_TRUE(node->data.is_drawn); EXPECT_TRUE(tree.ContributesToDrawnSurface(child_ptr->effect_tree_index())); + + // But if the opacity of the layer remains 0 after activation, it should not + // be drawn. + host_impl.ActivateSyncTree(); + LayerImpl* active_root = host_impl.active_tree()->root_layer(); + LayerImpl* active_child = host_impl.active_tree()->LayerById(child_ptr->id()); + + EffectTree& active_effect_tree = + host_impl.active_tree()->property_trees()->effect_tree; + EXPECT_TRUE(active_effect_tree.needs_update()); + + ExecuteCalculateDrawProperties(active_root); + + node = active_effect_tree.Node(active_child->effect_tree_index()); + EXPECT_FALSE(node->data.is_drawn); + EXPECT_FALSE(active_effect_tree.ContributesToDrawnSurface( + active_child->effect_tree_index())); } using LCDTextTestParam = std::tr1::tuple<bool, bool, bool>; @@ -5252,11 +5165,11 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, can_use_lcd_text_ = std::tr1::get<0>(GetParam()); layers_always_allowed_lcd_text_ = std::tr1::get<1>(GetParam()); - scoped_ptr<LayerImpl> root_ptr = + std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl_.active_tree(), 1); - scoped_ptr<LayerImpl> child_ptr = + std::unique_ptr<LayerImpl> child_ptr = LayerImpl::Create(host_impl_.active_tree(), 2); - scoped_ptr<LayerImpl> grand_child_ptr = + std::unique_ptr<LayerImpl> grand_child_ptr = LayerImpl::Create(host_impl_.active_tree(), 3); // Stash raw pointers to look at later. @@ -5468,26 +5381,28 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) { host_impl.CreatePendingTree(); const gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.pending_tree(), 1); LayerImpl* root_layer = root.get(); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false, false); root->SetDrawsContent(true); - scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl.pending_tree(), 2); SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40), true, false, false); child->SetDrawsContent(true); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl.pending_tree(), 3); SetLayerPropertiesForTesting(grand_child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), true, false, false); grand_child->SetDrawsContent(true); - grand_child->SetHideLayerAndSubtree(true); + grand_child->test_properties()->hide_layer_and_subtree = true; child->AddChild(std::move(grand_child)); root->AddChild(std::move(child)); @@ -5495,12 +5410,10 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) { host_impl.pending_tree()->SetRootLayer(std::move(root)); LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // We should have one render surface and two layers. The grand child has // hidden itself. @@ -5519,21 +5432,23 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { host_impl.CreatePendingTree(); const gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.pending_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false, true); root->SetDrawsContent(true); LayerImpl* root_layer = root.get(); - scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl.pending_tree(), 2); SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40), true, false, false); child->SetDrawsContent(true); - child->SetHideLayerAndSubtree(true); + child->test_properties()->hide_layer_and_subtree = true; - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl.pending_tree(), 3); SetLayerPropertiesForTesting(grand_child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), @@ -5545,12 +5460,10 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { host_impl.pending_tree()->SetRootLayer(std::move(root)); LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // We should have one render surface and one layers. The child has // hidden itself and the grand child. @@ -5559,7 +5472,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { EXPECT_EQ(1, root_layer->render_surface()->layer_list().at(0)->id()); } -void EmptyCopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} +void EmptyCopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { FakeImplTaskRunnerProvider task_runner_provider; @@ -5570,14 +5483,15 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { host_impl.CreatePendingTree(); const gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.pending_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false, true); root->SetDrawsContent(true); LayerImpl* root_layer = root.get(); - scoped_ptr<LayerImpl> copy_grand_parent = + std::unique_ptr<LayerImpl> copy_grand_parent = LayerImpl::Create(host_impl.pending_tree(), 2); SetLayerPropertiesForTesting(copy_grand_parent.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40), @@ -5585,7 +5499,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { copy_grand_parent->SetDrawsContent(true); LayerImpl* copy_grand_parent_layer = copy_grand_parent.get(); - scoped_ptr<LayerImpl> copy_parent = + std::unique_ptr<LayerImpl> copy_parent = LayerImpl::Create(host_impl.pending_tree(), 3); SetLayerPropertiesForTesting(copy_parent.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), @@ -5593,7 +5507,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { copy_parent->SetDrawsContent(true); LayerImpl* copy_parent_layer = copy_parent.get(); - scoped_ptr<LayerImpl> copy_request = + std::unique_ptr<LayerImpl> copy_request = LayerImpl::Create(host_impl.pending_tree(), 4); SetLayerPropertiesForTesting(copy_request.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(20, 20), @@ -5601,7 +5515,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { copy_request->SetDrawsContent(true); LayerImpl* copy_layer = copy_request.get(); - scoped_ptr<LayerImpl> copy_child = + std::unique_ptr<LayerImpl> copy_child = LayerImpl::Create(host_impl.pending_tree(), 5); SetLayerPropertiesForTesting(copy_child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(20, 20), @@ -5609,7 +5523,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { copy_child->SetDrawsContent(true); LayerImpl* copy_child_layer = copy_child.get(); - scoped_ptr<LayerImpl> copy_grand_child = + std::unique_ptr<LayerImpl> copy_grand_child = LayerImpl::Create(host_impl.pending_tree(), 6); SetLayerPropertiesForTesting(copy_grand_child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(20, 20), @@ -5617,7 +5531,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { copy_child->SetDrawsContent(true); LayerImpl* copy_grand_child_layer = copy_grand_child.get(); - scoped_ptr<LayerImpl> copy_grand_parent_sibling_before = + std::unique_ptr<LayerImpl> copy_grand_parent_sibling_before = LayerImpl::Create(host_impl.pending_tree(), 7); SetLayerPropertiesForTesting(copy_grand_parent_sibling_before.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), @@ -5626,7 +5540,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { LayerImpl* copy_grand_parent_sibling_before_layer = copy_grand_parent_sibling_before.get(); - scoped_ptr<LayerImpl> copy_grand_parent_sibling_after = + std::unique_ptr<LayerImpl> copy_grand_parent_sibling_after = LayerImpl::Create(host_impl.pending_tree(), 8); SetLayerPropertiesForTesting(copy_grand_parent_sibling_after.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), @@ -5647,24 +5561,24 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { // Hide the copy_grand_parent and its subtree. But make a copy request in that // hidden subtree on copy_layer. Also hide the copy grand child and its // subtree. - copy_grand_parent_layer->SetHideLayerAndSubtree(true); - copy_grand_parent_sibling_before_layer->SetHideLayerAndSubtree(true); - copy_grand_parent_sibling_after_layer->SetHideLayerAndSubtree(true); - copy_grand_child_layer->SetHideLayerAndSubtree(true); - - std::vector<scoped_ptr<CopyOutputRequest>> copy_requests; + copy_grand_parent_layer->test_properties()->hide_layer_and_subtree = true; + copy_grand_parent_sibling_before_layer->test_properties() + ->hide_layer_and_subtree = true; + copy_grand_parent_sibling_after_layer->test_properties() + ->hide_layer_and_subtree = true; + copy_grand_child_layer->test_properties()->hide_layer_and_subtree = true; + + std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests; copy_requests.push_back( CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); copy_layer->PassCopyRequests(©_requests); EXPECT_TRUE(copy_layer->HasCopyRequest()); LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_GT(root_layer->num_copy_requests_in_target_subtree(), 0); EXPECT_GT(copy_grand_parent_layer->num_copy_requests_in_target_subtree(), 0); @@ -5692,7 +5606,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { // appear in its list, since it needs to be drawn for the copy request. ASSERT_EQ(1u, copy_parent_layer->render_surface()->layer_list().size()); EXPECT_EQ(copy_layer->id(), - copy_layer->render_surface()->layer_list().at(0)->id()); + copy_parent_layer->render_surface()->layer_list().at(0)->id()); // The copy_layer's render surface should have two contributing layers. ASSERT_EQ(2u, copy_layer->render_surface()->layer_list().size()); @@ -5732,13 +5646,14 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { host_impl.CreatePendingTree(); const gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.pending_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false, true); root->SetDrawsContent(true); - scoped_ptr<LayerImpl> copy_parent = + std::unique_ptr<LayerImpl> copy_parent = LayerImpl::Create(host_impl.pending_tree(), 2); SetLayerPropertiesForTesting(copy_parent.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(), true, @@ -5746,21 +5661,21 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { copy_parent->SetDrawsContent(true); copy_parent->SetMasksToBounds(true); - scoped_ptr<LayerImpl> copy_layer = + std::unique_ptr<LayerImpl> copy_layer = LayerImpl::Create(host_impl.pending_tree(), 3); SetLayerPropertiesForTesting(copy_layer.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), true, false, true); copy_layer->SetDrawsContent(true); - scoped_ptr<LayerImpl> copy_child = + std::unique_ptr<LayerImpl> copy_child = LayerImpl::Create(host_impl.pending_tree(), 4); SetLayerPropertiesForTesting(copy_child.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(20, 20), true, false, false); copy_child->SetDrawsContent(true); - std::vector<scoped_ptr<CopyOutputRequest>> copy_requests; + std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests; copy_requests.push_back( CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); copy_layer->PassCopyRequests(©_requests); @@ -5771,14 +5686,12 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { root->AddChild(std::move(copy_parent)); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerImpl* root_layer = root.get(); root_layer->layer_tree_impl()->SetRootLayer(std::move(root)); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // We should have two render surface, as the others are clipped out. ASSERT_EQ(2u, render_surface_layer_list.size()); @@ -5836,10 +5749,10 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { intervening->SetDrawsContent(true); LayerImpl* clip_child = AddChild<LayerImpl>(intervening); clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); intervening->SetMasksToBounds(true); clip_parent->SetMasksToBounds(true); @@ -5911,7 +5824,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { render_surface2->SetDrawsContent(true); clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); + clip_child->test_properties()->clip_parent = clip_parent; intervening->SetMasksToBounds(true); clip_parent->SetMasksToBounds(true); @@ -6000,7 +5913,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { render_surface2->SetDrawsContent(true); clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); + clip_child->test_properties()->clip_parent = clip_parent; intervening->SetMasksToBounds(true); clip_parent->SetMasksToBounds(true); @@ -6086,10 +5999,10 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { clip_child->SetDrawsContent(true); child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); intervening->SetMasksToBounds(true); clip_parent->SetMasksToBounds(true); @@ -6147,10 +6060,10 @@ TEST_F(LayerTreeHostCommonTest, LayerImpl* non_clip_child = AddChild<LayerImpl>(render_surface2); non_clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); clip_parent->SetMasksToBounds(true); render_surface1->SetMasksToBounds(true); @@ -6206,8 +6119,8 @@ TEST_F(LayerTreeHostCommonTest, render_surface2->render_surface()->content_rect()); // Sanity check our num_unclipped_descendants values. - EXPECT_EQ(1u, render_surface1->num_unclipped_descendants()); - EXPECT_EQ(0u, render_surface2->num_unclipped_descendants()); + EXPECT_EQ(1u, render_surface1->test_properties()->num_unclipped_descendants); + EXPECT_EQ(0u, render_surface2->test_properties()->num_unclipped_descendants); } TEST_F(LayerTreeHostCommonTest, @@ -6256,13 +6169,13 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 12345); - scoped_ptr<LayerImpl> child1 = + std::unique_ptr<LayerImpl> child1 = LayerImpl::Create(host_impl.active_tree(), 123456); - scoped_ptr<LayerImpl> child2 = + std::unique_ptr<LayerImpl> child2 = LayerImpl::Create(host_impl.active_tree(), 1234567); - scoped_ptr<LayerImpl> child3 = + std::unique_ptr<LayerImpl> child3 = LayerImpl::Create(host_impl.active_tree(), 12345678); gfx::Transform identity_matrix; @@ -6297,12 +6210,10 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { { LayerImplList render_surface_layer_list; FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root_layer); - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_render_to_separate_surface = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(2u, render_surface_layer_list.size()); @@ -6330,12 +6241,10 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { { LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_render_to_separate_surface = false; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(1u, render_surface_layer_list.size()); @@ -6392,13 +6301,13 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { gfx::PointF(), gfx::Size(20, 20), true, false, false); - root->SetShouldFlattenTransform(false); + root->test_properties()->should_flatten_transform = false; root->Set3dSortingContextId(1); back_facing->Set3dSortingContextId(1); - back_facing->SetShouldFlattenTransform(false); - render_surface1->SetDoubleSided(false); + back_facing->test_properties()->should_flatten_transform = false; + render_surface1->test_properties()->double_sided = false; render_surface2->Set3dSortingContextId(2); - render_surface2->SetDoubleSided(false); + render_surface2->test_properties()->double_sided = false; ExecuteCalculateDrawProperties(root); @@ -6442,7 +6351,7 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { LayerImpl* grand_child = AddChild<LayerImpl>(child); grand_child->SetDrawsContent(true); - child->SetDoubleSided(false); + child->test_properties()->double_sided = false; grand_child->SetUseParentBackfaceVisibility(true); gfx::Transform identity_transform; @@ -6506,7 +6415,7 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { EXPECT_TRUE(grand_child->use_local_transform_for_backface_visibility()); grand_child->SetUseParentBackfaceVisibility(false); - grand_child->SetDoubleSided(false); + grand_child->test_properties()->double_sided = false; grand_child->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); @@ -6552,8 +6461,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), false, true, true); - render_surface1->SetDoubleSided(false); - render_surface2->SetDoubleSided(false); + render_surface1->test_properties()->double_sided = false; + render_surface2->test_properties()->double_sided = false; ExecuteCalculateDrawProperties(root); @@ -6600,10 +6509,12 @@ TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) { scroll_child->SetDrawsContent(true); scroll_parent_clip->SetMasksToBounds(true); - scroll_child->SetScrollParent(scroll_parent); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + scroll_child->test_properties()->scroll_parent = scroll_parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child); - scroll_parent->SetScrollChildren(scroll_children.release()); + scroll_parent->test_properties()->scroll_children.reset( + scroll_children.release()); gfx::Transform identity_transform; SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(), @@ -6642,10 +6553,12 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { scroll_parent->SetDrawsContent(true); scroll_child->SetDrawsContent(true); - scroll_child->SetScrollParent(scroll_parent); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + scroll_child->test_properties()->scroll_parent = scroll_parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child); - scroll_parent->SetScrollChildren(scroll_children.release()); + scroll_parent->test_properties()->scroll_children.reset( + scroll_children.release()); gfx::Transform identity_transform; SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(), @@ -6667,12 +6580,11 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { float device_scale_factor = 1.5f; LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), identity_transform, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), identity_transform, + &render_surface_layer_list_impl); inputs.device_scale_factor = device_scale_factor; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(scroll_child->effect_tree_index(), scroll_child_target->effect_tree_index()); @@ -6749,10 +6661,12 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) { scroll_parent_clip->SetMasksToBounds(true); - scroll_child->SetScrollParent(scroll_parent); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + scroll_child->test_properties()->scroll_parent = scroll_parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child); - scroll_parent->SetScrollChildren(scroll_children.release()); + scroll_parent->test_properties()->scroll_children.reset( + scroll_children.release()); gfx::Transform identity_transform; SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(), @@ -6809,15 +6723,18 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) { scroll_parent_clip->SetMasksToBounds(true); scroll_grandparent_clip->SetMasksToBounds(true); - scroll_child->SetScrollParent(scroll_parent); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + scroll_child->test_properties()->scroll_parent = scroll_parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child); - scroll_parent->SetScrollChildren(scroll_children.release()); + scroll_parent->test_properties()->scroll_children.reset( + scroll_children.release()); - scroll_parent_border->SetScrollParent(scroll_grandparent); + scroll_parent_border->test_properties()->scroll_parent = scroll_grandparent; scroll_children.reset(new std::set<LayerImpl*>); scroll_children->insert(scroll_parent_border); - scroll_grandparent->SetScrollChildren(scroll_children.release()); + scroll_grandparent->test_properties()->scroll_children.reset( + scroll_children.release()); gfx::Transform identity_transform; SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(), @@ -6898,15 +6815,18 @@ TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) { scroll_parent_clip->SetMasksToBounds(true); scroll_grandparent_clip->SetMasksToBounds(true); - scroll_child->SetScrollParent(scroll_parent); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + scroll_child->test_properties()->scroll_parent = scroll_parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child); - scroll_parent->SetScrollChildren(scroll_children.release()); + scroll_parent->test_properties()->scroll_children.reset( + scroll_children.release()); - scroll_parent_border->SetScrollParent(scroll_grandparent); + scroll_parent_border->test_properties()->scroll_parent = scroll_grandparent; scroll_children.reset(new std::set<LayerImpl*>); scroll_children->insert(scroll_parent_border); - scroll_grandparent->SetScrollChildren(scroll_children.release()); + scroll_grandparent->test_properties()->scroll_children.reset( + scroll_children.release()); gfx::Transform identity_transform; SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(), @@ -6978,12 +6898,12 @@ TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) { fixed->SetDrawsContent(true); child->SetDrawsContent(true); - root->SetIsContainerForFixedPositionLayers(true); - render_surface->SetForceRenderSurface(true); + render_surface->test_properties()->force_render_surface = true; + root->test_properties()->is_container_for_fixed_position_layers = true; LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); - fixed->SetPositionConstraint(constraint); + fixed->test_properties()->position_constraint = constraint; SetLayerPropertiesForTesting(root, gfx::Transform(), gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false); @@ -7038,23 +6958,24 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, &task_graph_runner); host_impl.CreatePendingTree(); - scoped_ptr<LayerImpl> root_ptr = + std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl.active_tree(), 1); LayerImpl* root = root_ptr.get(); - scoped_ptr<LayerImpl> container = + std::unique_ptr<LayerImpl> container = LayerImpl::Create(host_impl.active_tree(), 2); LayerImpl* container_layer = container.get(); - scoped_ptr<LayerImpl> scroller = + std::unique_ptr<LayerImpl> scroller = LayerImpl::Create(host_impl.active_tree(), 3); LayerImpl* scroll_layer = scroller.get(); - scoped_ptr<LayerImpl> fixed = LayerImpl::Create(host_impl.active_tree(), 4); + std::unique_ptr<LayerImpl> fixed = + LayerImpl::Create(host_impl.active_tree(), 4); LayerImpl* fixed_layer = fixed.get(); - container->SetIsContainerForFixedPositionLayers(true); + container->test_properties()->is_container_for_fixed_position_layers = true; LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); - fixed->SetPositionConstraint(constraint); + fixed->test_properties()->position_constraint = constraint; scroller->SetScrollClipLayer(container->id()); @@ -7093,14 +7014,12 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { SetScrollOffsetDelta(scroll_layer, scroll_delta); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list); root->layer_tree_impl() ->property_trees() ->transform_tree.set_source_to_parent_updates_allowed(false); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( container_layer->draw_properties().screen_space_transform, @@ -7123,11 +7042,9 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { gfx::Vector2dF rounded_scroll_delta(4.f, 8.f); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + root, root->bounds(), &render_surface_layer_list); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( container_layer->draw_properties().screen_space_transform, @@ -7153,11 +7070,9 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { SetScrollOffsetDelta(scroll_layer, scroll_delta); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + root, root->bounds(), &render_surface_layer_list); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( container_layer->draw_properties().screen_space_transform, @@ -7228,10 +7143,10 @@ TEST_F(LayerTreeHostCommonTest, class AnimationScaleFactorTrackingLayerImpl : public LayerImpl { public: - static scoped_ptr<AnimationScaleFactorTrackingLayerImpl> Create( + static std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> Create( LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr( + return base::WrapUnique( new AnimationScaleFactorTrackingLayerImpl(tree_impl, id)); } @@ -7254,13 +7169,13 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); gfx::Transform identity_matrix; - scoped_ptr<AnimationScaleFactorTrackingLayerImpl> grand_parent = + std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> grand_parent = AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<AnimationScaleFactorTrackingLayerImpl> parent = + std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> parent = AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 2); - scoped_ptr<AnimationScaleFactorTrackingLayerImpl> child = + std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> child = AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 3); - scoped_ptr<AnimationScaleFactorTrackingLayerImpl> grand_child = + std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> grand_child = AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 4); AnimationScaleFactorTrackingLayerImpl* parent_raw = parent.get(); @@ -7580,10 +7495,6 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { grand_child_raw->draw_properties().starting_animation_contents_scale); } -static int membership_id(LayerImpl* layer) { - return layer->draw_properties().last_drawn_render_surface_layer_list_id; -} - static void GatherDrawnLayers(LayerImplList* rsll, std::set<LayerImpl*>* drawn_layers) { for (LayerIterator it = LayerIterator::Begin(rsll), @@ -7611,13 +7522,15 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { &task_graph_runner); gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> grand_parent = + std::unique_ptr<LayerImpl> grand_parent = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> parent = LayerImpl::Create(host_impl.active_tree(), 3); - scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.active_tree(), 5); - scoped_ptr<LayerImpl> grand_child1 = + std::unique_ptr<LayerImpl> parent = + LayerImpl::Create(host_impl.active_tree(), 3); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl.active_tree(), 5); + std::unique_ptr<LayerImpl> grand_child1 = LayerImpl::Create(host_impl.active_tree(), 7); - scoped_ptr<LayerImpl> grand_child2 = + std::unique_ptr<LayerImpl> grand_child2 = LayerImpl::Create(host_impl.active_tree(), 9); LayerImpl* grand_parent_raw = grand_parent.get(); @@ -7653,13 +7566,12 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { // Start with nothing being drawn. ExecuteCalculateDrawProperties(grand_parent_raw); - int member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); std::set<LayerImpl*> expected; std::set<LayerImpl*> actual; @@ -7672,13 +7584,12 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { grand_child1_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); actual.clear(); @@ -7690,13 +7601,12 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { grand_child1_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child1_raw); @@ -7714,13 +7624,12 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { grand_child2_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child2_raw); @@ -7734,14 +7643,14 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(child_raw->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child2_raw); @@ -7756,22 +7665,24 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { EXPECT_EQ(expected, actual); // Add replica mask layer. - scoped_ptr<LayerImpl> replica_layer = + std::unique_ptr<LayerImpl> replica_layer = LayerImpl::Create(host_impl.active_tree(), 20); replica_layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 21)); child_raw->SetReplicaLayer(std::move(replica_layer)); child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(child_raw->mask_layer())); - EXPECT_EQ(member_id, membership_id(child_raw->replica_layer()->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child_raw->replica_layer() + ->mask_layer() + ->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child2_raw); @@ -7788,14 +7699,14 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { grand_child2_raw->SetDrawsContent(false); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(child_raw->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); actual.clear(); @@ -7807,14 +7718,14 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { child_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_EQ(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(child_raw->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(child_raw); @@ -7834,13 +7745,12 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { grand_child2_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_EQ(member_id, membership_id(grand_parent_raw)); - EXPECT_EQ(member_id, membership_id(parent_raw)); - EXPECT_EQ(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_TRUE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_parent_raw); @@ -7863,16 +7773,19 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.active_tree(), 1); LayerImpl* root_layer = root.get(); - scoped_ptr<LayerImpl> child1 = LayerImpl::Create(host_impl.active_tree(), 2); + std::unique_ptr<LayerImpl> child1 = + LayerImpl::Create(host_impl.active_tree(), 2); LayerImpl* child1_layer = child1.get(); - scoped_ptr<LayerImpl> child2 = LayerImpl::Create(host_impl.active_tree(), 3); + std::unique_ptr<LayerImpl> child2 = + LayerImpl::Create(host_impl.active_tree(), 3); LayerImpl* child2_layer = child2.get(); root->AddChild(std::move(child1)); root->AddChild(std::move(child2)); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; root->SetDrawsContent(true); host_impl.active_tree()->SetRootLayer(std::move(root)); @@ -7891,7 +7804,7 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { child1_layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 4)); child1_layer->SetDrawsContent(true); - scoped_ptr<LayerImpl> replica_layer = + std::unique_ptr<LayerImpl> replica_layer = LayerImpl::Create(host_impl.active_tree(), 5); replica_layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 6)); child1_layer->SetReplicaLayer(std::move(replica_layer)); @@ -7947,15 +7860,13 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, device_viewport_size, &render_surface_layer_list); inputs.page_scale_factor = page_scale_factor; inputs.can_adjust_raster_scales = true; inputs.page_scale_layer = root_layer; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_FLOAT_EQ(3.f, root_layer->GetIdealContentsScale()); EXPECT_FLOAT_EQ(9.f, child1_layer->GetIdealContentsScale()); @@ -7988,7 +7899,7 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { inputs.device_scale_factor = device_scale_factor; inputs.can_adjust_raster_scales = true; root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_FLOAT_EQ(12.f, root_layer->GetIdealContentsScale()); EXPECT_FLOAT_EQ(36.f, child1_layer->GetIdealContentsScale()); @@ -8036,15 +7947,13 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { gfx::Size device_viewport_size(768, 582); LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( root, device_viewport_size, identity_matrix, - &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + &render_surface_layer_list_impl); inputs.device_scale_factor = 2.f; inputs.page_scale_factor = 1.f; inputs.page_scale_layer = NULL; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // Layers in the root render surface have their visible content rect clipped // by the viewport. @@ -8103,16 +8012,14 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { sublayer->SetDrawsContent(true); LayerImplList layer_impl_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, &layer_impl_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, device_viewport_size, &layer_impl_list); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect()); root->SetBoundsDelta(gfx::Vector2dF(0.0, 50.0)); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); gfx::Rect affected_by_delta(0, 0, root_size.width(), root_size.height() + 50); @@ -8193,7 +8100,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { gfx::PointF(), gfx::Size(20, 20), true, false); root->SetMasksToBounds(true); - root->SetForceRenderSurface(true); + root->SetForceRenderSurfaceForTesting(true); animated->SetOpacity(0.f); AddOpacityTransitionToLayerWithPlayer(animated->id(), timeline(), 10.0, 0.f, @@ -8221,7 +8128,7 @@ TEST_F(LayerTreeHostCommonTest, surface->AddChild(descendant_of_animation); clip->SetMasksToBounds(true); - surface->SetForceRenderSurface(true); + surface->SetForceRenderSurfaceForTesting(true); host()->SetRootLayer(root); @@ -8282,24 +8189,21 @@ 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(); - root->AddChild(child); - child->AddChild(grandchild); + LayerImpl* root = root_layer(); + LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* grandchild = AddChild<LayerImpl>(child); gfx::Transform identity_transform; - SetLayerPropertiesForTesting(root.get(), identity_transform, gfx::Point3F(), + SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false); - SetLayerPropertiesForTesting(child.get(), identity_transform, gfx::Point3F(), + SetLayerPropertiesForTesting(child, identity_transform, gfx::Point3F(), + gfx::PointF(), gfx::Size(50, 50), true, false); + SetLayerPropertiesForTesting(grandchild, identity_transform, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false); - SetLayerPropertiesForTesting(grandchild.get(), identity_transform, - gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), - true, false); - host()->SetRootLayer(root); - AddAnimatedFilterToLayerWithPlayer(child->id(), timeline(), 10.0, 0.1f, 0.2f); - ExecuteCalculateDrawProperties(root.get()); + AddAnimatedFilterToLayerWithPlayer(child->id(), timeline_impl(), 10.0, 0.1f, + 0.2f); + ExecuteCalculateDrawProperties(root); EXPECT_TRUE(root->has_render_surface()); EXPECT_TRUE(child->has_render_surface()); @@ -8317,23 +8221,19 @@ TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) { // Verify that having a filter animation with a delayed start time creates a // render surface. TEST_F(LayerTreeHostCommonTest, DelayedFilterAnimationCreatesRenderSurface) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> child = Layer::Create(); - scoped_refptr<Layer> grandchild = Layer::Create(); - root->AddChild(child); - child->AddChild(grandchild); + LayerImpl* root = root_layer(); + LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* grandchild = AddChild<LayerImpl>(child); gfx::Transform identity_transform; - SetLayerPropertiesForTesting(root.get(), identity_transform, gfx::Point3F(), + SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false); - SetLayerPropertiesForTesting(child.get(), identity_transform, gfx::Point3F(), + SetLayerPropertiesForTesting(child, identity_transform, gfx::Point3F(), + gfx::PointF(), gfx::Size(50, 50), true, false); + SetLayerPropertiesForTesting(grandchild, identity_transform, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false); - SetLayerPropertiesForTesting(grandchild.get(), identity_transform, - gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), - true, false); - host()->SetRootLayer(root); - scoped_ptr<KeyframedFilterAnimationCurve> curve( + std::unique_ptr<KeyframedFilterAnimationCurve> curve( KeyframedFilterAnimationCurve::Create()); FilterOperations start_filters; start_filters.Append(FilterOperation::CreateBrightnessFilter(0.1f)); @@ -8343,13 +8243,14 @@ TEST_F(LayerTreeHostCommonTest, DelayedFilterAnimationCreatesRenderSurface) { FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); curve->AddKeyframe(FilterKeyframe::Create( base::TimeDelta::FromMilliseconds(100), end_filters, nullptr)); - scoped_ptr<Animation> animation = + std::unique_ptr<Animation> animation = Animation::Create(std::move(curve), 0, 1, TargetProperty::FILTER); - animation->set_fill_mode(Animation::FILL_MODE_NONE); + animation->set_fill_mode(Animation::FillMode::NONE); animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); - AddAnimationToLayerWithPlayer(child->id(), timeline(), std::move(animation)); - ExecuteCalculateDrawProperties(root.get()); + AddAnimationToLayerWithPlayer(child->id(), timeline_impl(), + std::move(animation)); + ExecuteCalculateDrawProperties(root); EXPECT_TRUE(root->has_render_surface()); EXPECT_TRUE(child->has_render_surface()); @@ -8386,13 +8287,13 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesAccountForFixedParentOffset) { true, false, false); root->SetMasksToBounds(true); - root->SetIsContainerForFixedPositionLayers(true); + root->test_properties()->is_container_for_fixed_position_layers = true; LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); - grandchild->SetPositionConstraint(constraint); + grandchild->test_properties()->position_constraint = constraint; grandchild->SetDrawsContent(true); - root->SetIsContainerForFixedPositionLayers(true); + root->test_properties()->is_container_for_fixed_position_layers = true; ExecuteCalculateDrawProperties(root); @@ -8421,13 +8322,13 @@ TEST_F(LayerTreeHostCommonTest, true, false, false); root->SetMasksToBounds(true); - child->SetIsContainerForFixedPositionLayers(true); + child->test_properties()->is_container_for_fixed_position_layers = true; LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); - grandchild->SetPositionConstraint(constraint); + grandchild->test_properties()->position_constraint = constraint; grandchild->SetDrawsContent(true); - root->SetIsContainerForFixedPositionLayers(true); + root->test_properties()->is_container_for_fixed_position_layers = true; ExecuteCalculateDrawProperties(root); @@ -8497,7 +8398,7 @@ TEST_F(LayerTreeHostCommonTest, OnlyApplyFixedPositioningOnce) { SetLayerPropertiesForTesting(root, identity, gfx::Point3F(), gfx::PointF(), gfx::Size(800, 800), true, false, true); - root->SetIsContainerForFixedPositionLayers(true); + root->test_properties()->is_container_for_fixed_position_layers = true; SetLayerPropertiesForTesting(frame_clip, translate_z, gfx::Point3F(), gfx::PointF(500, 100), gfx::Size(100, 100), true, @@ -8509,7 +8410,7 @@ TEST_F(LayerTreeHostCommonTest, OnlyApplyFixedPositioningOnce) { LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); - fixed->SetPositionConstraint(constraint); + fixed->test_properties()->position_constraint = constraint; fixed->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); @@ -8537,7 +8438,7 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) { gfx::PointF(100, 100), gfx::Size(50, 50), true, false, true); - root->SetIsContainerForFixedPositionLayers(true); + root->test_properties()->is_container_for_fixed_position_layers = true; root->SetDrawsContent(true); frame_clip->SetMasksToBounds(true); @@ -8549,7 +8450,7 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) { LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); - fixed->SetPositionConstraint(constraint); + fixed->test_properties()->position_constraint = constraint; fixed->SetMasksToBounds(true); fixed->SetDrawsContent(true); @@ -8604,7 +8505,7 @@ TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); - child->SetTransformOrigin(gfx::Point3F(10.f, 10.f, 10.f)); + child->test_properties()->transform_origin = gfx::Point3F(10.f, 10.f, 10.f); root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); @@ -8617,10 +8518,12 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { LayerImpl* scroll_child = AddChild<LayerImpl>(scroll_parent); scroll_child->SetDrawsContent(true); - scroll_child->SetScrollParent(scroll_parent); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + scroll_child->test_properties()->scroll_parent = scroll_parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child); - scroll_parent->SetScrollChildren(scroll_children.release()); + scroll_parent->test_properties()->scroll_children.reset( + scroll_children.release()); scroll_parent->SetDrawsContent(true); gfx::Transform identity_transform; @@ -8646,8 +8549,7 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect()); } -static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { -} +static void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} TEST_F(LayerTreeHostCommonTest, NumCopyRequestsInTargetSubtree) { // If the layer has a node in effect_tree, the return value of @@ -8738,10 +8640,10 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { // Add a transform animation with a start delay. Now, even though |child| has // a singular transform, the subtree should still get processed. int animation_id = 0; - scoped_ptr<Animation> animation = Animation::Create( - scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), + std::unique_ptr<Animation> animation = Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), animation_id, 1, TargetProperty::TRANSFORM); - animation->set_fill_mode(Animation::FILL_MODE_NONE); + animation->set_fill_mode(Animation::FillMode::NONE); animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddAnimationToLayerWithPlayer(child->id(), timeline(), std::move(animation)); ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); @@ -8767,9 +8669,9 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { // Add an opacity animation with a start delay. animation_id = 1; animation = Animation::Create( - scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), animation_id, 1, TargetProperty::OPACITY); - animation->set_fill_mode(Animation::FILL_MODE_NONE); + animation->set_fill_mode(Animation::FillMode::NONE); animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddAnimationToLayerWithExistingPlayer(child->id(), timeline(), std::move(animation)); @@ -8785,12 +8687,14 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { &task_graph_runner); gfx::Transform identity; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.active_tree(), 2); - scoped_ptr<LayerImpl> grandchild = + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl.active_tree(), 2); + std::unique_ptr<LayerImpl> grandchild = LayerImpl::Create(host_impl.active_tree(), 3); - scoped_ptr<FakePictureLayerImpl> greatgrandchild( + std::unique_ptr<FakePictureLayerImpl> greatgrandchild( FakePictureLayerImpl::Create(host_impl.active_tree(), 4)); child->SetDrawsContent(true); @@ -8844,10 +8748,10 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); child_ptr->SetTransform(identity); - child_ptr->SetHideLayerAndSubtree(true); + child_ptr->test_properties()->hide_layer_and_subtree = true; ExecuteCalculateDrawPropertiesWithPropertyTrees(root_ptr); EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); - child_ptr->SetHideLayerAndSubtree(false); + child_ptr->test_properties()->hide_layer_and_subtree = false; child_ptr->SetOpacity(0.f); ExecuteCalculateDrawPropertiesWithPropertyTrees(root_ptr); @@ -8875,7 +8779,7 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { // 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. - std::vector<scoped_ptr<CopyOutputRequest>> requests; + std::vector<std::unique_ptr<CopyOutputRequest>> requests; requests.push_back(CopyOutputRequest::CreateEmptyRequest()); grandchild_ptr->PassCopyRequests(&requests); @@ -8889,14 +8793,14 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { // A double sided render surface with backface visible should not be skipped grandchild_ptr->set_visible_layer_rect(gfx::Rect()); child_ptr->SetHasRenderSurface(true); - child_ptr->SetDoubleSided(true); + child_ptr->test_properties()->double_sided = true; child_ptr->SetTransform(rotate_back_and_translate); root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawPropertiesWithPropertyTrees(root_ptr); EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); child_ptr->SetTransform(identity); - scoped_ptr<KeyframedTransformAnimationCurve> curve( + std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); TransformOperations start; start.AppendTranslate(1.f, 2.f, 3.f); @@ -8908,14 +8812,14 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { TransformKeyframe::Create(base::TimeDelta(), start, nullptr)); curve->AddKeyframe(TransformKeyframe::Create( base::TimeDelta::FromSecondsD(1.0), operation, nullptr)); - scoped_ptr<Animation> transform_animation( + std::unique_ptr<Animation> transform_animation( Animation::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM)); scoped_refptr<AnimationPlayer> player(AnimationPlayer::Create(1)); - host_impl.active_tree()->animation_host()->RegisterPlayerForLayer( + host_impl.active_tree()->animation_host()->RegisterPlayerForElement( root_ptr->id(), player.get()); host_impl.active_tree() ->animation_host() - ->GetControllerForLayerId(root_ptr->id()) + ->GetElementAnimationsForElementId(root_ptr->id()) ->AddAnimation(std::move(transform_animation)); grandchild_ptr->set_visible_layer_rect(gfx::Rect()); child_ptr->SetScrollClipLayer(root_ptr->id()); @@ -8923,12 +8827,65 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { child_ptr->SetTransform(singular); root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawPropertiesWithPropertyTrees(root_ptr); - EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); - host_impl.active_tree()->animation_host()->UnregisterPlayerForLayer( + host_impl.active_tree()->animation_host()->UnregisterPlayerForElement( root_ptr->id(), player.get()); } +TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { + LayerImpl* root = root_layer(); + LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* grand_child = AddChild<LayerImpl>(child); + + gfx::Transform identity; + SetLayerPropertiesForTesting(root, identity, gfx::Point3F(), gfx::PointF(), + gfx::Size(10, 10), true, false, true); + SetLayerPropertiesForTesting(child, identity, gfx::Point3F(), gfx::PointF(), + gfx::Size(10, 10), true, false, false); + SetLayerPropertiesForTesting(grand_child, identity, gfx::Point3F(), + gfx::PointF(), gfx::Size(10, 10), true, false, + false); + + gfx::Transform singular; + singular.matrix().set(0, 0, 0); + singular.matrix().set(0, 1, 1); + + child->SetTransform(singular); + child->SetDrawsContent(true); + grand_child->SetDrawsContent(true); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve( + KeyframedTransformAnimationCurve::Create()); + TransformOperations start; + start.AppendTranslate(1.f, 2.f, 3.f); + gfx::Transform transform; + transform.Scale3d(1.0, 2.0, 3.0); + TransformOperations operation; + operation.AppendMatrix(transform); + curve->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), start, nullptr)); + curve->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operation, nullptr)); + std::unique_ptr<Animation> transform_animation( + Animation::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM)); + scoped_refptr<AnimationPlayer> player(AnimationPlayer::Create(1)); + host_impl()->active_tree()->animation_host()->RegisterPlayerForElement( + grand_child->id(), player.get()); + host_impl() + ->active_tree() + ->animation_host() + ->GetElementAnimationsForElementId(grand_child->id()) + ->AddAnimation(std::move(transform_animation)); + + ExecuteCalculateDrawProperties(root); + EXPECT_EQ(gfx::Rect(0, 0), grand_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); + + host_impl()->active_tree()->animation_host()->UnregisterPlayerForElement( + grand_child->id(), player.get()); +} + TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { FakeImplTaskRunnerProvider task_runner_provider; TestSharedBitmapManager shared_bitmap_manager; @@ -8938,12 +8895,14 @@ TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { gfx::Transform identity; host_impl.CreatePendingTree(); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); - scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2); - scoped_ptr<LayerImpl> grandchild = + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.pending_tree(), 1); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl.pending_tree(), 2); + std::unique_ptr<LayerImpl> grandchild = LayerImpl::Create(host_impl.pending_tree(), 3); - scoped_ptr<FakePictureLayerImpl> greatgrandchild( + std::unique_ptr<FakePictureLayerImpl> greatgrandchild( FakePictureLayerImpl::Create(host_impl.pending_tree(), 4)); child->SetDrawsContent(true); @@ -8972,21 +8931,21 @@ TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { ExecuteCalculateDrawPropertiesWithPropertyTrees(root_ptr); EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); - scoped_ptr<KeyframedFloatAnimationCurve> curve( + std::unique_ptr<KeyframedFloatAnimationCurve> curve( KeyframedFloatAnimationCurve::Create()); - scoped_ptr<TimingFunction> func = EaseTimingFunction::Create(); + std::unique_ptr<TimingFunction> func = EaseTimingFunction::Create(); curve->AddKeyframe( FloatKeyframe::Create(base::TimeDelta(), 0.9f, std::move(func))); curve->AddKeyframe( FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 0.3f, nullptr)); - scoped_ptr<Animation> animation( + std::unique_ptr<Animation> animation( Animation::Create(std::move(curve), 3, 3, TargetProperty::OPACITY)); scoped_refptr<AnimationPlayer> player(AnimationPlayer::Create(1)); - host_impl.active_tree()->animation_host()->RegisterPlayerForLayer( + host_impl.active_tree()->animation_host()->RegisterPlayerForElement( root_ptr->id(), player.get()); host_impl.active_tree() ->animation_host() - ->GetControllerForLayerId(root_ptr->id()) + ->GetElementAnimationsForElementId(root_ptr->id()) ->AddAnimation(std::move(animation)); root_ptr->SetOpacity(0); grandchild_ptr->set_visible_layer_rect(gfx::Rect()); @@ -8994,7 +8953,7 @@ TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { ExecuteCalculateDrawPropertiesWithPropertyTrees(root_ptr); EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); - host_impl.active_tree()->animation_host()->UnregisterPlayerForLayer( + host_impl.active_tree()->animation_host()->UnregisterPlayerForElement( root_ptr->id(), player.get()); } @@ -9013,11 +8972,11 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayer) { EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); child->set_visible_layer_rect(gfx::Rect()); - child->SetHideLayerAndSubtree(true); + child->test_properties()->hide_layer_and_subtree = true; root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); - child->SetHideLayerAndSubtree(false); + child->test_properties()->hide_layer_and_subtree = false; child->SetBounds(gfx::Size()); root->layer_tree_impl()->property_trees()->needs_rebuild = true; @@ -9026,13 +8985,13 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayer) { child->SetBounds(gfx::Size(10, 10)); gfx::Transform rotate; - child->SetDoubleSided(false); + child->test_properties()->double_sided = false; rotate.RotateAboutXAxis(180.f); child->SetTransform(rotate); root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); - child->SetDoubleSided(true); + child->test_properties()->double_sided = true; child->SetTransform(identity); child->SetOpacity(0.f); @@ -9075,30 +9034,6 @@ TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) { EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); } -TEST_F(LayerTreeHostCommonTest, InputHandlersRecursiveUpdateTest) { - // Ensure that the treewalk in LayertreeHostCommon:: - // PreCalculateMetaInformation updates input handlers correctly. - LayerImpl* root = root_layer(); - LayerImpl* child = AddChild<LayerImpl>(root); - - gfx::Transform identity; - - SetLayerPropertiesForTesting(root, identity, gfx::Point3F(), gfx::PointF(), - gfx::Size(100, 100), true, false, true); - SetLayerPropertiesForTesting(child, identity, gfx::Point3F(), gfx::PointF(), - gfx::Size(100, 100), true, false, false); - - EXPECT_EQ(root->layer_or_descendant_has_touch_handler(), false); - - child->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100)); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(root->layer_or_descendant_has_touch_handler(), true); - - child->SetTouchEventHandlerRegion(gfx::Rect()); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(root->layer_or_descendant_has_touch_handler(), false); -} - TEST_F(LayerTreeHostCommonTest, ResetPropertyTreeIndices) { gfx::Transform identity; gfx::Transform translate_z; @@ -9160,11 +9095,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { SetLayerPropertiesForTesting(test_layer, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), true, false); - root->SetForceRenderSurface(true); - significant_transform->SetForceRenderSurface(false); - layer_clips_subtree->SetForceRenderSurface(true); - render_surface->SetForceRenderSurface(true); - test_layer->SetForceRenderSurface(false); + root->test_properties()->force_render_surface = true; + significant_transform->test_properties()->force_render_surface = false; + layer_clips_subtree->test_properties()->force_render_surface = true; + render_surface->test_properties()->force_render_surface = true; + test_layer->test_properties()->force_render_surface = false; ExecuteCalculateDrawProperties(root); TransformTree transform_tree = @@ -9235,10 +9170,10 @@ TEST_F(LayerTreeHostCommonTest, clip_parent->SetMasksToBounds(true); test_layer->SetDrawsContent(true); - render_surface->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + render_surface->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(render_surface); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), true, false, true); @@ -9258,7 +9193,7 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawProperties(root); EXPECT_TRUE(test_layer->is_clipped()); - EXPECT_FALSE(test_layer->render_target()->render_surface()->is_clipped()); + EXPECT_FALSE(test_layer->render_target()->is_clipped()); EXPECT_EQ(gfx::Rect(-2, -2, 30, 30), test_layer->clip_rect()); EXPECT_EQ(gfx::Rect(28, 28), test_layer->drawable_content_rect()); } @@ -9278,10 +9213,10 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetDrawsContent(true); child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 10), true, false, true); @@ -9318,10 +9253,10 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetDrawsContent(true); test_layer1->SetDrawsContent(true); test_layer2->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), true, false, @@ -9361,10 +9296,10 @@ TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { render_surface->SetDrawsContent(true); clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false, @@ -9405,10 +9340,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { unclipped_desc_surface->SetDrawsContent(true); unclipped_desc_surface2->SetDrawsContent(true); clipped_surface->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); gfx::Transform identity_matrix; SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), @@ -9459,10 +9394,10 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { clip_child->SetDrawsContent(true); unclipped_desc_surface->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); gfx::Transform identity_matrix; gfx::Transform translate; @@ -9504,10 +9439,10 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { clip_child->SetDrawsContent(true); unclipped_desc_surface->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); gfx::Transform identity_matrix; gfx::Transform scale; @@ -9575,10 +9510,10 @@ TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { render_surface->SetMasksToBounds(true); render_surface->SetDrawsContent(true); clip_child->SetDrawsContent(true); - clip_child->SetClipParent(clip_parent); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = clip_parent; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - clip_parent->SetClipChildren(clip_children.release()); + clip_parent->test_properties()->clip_children.reset(clip_children.release()); SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30), true, false, @@ -9642,11 +9577,11 @@ TEST_F(LayerTreeHostCommonTest, SubtreeIsHiddenTest) { gfx::PointF(), gfx::Size(30, 30), true, false, true); - hidden->SetHideLayerAndSubtree(true); + hidden->test_properties()->hide_layer_and_subtree = true; ExecuteCalculateDrawProperties(root); EXPECT_TRUE(test->IsHidden()); - hidden->SetHideLayerAndSubtree(false); + hidden->test_properties()->hide_layer_and_subtree = false; root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_FALSE(test->IsHidden()); @@ -9659,10 +9594,10 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { LayerImpl* clip_child = AddChild<LayerImpl>(render_surface2); const gfx::Transform identity_matrix; - clip_child->SetClipParent(root); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + clip_child->test_properties()->clip_parent = root; + std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); clip_children->insert(clip_child); - root->SetClipChildren(clip_children.release()); + root->test_properties()->clip_children.reset(clip_children.release()); root->SetMasksToBounds(true); render_surface1->SetDrawsContent(true); render_surface2->SetDrawsContent(true); @@ -9814,6 +9749,168 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { EXPECT_TRUE(root_in_rsll); } +TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { + const gfx::Transform identity_matrix; + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<LayerWithForcedDrawsContent> child = + make_scoped_refptr(new LayerWithForcedDrawsContent()); + root->AddChild(child); + + host()->SetRootLayer(root); + + 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(20, 20), true, false); + + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + + // Changing the opacity from 1 to non-1 value should trigger rebuild of + // property trees as a new effect node will be created. + child->SetOpacity(0.5f); + PropertyTrees* property_trees = host()->property_trees(); + EXPECT_TRUE(property_trees->needs_rebuild); + + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + EXPECT_NE(property_trees->effect_id_to_index_map.find(child->id()), + property_trees->effect_id_to_index_map.end()); + + // child already has an effect node. Changing its opacity shouldn't trigger + // a property trees rebuild. + child->SetOpacity(0.8f); + property_trees = host()->property_trees(); + EXPECT_FALSE(property_trees->needs_rebuild); + + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + EXPECT_NE(property_trees->effect_id_to_index_map.find(child->id()), + property_trees->effect_id_to_index_map.end()); + + // Changing the opacity from non-1 value to 1 should trigger a rebuild of + // property trees as the effect node may no longer be needed. + child->SetOpacity(1.f); + property_trees = host()->property_trees(); + EXPECT_TRUE(property_trees->needs_rebuild); + + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + EXPECT_EQ(property_trees->effect_id_to_index_map.find(child->id()), + property_trees->effect_id_to_index_map.end()); +} + +TEST_F(LayerTreeHostCommonTest, OpacityAnimationsTrackingTest) { + const gfx::Transform identity_matrix; + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<LayerWithForcedDrawsContent> animated = + make_scoped_refptr(new LayerWithForcedDrawsContent()); + root->AddChild(animated); + + host()->SetRootLayer(root); + + SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(animated.get(), identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(20, 20), true, false); + + root->SetForceRenderSurfaceForTesting(true); + animated->SetOpacity(0.f); + + scoped_refptr<AnimationPlayer> player = + AnimationPlayer::Create(AnimationIdProvider::NextPlayerId()); + timeline()->AttachPlayer(player); + player->AttachElement(animated->id()); + + int animation_id = 0; + std::unique_ptr<Animation> animation = Animation::Create( + std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), + animation_id, 1, TargetProperty::OPACITY); + animation->set_fill_mode(Animation::FillMode::NONE); + animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); + Animation* animation_ptr = animation.get(); + AddAnimationToLayerWithExistingPlayer(animated->id(), timeline(), + std::move(animation)); + + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + + EffectTree& tree = root->layer_tree_host()->property_trees()->effect_tree; + EffectNode* node = tree.Node(animated->effect_tree_index()); + EXPECT_FALSE(node->data.is_currently_animating_opacity); + EXPECT_TRUE(node->data.has_potential_opacity_animation); + + animation_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0)); + root->layer_tree_host()->AnimateLayers( + base::TimeTicks::FromInternalValue(std::numeric_limits<int64_t>::max())); + node = tree.Node(animated->effect_tree_index()); + EXPECT_TRUE(node->data.is_currently_animating_opacity); + EXPECT_TRUE(node->data.has_potential_opacity_animation); + + player->AbortAnimations(TargetProperty::OPACITY, false /*needs_completion*/); + node = tree.Node(animated->effect_tree_index()); + EXPECT_FALSE(node->data.is_currently_animating_opacity); + EXPECT_FALSE(node->data.has_potential_opacity_animation); +} + +TEST_F(LayerTreeHostCommonTest, TransformAnimationsTrackingTest) { + const gfx::Transform identity_matrix; + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<LayerWithForcedDrawsContent> animated = + make_scoped_refptr(new LayerWithForcedDrawsContent()); + root->AddChild(animated); + + host()->SetRootLayer(root); + + SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(100, 100), true, false); + SetLayerPropertiesForTesting(animated.get(), identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(20, 20), true, false); + + root->SetForceRenderSurfaceForTesting(true); + + scoped_refptr<AnimationPlayer> player = + AnimationPlayer::Create(AnimationIdProvider::NextPlayerId()); + timeline()->AttachPlayer(player); + player->AttachElement(animated->id()); + + std::unique_ptr<KeyframedTransformAnimationCurve> curve( + KeyframedTransformAnimationCurve::Create()); + TransformOperations start; + start.AppendTranslate(1.f, 2.f, 3.f); + gfx::Transform transform; + transform.Scale3d(1.0, 2.0, 3.0); + TransformOperations operation; + operation.AppendMatrix(transform); + curve->AddKeyframe( + TransformKeyframe::Create(base::TimeDelta(), start, nullptr)); + curve->AddKeyframe(TransformKeyframe::Create( + base::TimeDelta::FromSecondsD(1.0), operation, nullptr)); + std::unique_ptr<Animation> animation( + Animation::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM)); + animation->set_fill_mode(Animation::FillMode::NONE); + animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); + Animation* animation_ptr = animation.get(); + AddAnimationToLayerWithExistingPlayer(animated->id(), timeline(), + std::move(animation)); + + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + + TransformTree& tree = + root->layer_tree_host()->property_trees()->transform_tree; + TransformNode* node = tree.Node(animated->transform_tree_index()); + EXPECT_FALSE(node->data.is_currently_animating); + EXPECT_TRUE(node->data.has_potential_animation); + + animation_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0)); + root->layer_tree_host()->AnimateLayers( + base::TimeTicks::FromInternalValue(std::numeric_limits<int64_t>::max())); + node = tree.Node(animated->transform_tree_index()); + EXPECT_TRUE(node->data.is_currently_animating); + EXPECT_TRUE(node->data.has_potential_animation); + + player->AbortAnimations(TargetProperty::TRANSFORM, + false /*needs_completion*/); + node = tree.Node(animated->transform_tree_index()); + EXPECT_FALSE(node->data.is_currently_animating); + EXPECT_FALSE(node->data.has_potential_animation); +} + TEST_F(LayerTreeHostCommonTest, SerializeScrollUpdateInfo) { LayerTreeHostCommon::ScrollUpdateInfo scroll; scroll.layer_id = 2; diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 0e7a5806ea4..faa4639450e 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -15,8 +15,10 @@ #include <utility> #include "base/auto_reset.h" +#include "base/bind.h" #include "base/containers/small_map.h" #include "base/json/json_writer.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" #include "base/numerics/safe_conversions.h" #include "base/stl_util.h" @@ -24,6 +26,8 @@ #include "base/trace_event/trace_event_argument.h" #include "cc/animation/animation_events.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/timing_function.h" #include "cc/base/histograms.h" #include "cc/base/math_util.h" @@ -59,13 +63,13 @@ #include "cc/quads/shared_quad_state.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/texture_draw_quad.h" -#include "cc/raster/bitmap_tile_task_worker_pool.h" +#include "cc/raster/bitmap_raster_buffer_provider.h" +#include "cc/raster/gpu_raster_buffer_provider.h" #include "cc/raster/gpu_rasterizer.h" -#include "cc/raster/gpu_tile_task_worker_pool.h" -#include "cc/raster/one_copy_tile_task_worker_pool.h" +#include "cc/raster/one_copy_raster_buffer_provider.h" +#include "cc/raster/raster_buffer_provider.h" #include "cc/raster/synchronous_task_graph_runner.h" -#include "cc/raster/tile_task_worker_pool.h" -#include "cc/raster/zero_copy_tile_task_worker_pool.h" +#include "cc/raster/zero_copy_raster_buffer_provider.h" #include "cc/resources/memory_history.h" #include "cc/resources/resource_pool.h" #include "cc/resources/ui_resource_bitmap.h" @@ -75,6 +79,7 @@ #include "cc/tiles/picture_layer_tiling.h" #include "cc/tiles/raster_tile_priority_queue.h" #include "cc/tiles/software_image_decode_controller.h" +#include "cc/tiles/tile_task_manager.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/latency_info_swap_promise_monitor.h" @@ -119,8 +124,8 @@ class ViewportAnchor { gfx::Vector2dF delta = viewport_in_content_coordinates_.DeltaFrom(viewport_location); - delta = outer_->ScrollBy(delta); - inner_->ScrollBy(delta); + delta = inner_->ScrollBy(delta); + outer_->ScrollBy(delta); } private: @@ -140,7 +145,7 @@ void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { } bool IsWheelBasedScroll(InputHandler::ScrollInputType type) { - return type == InputHandler::WHEEL || type == InputHandler::ANIMATED_WHEEL; + return type == InputHandler::WHEEL; } enum ScrollThread { MAIN_THREAD, CC_THREAD }; @@ -164,7 +169,7 @@ LayerTreeHostImpl::FrameData::FrameData() LayerTreeHostImpl::FrameData::~FrameData() {} -scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( +std::unique_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( const LayerTreeSettings& settings, LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, @@ -173,7 +178,7 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, TaskGraphRunner* task_graph_runner, int id) { - return make_scoped_ptr(new LayerTreeHostImpl( + return base::WrapUnique(new LayerTreeHostImpl( settings, client, task_runner_provider, rendering_stats_instrumentation, shared_bitmap_manager, gpu_memory_buffer_manager, task_graph_runner, id)); } @@ -226,7 +231,6 @@ LayerTreeHostImpl::LayerTreeHostImpl( texture_mailbox_deleter_(new TextureMailboxDeleter(GetTaskRunner())), max_memory_needed_bytes_(0), resourceless_software_draw_(false), - output_is_secure_(false), animation_host_(), rendering_stats_instrumentation_(rendering_stats_instrumentation), micro_benchmark_controller_(this), @@ -236,7 +240,8 @@ LayerTreeHostImpl::LayerTreeHostImpl( id_(id), requires_high_res_to_draw_(false), is_likely_to_require_a_draw_(false), - frame_timing_tracker_(FrameTimingTracker::Create(this)) { + mutator_(nullptr), + has_fixed_raster_scale_blurry_content_(false) { animation_host_ = AnimationHost::Create(ThreadInstance::IMPL); animation_host_->SetMutatorHostClient(this); animation_host_->SetSupportsScrollAnimations(SupportsImplScrolling()); @@ -277,7 +282,7 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { scroll_elasticity_helper_.reset(); // The layer trees must be destroyed before the layer tree host. We've - // made a contract with our animation controllers that the registrar + // made a contract with our animation controllers that the animation_host // will outlive them, and we must make good. if (recycle_tree_) recycle_tree_->Shutdown(); @@ -349,6 +354,9 @@ void LayerTreeHostImpl::CommitComplete() { UpdateTreeResourcesForGpuRasterizationIfNeeded(); sync_tree()->set_needs_update_draw_properties(); + // Advance the attempted scale change history before updating draw properties. + fixed_raster_scale_attempted_scale_change_history_ <<= 1; + // 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 @@ -494,7 +502,7 @@ void LayerTreeHostImpl::StartPageScaleAnimation( gfx::SizeF(active_tree_->InnerViewportContainerLayer()->bounds()); // Easing constants experimentally determined. - scoped_ptr<TimingFunction> timing_function = + std::unique_ptr<TimingFunction> timing_function = CubicBezierTimingFunction::Create(.8, 0, .3, .9); // TODO(miletus) : Pass in ScrollOffset. @@ -587,10 +595,10 @@ bool LayerTreeHostImpl::DoTouchEventsBlockScrollAt( return layer_impl != NULL; } -scoped_ptr<SwapPromiseMonitor> +std::unique_ptr<SwapPromiseMonitor> LayerTreeHostImpl::CreateLatencyInfoSwapPromiseMonitor( ui::LatencyInfo* latency) { - return make_scoped_ptr( + return base::WrapUnique( new LatencyInfoSwapPromiseMonitor(latency, NULL, this)); } @@ -604,7 +612,7 @@ ScrollElasticityHelper* LayerTreeHostImpl::CreateScrollElasticityHelper() { } void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate( - scoped_ptr<SwapPromise> swap_promise) { + std::unique_ptr<SwapPromise> swap_promise) { swap_promises_for_main_thread_scroll_update_.push_back( std::move(swap_promise)); } @@ -623,11 +631,9 @@ void LayerTreeHostImpl::TrackDamageForAllSurfaces( RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); DCHECK(render_surface); render_surface->damage_tracker()->UpdateDamageTrackingState( - render_surface->layer_list(), - render_surface_layer->id(), + render_surface->layer_list(), render_surface, render_surface->SurfacePropertyChangedOnlyFromDescendant(), - render_surface->content_rect(), - render_surface_layer->mask_layer(), + render_surface->content_rect(), render_surface_layer->mask_layer(), render_surface_layer->filters()); } } @@ -653,7 +659,7 @@ void LayerTreeHostImpl::FrameData::AsValueInto( } void LayerTreeHostImpl::FrameData::AppendRenderPass( - scoped_ptr<RenderPass> render_pass) { + std::unique_ptr<RenderPass> render_pass) { render_passes.push_back(std::move(render_pass)); } @@ -757,7 +763,7 @@ static RenderPass* FindRenderPassById(const RenderPassList& list, RenderPassId id) { auto it = std::find_if( list.begin(), list.end(), - [id](const scoped_ptr<RenderPass>& p) { return p->id == id; }); + [id](const std::unique_ptr<RenderPass>& p) { return p->id == id; }); return it == list.end() ? nullptr : it->get(); } @@ -816,6 +822,13 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( render_surface->AppendRenderPasses(frame); } + // Damage rects for non-root passes aren't meaningful, so set them to be + // equal to the output rect. + for (size_t i = 0; i + 1 < frame->render_passes.size(); ++i) { + RenderPass* pass = frame->render_passes[i].get(); + pass->damage_rect = pass->output_rect; + } + // When we are displaying the HUD, change the root damage rect to cover the // entire root surface. This will disable partial-swap/scissor optimizations // that would prevent the HUD from updating, since the HUD does not cause @@ -897,16 +910,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( frame->will_draw_layers.push_back(*it); it->AppendQuads(target_render_pass, &append_quads_data); - - // 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()) { - if (request.rect().Intersects(it->visible_layer_rect())) { - frame->composite_events.push_back( - FrameTimingTracker::FrameAndRectIds( - active_tree_->source_frame_number(), request.id())); - } - } } ++layers_drawn; @@ -982,7 +985,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( // Any copy requests left in the tree are not going to get serviced, and // should be aborted. - std::vector<scoped_ptr<CopyOutputRequest>> requests_to_abort; + std::vector<std::unique_ptr<CopyOutputRequest>> requests_to_abort; while (!active_tree_->LayersWithCopyOutputRequest().empty()) { LayerImpl* layer = active_tree_->LayersWithCopyOutputRequest().back(); layer->TakeCopyRequestsAndTransformToTarget(&requests_to_abort); @@ -1062,10 +1065,6 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { if (input_handler_client_) input_handler_client_->ReconcileElasticOverscrollAndRootScroll(); - UMA_HISTOGRAM_CUSTOM_COUNTS( - "Compositing.NumActiveLayers", - base::saturated_cast<int>(active_tree_->NumLayers()), 1, 400, 20); - if (const char* client_name = GetClientNameForMetrics()) { size_t total_picture_memory = 0; for (const PictureLayerImpl* layer : active_tree()->picture_layers()) @@ -1078,6 +1077,11 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { client_name), base::saturated_cast<int>(total_picture_memory / 1024)); } + // GetClientNameForMetrics only returns one non-null value over the lifetime + // of the process, so this histogram name is runtime constant. + UMA_HISTOGRAM_CUSTOM_COUNTS( + base::StringPrintf("Compositing.%s.NumActiveLayers", client_name), + base::saturated_cast<int>(active_tree_->NumLayers()), 1, 400, 20); } bool update_lcd_text = false; @@ -1238,14 +1242,21 @@ 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 > 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 */); + // allow the worker context and image decode controller to retain allocated + // resources. Notify them here. If the memory policy has become zero, we'll + // handle the notification in NotifyAllTileTasksCompleted, after + // in-progress work finishes. + if (output_surface_) { + output_surface_->SetWorkerContextShouldAggressivelyFreeResources( + false /* aggressively_free_resources */); + } + + if (image_decode_controller_) { + image_decode_controller_->SetShouldAggressivelyFreeResources( + false /* aggressively_free_resources */); + } } DCHECK(resource_pool_); @@ -1265,7 +1276,7 @@ void LayerTreeHostImpl::DidModifyTilePriorities() { client_->SetNeedsPrepareTilesOnImplThread(); } -scoped_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue( +std::unique_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue( TreePriority tree_priority, RasterTilePriorityQueue::Type type) { TRACE_EVENT0("disabled-by-default-cc.debug", @@ -1278,12 +1289,13 @@ scoped_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue( tree_priority, type); } -scoped_ptr<EvictionTilePriorityQueue> LayerTreeHostImpl::BuildEvictionQueue( - TreePriority tree_priority) { +std::unique_ptr<EvictionTilePriorityQueue> +LayerTreeHostImpl::BuildEvictionQueue(TreePriority tree_priority) { TRACE_EVENT0("disabled-by-default-cc.debug", "LayerTreeHostImpl::BuildEvictionQueue"); - scoped_ptr<EvictionTilePriorityQueue> queue(new EvictionTilePriorityQueue); + std::unique_ptr<EvictionTilePriorityQueue> queue( + new EvictionTilePriorityQueue); queue->Build(active_tree_->picture_layers(), pending_tree_ ? pending_tree_->picture_layers() : std::vector<PictureLayerImpl*>(), @@ -1316,9 +1328,18 @@ void LayerTreeHostImpl::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 */); + if (global_tile_state_.hard_memory_limit_in_bytes == 0) { + // Free image decode controller resources before worker context resources. + // This ensures that the imaged decode controller has released all Skia refs + // at the time Skia's cleanup executes (within worker context's cleanup). + if (image_decode_controller_) { + image_decode_controller_->SetShouldAggressivelyFreeResources( + true /* aggressively_free_resources */); + } + if (output_surface_) { + output_surface_->SetWorkerContextShouldAggressivelyFreeResources( + true /* aggressively_free_resources */); + } } } @@ -1594,11 +1615,6 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) { base::TimeTicks frame_begin_time = CurrentBeginFrameArgs().frame_time; DCHECK(CanDraw()); - if (!frame->composite_events.empty()) { - frame_timing_tracker_->SaveTimeStamps(frame_begin_time, - frame->composite_events); - } - if (frame->has_no_damage) { TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD); DCHECK(!resourceless_software_draw_); @@ -1626,12 +1642,10 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) { if (is_new_trace) { if (pending_tree_) { LayerTreeHostCommon::CallFunctionForEveryLayer( - pending_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }, - CallFunctionLayerType::ALL_LAYERS); + pending_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); } LayerTreeHostCommon::CallFunctionForEveryLayer( - active_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }, - CallFunctionLayerType::ALL_LAYERS); + active_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); } { @@ -1656,9 +1670,15 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) { bool disable_picture_quad_image_filtering = IsActivelyScrolling() || animation_host_->NeedsAnimateLayers(); - scoped_ptr<SoftwareRenderer> temp_software_renderer = + // We must disable the image hijack canvas when using GPU rasterization but + // performing a resourceless software draw. Otherwise, we will attempt to + // use the GPU ImageDecodeController during software raster. + bool use_image_hijack_canvas = !use_gpu_rasterization_; + + std::unique_ptr<SoftwareRenderer> temp_software_renderer = SoftwareRenderer::Create(this, &settings_.renderer_settings, - output_surface_, NULL); + output_surface_, nullptr, + use_image_hijack_canvas); temp_software_renderer->DrawFrame( &frame->render_passes, active_tree_->device_scale_factor(), DeviceViewport(), DeviceClip(), disable_picture_quad_image_filtering); @@ -1678,7 +1698,7 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) { (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()-> DidDrawDamagedArea(); } - active_tree_->ResetAllChangeTracking(PropertyTrees::ResetFlags::ALL_TREES); + active_tree_->ResetAllChangeTracking(); active_tree_->set_has_ever_been_drawn(true); devtools_instrumentation::DidDrawFrame(id_); @@ -1962,23 +1982,24 @@ void LayerTreeHostImpl::ActivateSyncTree() { active_tree_.get()); } - // We need to preserve the damage status of property trees on active tree. - // We do this by pushing the damage status from active tree property trees - // to pending tree property trees. + // Property trees may store damage status. We preserve the active tree + // damage status by pushing the damage status from active tree property + // trees to pending tree property trees or by moving it onto the layers. if (active_tree_->property_trees()->changed) { if (pending_tree_->property_trees()->sequence_number == active_tree_->property_trees()->sequence_number) active_tree_->property_trees()->PushChangeTrackingTo( pending_tree_->property_trees()); else - active_tree_->root_layer()->PushLayerPropertyChangedForSubtree(); + active_tree_->MoveChangeTrackingToLayers(); } + active_tree_->property_trees()->PushOpacityIfNeeded( + pending_tree_->property_trees()); TreeSynchronizer::PushLayerProperties(pending_tree(), active_tree()); pending_tree_->PushPropertiesTo(active_tree_.get()); if (pending_tree_->root_layer()) - pending_tree_->property_trees()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + pending_tree_->property_trees()->ResetAllChangeTracking(); // Now that we've synced everything from the pending tree to the active // tree, rename the pending tree the recycle tree so we can reuse it on the @@ -2011,7 +2032,7 @@ void LayerTreeHostImpl::ActivateSyncTree() { if (!tree_activation_callback_.is_null()) tree_activation_callback_.Run(); - scoped_ptr<PendingPageScaleAnimation> pending_page_scale_animation = + std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation = active_tree_->TakePendingPageScaleAnimation(); if (pending_page_scale_animation) { StartPageScaleAnimation( @@ -2115,9 +2136,9 @@ void LayerTreeHostImpl::CreateAndSetRenderer() { resource_provider_.get(), texture_mailbox_deleter_.get(), settings_.renderer_settings.highp_threshold_min); } else if (output_surface_->software_device()) { - renderer_ = - SoftwareRenderer::Create(this, &settings_.renderer_settings, - output_surface_, resource_provider_.get()); + renderer_ = SoftwareRenderer::Create( + this, &settings_.renderer_settings, output_surface_, + resource_provider_.get(), true /* use_image_hijack_canvas */); } DCHECK(renderer_); @@ -2134,51 +2155,58 @@ void LayerTreeHostImpl::CreateAndSetRenderer() { } void LayerTreeHostImpl::CreateTileManagerResources() { - CreateResourceAndTileTaskWorkerPool(&tile_task_worker_pool_, &resource_pool_); + std::unique_ptr<RasterBufferProvider> raster_buffer_provider; + CreateResourceAndRasterBufferProvider(&raster_buffer_provider, + &resource_pool_); if (use_gpu_rasterization_) { - image_decode_controller_ = make_scoped_ptr(new GpuImageDecodeController); + image_decode_controller_ = base::WrapUnique(new GpuImageDecodeController( + output_surface_->worker_context_provider(), + settings_.renderer_settings.preferred_tile_format)); } else { image_decode_controller_ = - make_scoped_ptr(new SoftwareImageDecodeController( + base::WrapUnique(new SoftwareImageDecodeController( settings_.renderer_settings.preferred_tile_format)); } + // Pass the single-threaded synchronous task graph runner to the worker pool + // if we're in synchronous single-threaded mode. + TaskGraphRunner* task_graph_runner = task_graph_runner_; + if (is_synchronous_single_threaded_) { + DCHECK(!single_thread_synchronous_task_graph_runner_); + single_thread_synchronous_task_graph_runner_.reset( + new SynchronousTaskGraphRunner); + task_graph_runner = single_thread_synchronous_task_graph_runner_.get(); + } + + tile_task_manager_ = TileTaskManagerImpl::Create( + std::move(raster_buffer_provider), task_graph_runner); + // TODO(vmpstr): Initialize tile task limit at ctor time. tile_manager_->SetResources( - resource_pool_.get(), tile_task_worker_pool_->AsTileTaskRunner(), - image_decode_controller_.get(), + resource_pool_.get(), image_decode_controller_.get(), + tile_task_manager_.get(), is_synchronous_single_threaded_ ? std::numeric_limits<size_t>::max() : settings_.scheduled_raster_task_limit, use_gpu_rasterization_); UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); } -void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( - scoped_ptr<TileTaskWorkerPool>* tile_task_worker_pool, - scoped_ptr<ResourcePool>* resource_pool) { +void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( + std::unique_ptr<RasterBufferProvider>* raster_buffer_provider, + std::unique_ptr<ResourcePool>* resource_pool) { DCHECK(GetTaskRunner()); // TODO(vmpstr): Make this a DCHECK (or remove) when crbug.com/419086 is // resolved. CHECK(resource_provider_); - // Pass the single-threaded synchronous task graph runner to the worker pool - // if we're in synchronous single-threaded mode. - TaskGraphRunner* task_graph_runner = task_graph_runner_; - if (is_synchronous_single_threaded_) { - DCHECK(!single_thread_synchronous_task_graph_runner_); - single_thread_synchronous_task_graph_runner_.reset( - new SynchronousTaskGraphRunner); - task_graph_runner = single_thread_synchronous_task_graph_runner_.get(); - } - ContextProvider* context_provider = output_surface_->context_provider(); if (!context_provider) { *resource_pool = ResourcePool::Create(resource_provider_.get(), GetTaskRunner()); - *tile_task_worker_pool = BitmapTileTaskWorkerPool::Create( - GetTaskRunner(), task_graph_runner, resource_provider_.get()); + *raster_buffer_provider = + BitmapRasterBufferProvider::Create(resource_provider_.get()); return; } @@ -2190,10 +2218,9 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0; - *tile_task_worker_pool = GpuTileTaskWorkerPool::Create( - GetTaskRunner(), task_graph_runner, context_provider, - resource_provider_.get(), settings_.use_distance_field_text, - msaa_sample_count); + *raster_buffer_provider = GpuRasterBufferProvider::Create( + context_provider, resource_provider_.get(), + settings_.use_distance_field_text, msaa_sample_count); return; } @@ -2212,8 +2239,8 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( *resource_pool = ResourcePool::CreateForGpuMemoryBufferResources( resource_provider_.get(), GetTaskRunner()); - *tile_task_worker_pool = ZeroCopyTileTaskWorkerPool::Create( - GetTaskRunner(), task_graph_runner, resource_provider_.get(), + *raster_buffer_provider = ZeroCopyRasterBufferProvider::Create( + resource_provider_.get(), settings_.renderer_settings.preferred_tile_format); return; } @@ -2221,42 +2248,27 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( *resource_pool = ResourcePool::Create(resource_provider_.get(), GetTaskRunner()); - int max_copy_texture_chromium_size = context_provider->ContextCapabilities() - .gpu.max_copy_texture_chromium_size; + const int max_copy_texture_chromium_size = + context_provider->ContextCapabilities().max_copy_texture_chromium_size; - *tile_task_worker_pool = OneCopyTileTaskWorkerPool::Create( - GetTaskRunner(), task_graph_runner, context_provider, - resource_provider_.get(), max_copy_texture_chromium_size, - settings_.use_partial_raster, settings_.max_staging_buffer_usage_in_bytes, + *raster_buffer_provider = OneCopyRasterBufferProvider::Create( + GetTaskRunner(), context_provider, resource_provider_.get(), + max_copy_texture_chromium_size, settings_.use_partial_raster, + settings_.max_staging_buffer_usage_in_bytes, settings_.renderer_settings.preferred_tile_format); } -void LayerTreeHostImpl::RecordMainFrameTiming( - const BeginFrameArgs& start_of_main_frame_args, - const BeginFrameArgs& expected_next_main_frame_args) { - std::vector<int64_t> request_ids; - active_tree_->GatherFrameTimingRequestIds(&request_ids); - if (request_ids.empty()) - return; - - base::TimeTicks start_time = start_of_main_frame_args.frame_time; - base::TimeTicks end_time = expected_next_main_frame_args.frame_time; - frame_timing_tracker_->SaveMainFrameTimeStamps( - request_ids, start_time, end_time, active_tree_->source_frame_number()); -} - -void LayerTreeHostImpl::PostFrameTimingEvents( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) { - client_->PostFrameTimingEventsOnImplThread(std::move(composite_events), - std::move(main_frame_events)); +void LayerTreeHostImpl::SetLayerTreeMutator(LayerTreeMutator* mutator) { + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), + "LayerTreeHostImpl::SetLayerTreeMutator"); + mutator_ = mutator; } void LayerTreeHostImpl::CleanUpTileManagerAndUIResources() { ClearUIResources(); tile_manager_->FinishTasksAndCleanUp(); resource_pool_ = nullptr; - tile_task_worker_pool_ = nullptr; + tile_task_manager_ = nullptr; single_thread_synchronous_task_graph_runner_ = nullptr; image_decode_controller_ = nullptr; } @@ -2281,6 +2293,10 @@ void LayerTreeHostImpl::ReleaseOutputSurface() { output_surface_->DetachFromClient(); output_surface_ = nullptr; } + + // We don't know if the next OutputSurface will support GPU rasterization. + // Make sure to clear the flag so that we force a re-computation. + use_gpu_rasterization_ = false; } bool LayerTreeHostImpl::InitializeRenderer(OutputSurface* output_surface) { @@ -2343,6 +2359,10 @@ void LayerTreeHostImpl::CommitVSyncParameters(base::TimeTicks timebase, client_->CommitVSyncParameters(timebase, interval); } +void LayerTreeHostImpl::SetBeginFrameSource(BeginFrameSource* source) { + client_->SetBeginFrameSource(source); +} + void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { if (device_viewport_size == device_viewport_size_) return; @@ -2636,8 +2656,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( ClearCurrentlyScrollingLayer(); - gfx::Point viewport_point(scroll_state->start_position_x(), - scroll_state->start_position_y()); + gfx::Point viewport_point(scroll_state->position_x(), + scroll_state->position_y()); gfx::PointF device_viewport_point = gfx::ScalePoint( gfx::PointF(viewport_point), active_tree_->device_scale_factor()); @@ -2646,7 +2666,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( if (layer_impl) { LayerImpl* scroll_layer_impl = - active_tree_->FindFirstScrollingLayerThatIsHitByPoint( + active_tree_->FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( device_viewport_point); if (scroll_layer_impl && !HasScrollAncestor(layer_impl, scroll_layer_impl)) { @@ -2696,16 +2716,16 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( return scroll_status; } ScrollStateData scroll_state_data; - scroll_state_data.start_position_x = viewport_point.x(); - scroll_state_data.start_position_y = viewport_point.y(); + scroll_state_data.position_x = viewport_point.x(); + scroll_state_data.position_y = viewport_point.y(); scroll_state_data.is_in_inertial_phase = true; ScrollState scroll_state(scroll_state_data); // ScrollAnimated is used for animated wheel scrolls. We find the first layer // that can scroll and set up an animation of its scroll offset. Note that - // this does not currently go through the scroll customization and viewport - // machinery that ScrollBy uses for non-animated wheel scrolls. - scroll_status = ScrollBegin(&scroll_state, ANIMATED_WHEEL); + // this does not currently go through the scroll customization machinery + // that ScrollBy uses for non-animated wheel scrolls. + scroll_status = ScrollBegin(&scroll_state, WHEEL); scroll_node = scroll_tree.CurrentlyScrollingNode(); if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { ScrollStateData scroll_state_end_data; @@ -2790,16 +2810,16 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( } ScrollStateData scroll_state_data; - scroll_state_data.start_position_x = viewport_point.x(); - scroll_state_data.start_position_y = viewport_point.y(); + scroll_state_data.position_x = viewport_point.x(); + scroll_state_data.position_y = viewport_point.y(); scroll_state_data.is_in_inertial_phase = true; ScrollState scroll_state(scroll_state_data); // ScrollAnimated is used for animated wheel scrolls. We find the first layer // that can scroll and set up an animation of its scroll offset. Note that - // this does not currently go through the scroll customization and viewport - // machinery that ScrollBy uses for non-animated wheel scrolls. - scroll_status = ScrollBegin(&scroll_state, ANIMATED_WHEEL); + // this does not currently go through the scroll customization machinery + // that ScrollBy uses for non-animated wheel scrolls. + scroll_status = ScrollBegin(&scroll_state, WHEEL); scroll_node = scroll_tree.CurrentlyScrollingNode(); if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { gfx::Vector2dF pending_delta = scroll_delta; @@ -2952,8 +2972,8 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollSingleNode( void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node, ScrollState* scroll_state) { DCHECK(scroll_state); - gfx::Point viewport_point(scroll_state->start_position_x(), - scroll_state->start_position_y()); + gfx::Point viewport_point(scroll_state->position_x(), + scroll_state->position_y()); const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y()); gfx::Vector2dF applied_delta; // TODO(tdresser): Use a more rational epsilon. See crbug.com/510550 for @@ -3308,6 +3328,17 @@ void LayerTreeHostImpl::PinchGestureEnd() { SetNeedsRedraw(); } +std::unique_ptr<BeginFrameCallbackList> +LayerTreeHostImpl::ProcessLayerTreeMutations() { + std::unique_ptr<BeginFrameCallbackList> callbacks(new BeginFrameCallbackList); + if (mutator_) { + const base::Closure& callback = mutator_->TakeMutations(); + if (!callback.is_null()) + callbacks->push_back(callback); + } + return callbacks; +} + static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, LayerImpl* root_layer) { if (!root_layer) @@ -3318,8 +3349,8 @@ static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, ->scroll_tree.CollectScrollDeltas(scroll_info); } -scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { - scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); +std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { + std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer()); scroll_info->page_scale_delta = @@ -3421,7 +3452,7 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { // tree, or if they are on the pending tree waiting for some future time to // start. // TODO(crbug.com/551138): We currently have a single signal from the - // animation host/registrar, so on the last frame of an animation we will + // animation_host, so on the last frame of an animation we will // still request an extra SetNeedsAnimate here. if (animated) SetNeedsOneBeginImplFrame(); @@ -3432,7 +3463,7 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { } void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) { - scoped_ptr<AnimationEvents> events = animation_host_->CreateEvents(); + std::unique_ptr<AnimationEvents> events = animation_host_->CreateEvents(); const bool has_active_animations = animation_host_->UpdateAnimationState( start_ready_animations, events.get()); @@ -3459,7 +3490,8 @@ void LayerTreeHostImpl::ActivateAnimations() { std::string LayerTreeHostImpl::LayerTreeAsJson() const { std::string str; if (active_tree_->root_layer()) { - scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson()); + std::unique_ptr<base::Value> json( + active_tree_->root_layer()->LayerTreeAsJson()); base::JSONWriter::WriteWithOptions( *json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &str); } @@ -3558,9 +3590,9 @@ base::TimeDelta LayerTreeHostImpl::CurrentBeginFrameInterval() const { return current_begin_frame_tracker_.Interval(); } -scoped_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> LayerTreeHostImpl::AsValueWithFrame(FrameData* frame) const { - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); AsValueWithFrameInto(frame, state.get()); return std::move(state); @@ -3726,7 +3758,7 @@ void LayerTreeHostImpl::MarkUIResourceNotEvicted(UIResourceId uid) { } void LayerTreeHostImpl::ScheduleMicroBenchmark( - scoped_ptr<MicroBenchmarkImpl> benchmark) { + std::unique_ptr<MicroBenchmarkImpl> benchmark) { micro_benchmark_controller_.ScheduleRun(std::move(benchmark)); } @@ -3774,15 +3806,15 @@ bool LayerTreeHostImpl::ScrollAnimationUpdateTarget( CurrentBeginFrameArgs().frame_time); } -bool LayerTreeHostImpl::IsLayerInTree(int layer_id, - LayerTreeType tree_type) const { - if (tree_type == LayerTreeType::ACTIVE) { - return active_tree() ? active_tree()->LayerById(layer_id) != nullptr +bool LayerTreeHostImpl::IsElementInList(ElementId element_id, + ElementListType list_type) const { + if (list_type == ElementListType::ACTIVE) { + return active_tree() ? active_tree()->LayerById(element_id) != nullptr : false; } else { - if (pending_tree() && pending_tree()->LayerById(layer_id)) + if (pending_tree() && pending_tree()->LayerById(element_id)) return true; - if (recycle_tree() && recycle_tree()->LayerById(layer_id)) + if (recycle_tree() && recycle_tree()->LayerById(element_id)) return true; return false; @@ -3840,79 +3872,107 @@ void LayerTreeHostImpl::SetTreeLayerScrollOffsetMutated( layer->OnScrollOffsetAnimated(scroll_offset); } -void LayerTreeHostImpl::TreeLayerTransformIsPotentiallyAnimatingChanged( - int layer_id, - LayerTreeImpl* tree, - bool is_animating) { - if (!tree) - return; - - LayerImpl* layer = tree->LayerById(layer_id); - if (layer) - layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); -} - bool LayerTreeHostImpl::AnimationsPreserveAxisAlignment( const LayerImpl* layer) const { return animation_host_->AnimationsPreserveAxisAlignment(layer->id()); } -void LayerTreeHostImpl::SetLayerFilterMutated(int layer_id, - LayerTreeType tree_type, - const FilterOperations& filters) { - if (tree_type == LayerTreeType::ACTIVE) { - SetTreeLayerFilterMutated(layer_id, active_tree(), filters); +void LayerTreeHostImpl::SetElementFilterMutated( + ElementId element_id, + ElementListType list_type, + const FilterOperations& filters) { + if (list_type == ElementListType::ACTIVE) { + SetTreeLayerFilterMutated(element_id, active_tree(), filters); } else { - SetTreeLayerFilterMutated(layer_id, pending_tree(), filters); - SetTreeLayerFilterMutated(layer_id, recycle_tree(), filters); + SetTreeLayerFilterMutated(element_id, pending_tree(), filters); + SetTreeLayerFilterMutated(element_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); +void LayerTreeHostImpl::SetElementOpacityMutated(ElementId element_id, + ElementListType list_type, + float opacity) { + if (list_type == ElementListType::ACTIVE) { + SetTreeLayerOpacityMutated(element_id, active_tree(), opacity); } else { - SetTreeLayerOpacityMutated(layer_id, pending_tree(), opacity); - SetTreeLayerOpacityMutated(layer_id, recycle_tree(), opacity); + SetTreeLayerOpacityMutated(element_id, pending_tree(), opacity); + SetTreeLayerOpacityMutated(element_id, recycle_tree(), opacity); } } -void LayerTreeHostImpl::SetLayerTransformMutated( - int layer_id, - LayerTreeType tree_type, +void LayerTreeHostImpl::SetElementTransformMutated( + ElementId element_id, + ElementListType list_type, const gfx::Transform& transform) { - if (tree_type == LayerTreeType::ACTIVE) { - SetTreeLayerTransformMutated(layer_id, active_tree(), transform); + if (list_type == ElementListType::ACTIVE) { + SetTreeLayerTransformMutated(element_id, active_tree(), transform); } else { - SetTreeLayerTransformMutated(layer_id, pending_tree(), transform); - SetTreeLayerTransformMutated(layer_id, recycle_tree(), transform); + SetTreeLayerTransformMutated(element_id, pending_tree(), transform); + SetTreeLayerTransformMutated(element_id, recycle_tree(), transform); } } -void LayerTreeHostImpl::SetLayerScrollOffsetMutated( - int layer_id, - LayerTreeType tree_type, +void LayerTreeHostImpl::SetElementScrollOffsetMutated( + ElementId element_id, + ElementListType list_type, const gfx::ScrollOffset& scroll_offset) { - if (tree_type == LayerTreeType::ACTIVE) { - SetTreeLayerScrollOffsetMutated(layer_id, active_tree(), scroll_offset); + if (list_type == ElementListType::ACTIVE) { + SetTreeLayerScrollOffsetMutated(element_id, active_tree(), scroll_offset); } else { - SetTreeLayerScrollOffsetMutated(layer_id, pending_tree(), scroll_offset); - SetTreeLayerScrollOffsetMutated(layer_id, recycle_tree(), scroll_offset); + SetTreeLayerScrollOffsetMutated(element_id, pending_tree(), scroll_offset); + SetTreeLayerScrollOffsetMutated(element_id, recycle_tree(), scroll_offset); } } -void LayerTreeHostImpl::LayerTransformIsPotentiallyAnimatingChanged( - int layer_id, - LayerTreeType tree_type, +void LayerTreeHostImpl::ElementTransformIsAnimatingChanged( + ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, bool is_animating) { - if (tree_type == LayerTreeType::ACTIVE) { - TreeLayerTransformIsPotentiallyAnimatingChanged(layer_id, active_tree(), - is_animating); - } else { - TreeLayerTransformIsPotentiallyAnimatingChanged(layer_id, pending_tree(), - is_animating); + LayerTreeImpl* tree = + list_type == ElementListType::ACTIVE ? active_tree() : pending_tree(); + if (!tree) + return; + LayerImpl* layer = tree->LayerById(element_id); + if (layer) { + switch (change_type) { + case AnimationChangeType::POTENTIAL: + layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); + break; + case AnimationChangeType::RUNNING: + layer->OnTransformIsCurrentlyAnimatingChanged(is_animating); + break; + case AnimationChangeType::BOTH: + layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); + layer->OnTransformIsCurrentlyAnimatingChanged(is_animating); + break; + } + } +} + +void LayerTreeHostImpl::ElementOpacityIsAnimatingChanged( + ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, + bool is_animating) { + LayerTreeImpl* tree = + list_type == ElementListType::ACTIVE ? active_tree() : pending_tree(); + if (!tree) + return; + LayerImpl* layer = tree->LayerById(element_id); + if (layer) { + switch (change_type) { + case AnimationChangeType::POTENTIAL: + layer->OnOpacityIsPotentiallyAnimatingChanged(is_animating); + break; + case AnimationChangeType::RUNNING: + layer->OnOpacityIsCurrentlyAnimatingChanged(is_animating); + break; + case AnimationChangeType::BOTH: + layer->OnOpacityIsPotentiallyAnimatingChanged(is_animating); + layer->OnOpacityIsCurrentlyAnimatingChanged(is_animating); + break; + } } } @@ -3924,9 +3984,9 @@ void LayerTreeHostImpl::ScrollOffsetAnimationFinished() { } gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation( - int layer_id) const { + ElementId element_id) const { if (active_tree()) { - LayerImpl* layer = active_tree()->LayerById(layer_id); + LayerImpl* layer = active_tree()->LayerById(element_id); if (layer) return layer->ScrollOffsetForAnimation(); } @@ -3945,4 +4005,14 @@ bool LayerTreeHostImpl::CommitToActiveTree() const { return !task_runner_provider_->HasImplThread(); } +bool LayerTreeHostImpl::HasFixedRasterScalePotentialPerformanceRegression() + const { + return fixed_raster_scale_attempted_scale_change_history_.count() >= + kFixedRasterScaleAttemptedScaleChangeThreshold; +} + +void LayerTreeHostImpl::SetFixedRasterScaleAttemptedToChangeScale() { + fixed_raster_scale_attempted_scale_change_history_.set(0); +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index 9366c223c9b..c5e132c1ab0 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -7,17 +7,19 @@ #include <stddef.h> +#include <bitset> +#include <memory> #include <set> #include <string> #include <unordered_map> #include <vector> +#include "base/callback.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" +#include "cc/animation/layer_tree_mutator.h" #include "cc/base/cc_export.h" #include "cc/base/synced_property.h" -#include "cc/debug/frame_timing_tracker.h" #include "cc/debug/micro_benchmark_controller_impl.h" #include "cc/input/input_handler.h" #include "cc/input/scrollbar_animation_controller.h" @@ -40,8 +42,6 @@ #include "cc/trees/layer_tree_settings.h" #include "cc/trees/mutator_host_client.h" #include "cc/trees/task_runner_provider.h" -#include "skia/ext/refptr.h" -#include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" namespace gfx { @@ -63,7 +63,8 @@ class MemoryHistory; class PageScaleAnimation; class PictureLayerImpl; class RasterTilePriorityQueue; -class TileTaskWorkerPool; +class TileTaskManager; +class RasterBufferProvider; class RenderPassDrawQuad; class RenderingStatsInstrumentation; class ResourcePool; @@ -72,6 +73,7 @@ class ScrollbarLayerImplBase; class SwapPromise; class SwapPromiseMonitor; class SynchronousTaskGraphRunner; +class TaskGraphRunner; class TextureMailboxDeleter; class TopControlsManager; class UIResourceBitmap; @@ -79,6 +81,8 @@ class UIResourceRequest; struct ScrollAndScaleSet; class Viewport; +using BeginFrameCallbackList = std::vector<base::Closure>; + enum class GpuRasterizationStatus { ON, ON_FORCED, @@ -95,6 +99,7 @@ class LayerTreeHostImplClient { virtual void DidLoseOutputSurfaceOnImplThread() = 0; virtual void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) = 0; + virtual void SetBeginFrameSource(BeginFrameSource* source) = 0; virtual void SetEstimatedParentDrawTime(base::TimeDelta draw_time) = 0; virtual void DidSwapBuffersOnImplThread() = 0; virtual void DidSwapBuffersCompleteOnImplThread() = 0; @@ -111,7 +116,7 @@ class LayerTreeHostImplClient { virtual void SetNeedsPrepareTilesOnImplThread() = 0; virtual void SetVideoNeedsBeginFrames(bool needs_begin_frames) = 0; virtual void PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEvents> events) = 0; + std::unique_ptr<AnimationEvents> events) = 0; virtual bool IsInsideDraw() = 0; virtual void RenewTreePriority() = 0; virtual void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -126,10 +131,6 @@ class LayerTreeHostImplClient { // Called when output surface asks for a draw. virtual void OnDrawForOutputSurface(bool resourceless_software_draw) = 0; - virtual void PostFrameTimingEventsOnImplThread( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) = 0; - protected: virtual ~LayerTreeHostImplClient() {} }; @@ -147,7 +148,7 @@ class CC_EXPORT LayerTreeHostImpl public MutatorHostClient, public base::SupportsWeakPtr<LayerTreeHostImpl> { public: - static scoped_ptr<LayerTreeHostImpl> Create( + static std::unique_ptr<LayerTreeHostImpl> Create( const LayerTreeSettings& settings, LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, @@ -196,7 +197,7 @@ class CC_EXPORT LayerTreeHostImpl EventListenerProperties GetEventListenerProperties( EventListenerClass event_class) const override; bool DoTouchEventsBlockScrollAt(const gfx::Point& viewport_port) override; - scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( + std::unique_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( ui::LatencyInfo* latency) override; ScrollElasticityHelper* CreateScrollElasticityHelper() override; @@ -209,6 +210,10 @@ class CC_EXPORT LayerTreeHostImpl void UpdateViewportContainerSizes(); + void set_resourceless_software_draw_for_testing() { + resourceless_software_draw_ = true; + } + struct CC_EXPORT FrameData : public RenderPassSink { FrameData(); ~FrameData() override; @@ -216,14 +221,13 @@ class CC_EXPORT LayerTreeHostImpl std::vector<gfx::Rect> occluding_screen_space_rects; std::vector<gfx::Rect> non_occluding_screen_space_rects; - std::vector<FrameTimingTracker::FrameAndRectIds> composite_events; RenderPassList render_passes; const LayerImplList* render_surface_layer_list; LayerImplList will_draw_layers; bool has_no_damage; // RenderPassSink implementation. - void AppendRenderPass(scoped_ptr<RenderPass> render_pass) override; + void AppendRenderPass(std::unique_ptr<RenderPass> render_pass) override; private: DISALLOW_COPY_AND_ASSIGN(FrameData); @@ -252,33 +256,37 @@ class CC_EXPORT LayerTreeHostImpl void SetTreeLayerScrollOffsetMutated(int layer_id, LayerTreeImpl* tree, const gfx::ScrollOffset& scroll_offset); - void TreeLayerTransformIsPotentiallyAnimatingChanged(int layer_id, - LayerTreeImpl* tree, - bool is_animating); bool AnimationsPreserveAxisAlignment(const LayerImpl* layer) const; - // LayerTreeMutatorsClient implementation. - bool IsLayerInTree(int layer_id, LayerTreeType tree_type) const override; + // MutatorHostClient implementation. + bool IsElementInList(ElementId element_id, + ElementListType list_type) const override; void SetMutatorsNeedCommit() override; void SetMutatorsNeedRebuildPropertyTrees() 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, + void SetElementFilterMutated(ElementId element_id, + ElementListType list_type, + const FilterOperations& filters) override; + void SetElementOpacityMutated(ElementId element_id, + ElementListType list_type, + float opacity) override; + void SetElementTransformMutated(ElementId element_id, + ElementListType list_type, + const gfx::Transform& transform) override; + void SetElementScrollOffsetMutated( + ElementId element_id, + ElementListType list_type, const gfx::ScrollOffset& scroll_offset) override; - void LayerTransformIsPotentiallyAnimatingChanged(int layer_id, - LayerTreeType tree_type, - bool is_animating) override; + void ElementTransformIsAnimatingChanged(ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, + bool is_animating) override; + void ElementOpacityIsAnimatingChanged(ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, + bool is_animating) override; void ScrollOffsetAnimationFinished() override; - gfx::ScrollOffset GetScrollOffsetForAnimation(int layer_id) const override; + gfx::ScrollOffset GetScrollOffsetForAnimation( + ElementId element_id) const override; virtual bool PrepareTiles(); @@ -328,10 +336,10 @@ class CC_EXPORT LayerTreeHostImpl void NotifyReadyToDraw() override; void NotifyAllTileTasksCompleted() override; void NotifyTileStateChanged(const Tile* tile) override; - scoped_ptr<RasterTilePriorityQueue> BuildRasterQueue( + std::unique_ptr<RasterTilePriorityQueue> BuildRasterQueue( TreePriority tree_priority, RasterTilePriorityQueue::Type type) override; - scoped_ptr<EvictionTilePriorityQueue> BuildEvictionQueue( + std::unique_ptr<EvictionTilePriorityQueue> BuildEvictionQueue( TreePriority tree_priority) override; void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) override; @@ -349,6 +357,7 @@ class CC_EXPORT LayerTreeHostImpl // OutputSurfaceClient implementation. void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) override; + void SetBeginFrameSource(BeginFrameSource* source) override; void SetNeedsRedrawRect(const gfx::Rect& rect) override; void SetExternalTilePriorityConstraints( const gfx::Rect& viewport_rect, @@ -441,7 +450,7 @@ class CC_EXPORT LayerTreeHostImpl return scroll_affects_scroll_handler_; } void QueueSwapPromiseForMainThreadScrollUpdate( - scoped_ptr<SwapPromise> swap_promise); + std::unique_ptr<SwapPromise> swap_promise); bool IsActivelyScrolling() const; @@ -461,7 +470,9 @@ class CC_EXPORT LayerTreeHostImpl const gfx::Transform& DrawTransform() const; - scoped_ptr<ScrollAndScaleSet> ProcessScrollDeltas(); + std::unique_ptr<BeginFrameCallbackList> ProcessLayerTreeMutations(); + + std::unique_ptr<ScrollAndScaleSet> ProcessScrollDeltas(); void set_max_memory_needed_bytes(size_t bytes) { max_memory_needed_bytes_ = bytes; @@ -513,7 +524,7 @@ class CC_EXPORT LayerTreeHostImpl void AsValueWithFrameInto(FrameData* frame, base::trace_event::TracedValue* value) const; - scoped_ptr<base::trace_event::ConvertableToTraceFormat> AsValueWithFrame( + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValueWithFrame( FrameData* frame) const; void ActivationStateAsValueInto(base::trace_event::TracedValue* value) const; @@ -541,7 +552,7 @@ class CC_EXPORT LayerTreeHostImpl gfx::Vector2dF ComputeScrollDelta(ScrollNode* scroll_node, const gfx::Vector2dF& delta); - void ScheduleMicroBenchmark(scoped_ptr<MicroBenchmarkImpl> benchmark); + void ScheduleMicroBenchmark(std::unique_ptr<MicroBenchmarkImpl> benchmark); CompositorFrameMetadata MakeCompositorFrameMetadata() const; // Viewport rectangle and clip in nonflipped window space. These rects @@ -569,46 +580,18 @@ class CC_EXPORT LayerTreeHostImpl bool SupportsImplScrolling() const; bool CommitToActiveTree() const; - virtual void CreateResourceAndTileTaskWorkerPool( - scoped_ptr<TileTaskWorkerPool>* tile_task_worker_pool, - scoped_ptr<ResourcePool>* resource_pool); + virtual void CreateResourceAndRasterBufferProvider( + std::unique_ptr<RasterBufferProvider>* raster_buffer_provider, + std::unique_ptr<ResourcePool>* resource_pool); bool prepare_tiles_needed() const { return tile_priorities_dirty_; } - FrameTimingTracker* frame_timing_tracker() { - return frame_timing_tracker_.get(); - } - gfx::Vector2dF ScrollSingleNode(ScrollNode* scroll_node, const gfx::Vector2dF& delta, const gfx::Point& viewport_point, bool is_direct_manipulation, ScrollTree* scroll_tree); - void set_output_is_secure(bool output_is_secure) { - output_is_secure_ = output_is_secure; - } - - bool output_is_secure() const { return output_is_secure_; } - - // Record main frame timing information. - // |start_of_main_frame_args| is the BeginFrameArgs of the beginning of the - // main frame (ie the frame that kicked off the main frame). - // |expected_next_main_frame_args| is the BeginFrameArgs of the frame that - // follows the completion of the main frame (whether it is activation or some - // other completion, such as early out). Note that if there is a main frame - // scheduled in that frame, then this BeginFrameArgs will become the main - // frame args. However, if no such frame is scheduled, then this _would_ be - // the main frame args if it was scheduled. - void RecordMainFrameTiming( - 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); - base::SingleThreadTaskRunner* GetTaskRunner() const { DCHECK(task_runner_provider_); return task_runner_provider_->HasImplThread() @@ -626,6 +609,19 @@ class CC_EXPORT LayerTreeHostImpl bool ScrollAnimationCreate(ScrollNode* scroll_node, const gfx::Vector2dF& scroll_amount); + void SetLayerTreeMutator(LayerTreeMutator* mutator); + LayerTreeMutator* mutator() { return mutator_; } + + void set_fixed_raster_scale_has_blurry_content() { + has_fixed_raster_scale_blurry_content_ = true; + } + bool has_fixed_raster_scale_blurry_content() const { + return has_fixed_raster_scale_blurry_content_; + } + + bool HasFixedRasterScalePotentialPerformanceRegression() const; + void SetFixedRasterScaleAttemptedToChangeScale(); + protected: LayerTreeHostImpl( const LayerTreeSettings& settings, @@ -653,6 +649,9 @@ class CC_EXPORT LayerTreeHostImpl BeginFrameTracker current_begin_frame_tracker_; private: + enum { kFixedRasterScaleAttemptedScaleChangeThreshold = 5 }; + enum { kFixedRasterScaleAttemptedScaleChangeHistoryCount = 10 }; + gfx::Vector2dF ScrollNodeWithViewportSpaceDelta( ScrollNode* scroll_node, const gfx::PointF& viewport_point, @@ -737,42 +736,42 @@ class CC_EXPORT LayerTreeHostImpl OutputSurface* output_surface_; - scoped_ptr<ResourceProvider> resource_provider_; + std::unique_ptr<ResourceProvider> resource_provider_; bool content_is_suitable_for_gpu_rasterization_; bool has_gpu_rasterization_trigger_; bool use_gpu_rasterization_; bool use_msaa_; GpuRasterizationStatus gpu_rasterization_status_; bool tree_resources_for_gpu_rasterization_dirty_; - scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_; - scoped_ptr<ResourcePool> resource_pool_; - scoped_ptr<Renderer> renderer_; - scoped_ptr<ImageDecodeController> image_decode_controller_; + std::unique_ptr<TileTaskManager> tile_task_manager_; + std::unique_ptr<ResourcePool> resource_pool_; + std::unique_ptr<Renderer> renderer_; + std::unique_ptr<ImageDecodeController> image_decode_controller_; GlobalStateThatImpactsTilePriority global_tile_state_; // Tree currently being drawn. - scoped_ptr<LayerTreeImpl> active_tree_; + std::unique_ptr<LayerTreeImpl> active_tree_; // In impl-side painting mode, tree with possibly incomplete rasterized // content. May be promoted to active by ActivatePendingTree(). - scoped_ptr<LayerTreeImpl> pending_tree_; + std::unique_ptr<LayerTreeImpl> pending_tree_; // In impl-side painting mode, inert tree with layers that can be recycled // by the next sync from the main thread. - scoped_ptr<LayerTreeImpl> recycle_tree_; + std::unique_ptr<LayerTreeImpl> recycle_tree_; InputHandlerClient* input_handler_client_; bool did_lock_scrolling_layer_; bool wheel_scrolling_; bool scroll_affects_scroll_handler_; int scroll_layer_id_when_mouse_over_scrollbar_; - std::vector<scoped_ptr<SwapPromise>> + std::vector<std::unique_ptr<SwapPromise>> swap_promises_for_main_thread_scroll_update_; // An object to implement the ScrollElasticityHelper interface and // hold all state related to elasticity. May be NULL if never requested. - scoped_ptr<ScrollElasticityHelper> scroll_elasticity_helper_; + std::unique_ptr<ScrollElasticityHelper> scroll_elasticity_helper_; bool tile_priorities_dirty_; @@ -782,22 +781,22 @@ class CC_EXPORT LayerTreeHostImpl ManagedMemoryPolicy cached_managed_memory_policy_; const bool is_synchronous_single_threaded_; - scoped_ptr<TileManager> tile_manager_; + std::unique_ptr<TileManager> tile_manager_; gfx::Vector2dF accumulated_root_overscroll_; bool pinch_gesture_active_; bool pinch_gesture_end_should_clear_scrolling_layer_; - scoped_ptr<TopControlsManager> top_controls_manager_; + std::unique_ptr<TopControlsManager> top_controls_manager_; - scoped_ptr<PageScaleAnimation> page_scale_animation_; + std::unique_ptr<PageScaleAnimation> page_scale_animation_; - scoped_ptr<FrameRateCounter> fps_counter_; - scoped_ptr<MemoryHistory> memory_history_; - scoped_ptr<DebugRectHistory> debug_rect_history_; + std::unique_ptr<FrameRateCounter> fps_counter_; + std::unique_ptr<MemoryHistory> memory_history_; + std::unique_ptr<DebugRectHistory> debug_rect_history_; - scoped_ptr<TextureMailboxDeleter> texture_mailbox_deleter_; + std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter_; // The maximum memory that would be used by the prioritized resource // manager, if there were no limit on memory usage. @@ -822,21 +821,19 @@ class CC_EXPORT LayerTreeHostImpl gfx::Rect viewport_rect_for_tile_priority_; bool resourceless_software_draw_; - bool output_is_secure_; - gfx::Rect viewport_damage_rect_; - scoped_ptr<AnimationHost> animation_host_; + std::unique_ptr<AnimationHost> animation_host_; std::set<VideoFrameController*> video_frame_controllers_; // Map from scroll layer ID to scrollbar animation controller. // There is one animation controller per pair of overlay scrollbars. - std::unordered_map<int, scoped_ptr<ScrollbarAnimationController>> + std::unordered_map<int, std::unique_ptr<ScrollbarAnimationController>> scrollbar_animation_controllers_; RenderingStatsInstrumentation* rendering_stats_instrumentation_; MicroBenchmarkControllerImpl micro_benchmark_controller_; - scoped_ptr<SynchronousTaskGraphRunner> + std::unique_ptr<SynchronousTaskGraphRunner> single_thread_synchronous_task_graph_runner_; // Optional callback to notify of new tree activations. @@ -852,9 +849,13 @@ class CC_EXPORT LayerTreeHostImpl bool requires_high_res_to_draw_; bool is_likely_to_require_a_draw_; - scoped_ptr<FrameTimingTracker> frame_timing_tracker_; + std::unique_ptr<Viewport> viewport_; + + LayerTreeMutator* mutator_; - scoped_ptr<Viewport> viewport_; + bool has_fixed_raster_scale_blurry_content_; + std::bitset<kFixedRasterScaleAttemptedScaleChangeHistoryCount> + fixed_raster_scale_attempted_scale_change_history_; DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl); }; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index 31b8f56db17..402a94ec395 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -13,7 +13,8 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/location.h" -#include "base/thread_task_runner_handle.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/animation/animation_events.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" @@ -25,7 +26,6 @@ #include "cc/input/top_controls_manager.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/heads_up_display_layer_impl.h" -#include "cc/layers/io_surface_layer_impl.h" #include "cc/layers/layer_impl.h" #include "cc/layers/painted_scrollbar_layer_impl.h" #include "cc/layers/render_surface_impl.h" @@ -111,6 +111,7 @@ class LayerTreeHostImplTest : public testing::Test, settings.minimum_occlusion_tracking_size = gfx::Size(); settings.renderer_settings.texture_id_allocation_chunk_size = 1; settings.gpu_rasterization_enabled = true; + settings.verify_clip_tree_calculations = true; return settings; } @@ -124,6 +125,7 @@ class LayerTreeHostImplTest : public testing::Test, void DidLoseOutputSurfaceOnImplThread() override {} void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) override {} + void SetBeginFrameSource(BeginFrameSource* source) override {} void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override {} void DidSwapBuffersOnImplThread() override {} void DidSwapBuffersCompleteOnImplThread() override {} @@ -148,7 +150,7 @@ class LayerTreeHostImplTest : public testing::Test, void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; } void SetVideoNeedsBeginFrames(bool needs_begin_frames) override {} void PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEvents> events) override {} + std::unique_ptr<AnimationEvents> events) override {} bool IsInsideDraw() override { return false; } void RenewTreePriority() override {} void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -163,7 +165,7 @@ class LayerTreeHostImplTest : public testing::Test, did_complete_page_scale_animation_ = true; } void OnDrawForOutputSurface(bool resourceless_software_draw) override { - scoped_ptr<LayerTreeHostImpl::FrameData> frame( + std::unique_ptr<LayerTreeHostImpl::FrameData> frame( new LayerTreeHostImpl::FrameData); EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(frame.get())); last_on_draw_render_passes_.clear(); @@ -174,24 +176,20 @@ class LayerTreeHostImplTest : public testing::Test, host_impl_->SwapBuffers(*frame); last_on_draw_frame_ = std::move(frame); } - 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; } virtual bool CreateHostImpl(const LayerTreeSettings& settings, - scoped_ptr<OutputSurface> output_surface) { + std::unique_ptr<OutputSurface> output_surface) { return CreateHostImplWithTaskRunnerProvider( settings, std::move(output_surface), &task_runner_provider_); } virtual bool CreateHostImplWithTaskRunnerProvider( const LayerTreeSettings& settings, - scoped_ptr<OutputSurface> output_surface, + std::unique_ptr<OutputSurface> output_surface, TaskRunnerProvider* task_runner_provider) { host_impl_ = LayerTreeHostImpl::Create( settings, this, task_runner_provider, &stats_instrumentation_, @@ -215,12 +213,12 @@ class LayerTreeHostImplTest : public testing::Test, return init; } - void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) { + void SetupRootLayerImpl(std::unique_ptr<LayerImpl> root) { root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); } @@ -232,10 +230,9 @@ class LayerTreeHostImplTest : public testing::Test, return gfx::Vector2dF(delta.x(), delta.y()); } - static void ExpectClearedScrollDeltasRecursive(LayerImpl* layer) { - ASSERT_EQ(ScrollDelta(layer), gfx::Vector2d()); - for (size_t i = 0; i < layer->children().size(); ++i) - ExpectClearedScrollDeltasRecursive(layer->children()[i]); + static void ExpectClearedScrollDeltasRecursive(LayerImpl* root) { + for (auto* layer : *root->layer_tree_impl()) + ASSERT_EQ(ScrollDelta(layer), gfx::Vector2d()); } static ::testing::AssertionResult ScrollInfoContains( @@ -285,38 +282,39 @@ class LayerTreeHostImplTest : public testing::Test, const int kInnerViewportClipLayerId = 4; const int kPageScaleLayerId = 5; - scoped_ptr<LayerImpl> root = - LayerImpl::Create(layer_tree_impl, 1); + std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); root->SetBounds(content_size); root->SetPosition(gfx::PointF()); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; - scoped_ptr<LayerImpl> inner_scroll = + std::unique_ptr<LayerImpl> inner_scroll = LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); - inner_scroll->SetIsContainerForFixedPositionLayers(true); + inner_scroll->test_properties()->is_container_for_fixed_position_layers = + true; inner_scroll->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(), gfx::ScrollOffset()); - scoped_ptr<LayerImpl> inner_clip = + std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); inner_clip->SetBounds( gfx::Size(content_size.width() / 2, content_size.height() / 2)); - scoped_ptr<LayerImpl> page_scale = + std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); inner_scroll->SetScrollClipLayer(inner_clip->id()); inner_scroll->SetBounds(content_size); inner_scroll->SetPosition(gfx::PointF()); - scoped_ptr<LayerImpl> outer_clip = + std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId); outer_clip->SetBounds(content_size); - outer_clip->SetIsContainerForFixedPositionLayers(true); + outer_clip->test_properties()->is_container_for_fixed_position_layers = + true; - scoped_ptr<LayerImpl> outer_scroll = + std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); outer_scroll->SetScrollClipLayer(outer_clip->id()); outer_scroll->layer_tree_impl() @@ -326,7 +324,7 @@ class LayerTreeHostImplTest : public testing::Test, outer_scroll->SetBounds(content_size); outer_scroll->SetPosition(gfx::PointF()); - scoped_ptr<LayerImpl> contents = + std::unique_ptr<LayerImpl> contents = LayerImpl::Create(layer_tree_impl, kContentLayerId); contents->SetDrawsContent(true); contents->SetBounds(content_size); @@ -386,12 +384,12 @@ class LayerTreeHostImplTest : public testing::Test, return content_layer; } - scoped_ptr<LayerImpl> CreateScrollableLayer(int id, - const gfx::Size& size, - LayerImpl* clip_layer) { + std::unique_ptr<LayerImpl> CreateScrollableLayer(int id, + const gfx::Size& size, + LayerImpl* clip_layer) { DCHECK(clip_layer); DCHECK(id != clip_layer->id()); - scoped_ptr<LayerImpl> layer = + std::unique_ptr<LayerImpl> layer = LayerImpl::Create(host_impl_->active_tree(), id); layer->SetScrollClipLayer(clip_layer->id()); layer->SetDrawsContent(true); @@ -400,30 +398,33 @@ class LayerTreeHostImplTest : public testing::Test, return layer; } - scoped_ptr<ScrollState> BeginState(const gfx::Point& point) { + std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) { ScrollStateData scroll_state_data; scroll_state_data.is_beginning = true; - scroll_state_data.start_position_x = point.x(); - scroll_state_data.start_position_y = point.y(); - scoped_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); + scroll_state_data.position_x = point.x(); + scroll_state_data.position_y = point.y(); + std::unique_ptr<ScrollState> scroll_state( + new ScrollState(scroll_state_data)); return scroll_state; } - scoped_ptr<ScrollState> UpdateState(const gfx::Point& point, - const gfx::Vector2dF& delta) { + std::unique_ptr<ScrollState> UpdateState(const gfx::Point& point, + const gfx::Vector2dF& delta) { ScrollStateData scroll_state_data; scroll_state_data.delta_x = delta.x(); scroll_state_data.delta_y = delta.y(); - scroll_state_data.start_position_x = point.x(); - scroll_state_data.start_position_y = point.y(); - scoped_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); + scroll_state_data.position_x = point.x(); + scroll_state_data.position_y = point.y(); + std::unique_ptr<ScrollState> scroll_state( + new ScrollState(scroll_state_data)); return scroll_state; } - scoped_ptr<ScrollState> EndState() { + std::unique_ptr<ScrollState> EndState() { ScrollStateData scroll_state_data; scroll_state_data.is_ending = true; - scoped_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); + std::unique_ptr<ScrollState> scroll_state( + new ScrollState(scroll_state_data)); return scroll_state; } @@ -460,7 +461,7 @@ class LayerTreeHostImplTest : public testing::Test, scoped_refptr<AnimationTimeline> timeline() { return timeline_; } protected: - virtual scoped_ptr<OutputSurface> CreateOutputSurface() { + virtual std::unique_ptr<OutputSurface> CreateOutputSurface() { return FakeOutputSurface::Create3d(); } @@ -495,8 +496,8 @@ class LayerTreeHostImplTest : public testing::Test, TestSharedBitmapManager shared_bitmap_manager_; TestGpuMemoryBufferManager gpu_memory_buffer_manager_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<LayerTreeHostImpl> host_impl_; + std::unique_ptr<OutputSurface> output_surface_; + std::unique_ptr<LayerTreeHostImpl> host_impl_; FakeRenderingStatsInstrumentation stats_instrumentation_; bool on_can_draw_state_changed_called_; bool did_notify_ready_to_activate_; @@ -509,7 +510,7 @@ class LayerTreeHostImplTest : public testing::Test, base::Closure animation_task_; base::TimeDelta requested_animation_delay_; bool skip_draw_layers_in_on_draw_; - scoped_ptr<LayerTreeHostImpl::FrameData> last_on_draw_frame_; + std::unique_ptr<LayerTreeHostImpl::FrameData> last_on_draw_frame_; RenderPassList last_on_draw_render_passes_; scoped_refptr<AnimationTimeline> timeline_; }; @@ -561,7 +562,7 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { CreateHostImpl(DefaultSettings(), FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice()))); + base::WrapUnique(new SoftwareOutputDevice()))); SetupScrollAndContentsLayers(gfx::Size(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); host_impl_->SetViewportSize(gfx::Size()); @@ -582,13 +583,14 @@ TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { ASSERT_FALSE(host_impl_->active_tree()->root_layer()); - scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); ASSERT_EQ(scroll_info->scrolls.size(), 0u); } TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) { { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2)); root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 3)); @@ -604,7 +606,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) { ExpectClearedScrollDeltasRecursive(root); - scoped_ptr<ScrollAndScaleSet> scroll_info; + std::unique_ptr<ScrollAndScaleSet> scroll_info; scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(scroll_info->scrolls.size(), 0u); @@ -619,9 +621,9 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { gfx::ScrollOffset scroll_offset(20, 30); gfx::Vector2d scroll_delta(11, -15); { - scoped_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 2); - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root_clip->SetBounds(gfx::Size(10, 10)); LayerImpl* root_layer = root.get(); @@ -639,7 +641,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { LayerImpl* root = host_impl_->active_tree()->root_layer()->children()[0]; - scoped_ptr<ScrollAndScaleSet> scroll_info; + std::unique_ptr<ScrollAndScaleSet> scroll_info; scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(scroll_info->scrolls.size(), 1u); @@ -709,7 +711,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) { } TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { - scoped_ptr<TestWebGraphicsContext3D> context_owned = + std::unique_ptr<TestWebGraphicsContext3D> context_owned = TestWebGraphicsContext3D::Create(); context_owned->set_context_lost(true); @@ -748,7 +750,8 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { gfx::Vector2d scroll_delta(0, 10); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); EXPECT_TRUE( ScrollInfoContains(*scroll_info, scroll_layer->id(), scroll_delta)); } @@ -806,7 +809,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { LayerImpl* child = 0; { - scoped_ptr<LayerImpl> child_layer = + std::unique_ptr<LayerImpl> child_layer = LayerImpl::Create(host_impl_->active_tree(), 6); child = child_layer.get(); child_layer->SetDrawsContent(true); @@ -934,6 +937,78 @@ TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { status.main_thread_scrolling_reasons); } +TEST_F(LayerTreeHostImplTest, ScrollWithOverlappingNonScrollableLayer) { + LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); + gfx::Size content_size = gfx::Size(360, 600); + gfx::Size scroll_content_size = gfx::Size(345, 3800); + gfx::Size scrollbar_size = gfx::Size(15, 600); + + host_impl_->SetViewportSize(content_size); + std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); + root->SetBounds(content_size); + root->SetPosition(gfx::PointF()); + + std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2); + clip->SetBounds(content_size); + clip->SetPosition(gfx::PointF()); + + std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); + scroll->SetBounds(scroll_content_size); + scroll->SetScrollClipLayer(clip->id()); + scroll->SetDrawsContent(true); + + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = + SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, 0, + false, true); + scrollbar->SetBounds(scrollbar_size); + scrollbar->SetPosition(gfx::PointF(345, 0)); + scrollbar->SetScrollLayerId(scroll->id()); + scrollbar->SetDrawsContent(true); + scrollbar->SetOpacity(1.f); + + std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5); + squash1->SetBounds(gfx::Size(140, 300)); + squash1->SetPosition(gfx::PointF(220, 0)); + squash1->SetDrawsContent(true); + + std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6); + squash2->SetBounds(gfx::Size(140, 300)); + squash2->SetPosition(gfx::PointF(220, 300)); + squash2->SetDrawsContent(true); + + scroll->AddChild(std::move(squash2)); + clip->AddChild(std::move(scroll)); + clip->AddChild(std::move(scrollbar)); + clip->AddChild(std::move(squash1)); + root->AddChild(std::move(clip)); + + layer_tree_impl->SetRootLayer(std::move(root)); + SetNeedsRebuildPropertyTrees(); + RebuildPropertyTrees(); + layer_tree_impl->DidBecomeActive(); + + // The point hits squash1 layer and also scroll layer, because scroll layer is + // not an ancestor of squash1 layer, we cannot scroll on impl thread. + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_scrolling_reasons); + + // The point hits squash1 layer and also scrollbar layer. + status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); + EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_scrolling_reasons); + + // The point hits squash2 layer and also scroll layer, because scroll layer is + // an ancestor of squash2 layer, we should scroll on impl. + status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(), + InputHandler::WHEEL); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); +} + TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { SetupScrollAndContentsLayers(gfx::Size(200, 200)); host_impl_->SetViewportSize(gfx::Size(100, 100)); @@ -1232,7 +1307,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingPendingTree) { LayerImpl::Create(host_impl_->pending_tree(), 1)); LayerImpl* root = host_impl_->pending_tree()->root_layer(); root->SetBounds(gfx::Size(50, 50)); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; root->AddChild(LayerImpl::Create(host_impl_->pending_tree(), 2)); LayerImpl* child = root->children()[0]; @@ -1282,7 +1357,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) { LayerImpl::Create(host_impl_->active_tree(), 1)); LayerImpl* root = host_impl_->active_tree()->root_layer(); root->SetBounds(gfx::Size(50, 50)); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2)); LayerImpl* child = root->children()[0]; @@ -1359,8 +1434,8 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { // CommitComplete below. LayerImplList list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Size(50, 50), &list, 0); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + root, gfx::Size(50, 50), &list); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); @@ -1405,7 +1480,7 @@ TEST_F(LayerTreeHostImplTest, AnimationMarksLayerNotReady) { root->SetBounds(gfx::Size(50, 50)); root->SetHasRenderSurface(true); - root->AddChild(scoped_ptr<MissingTilesLayer>( + root->AddChild(std::unique_ptr<MissingTilesLayer>( new MissingTilesLayer(host_impl_->active_tree(), 2))); MissingTilesLayer* child = static_cast<MissingTilesLayer*>(root->children()[0]); @@ -1513,7 +1588,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { EXPECT_TRUE(did_request_commit_); EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); @@ -1545,7 +1620,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains( *scroll_info.get(), scroll_layer->id(), @@ -1886,7 +1961,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { ui::LatencyInfo latency_info; latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 1234); - scoped_ptr<SwapPromise> swap_promise( + std::unique_ptr<SwapPromise> swap_promise( new LatencyInfoSwapPromise(latency_info)); SetupScrollAndContentsLayers(gfx::Size(100, 100)); @@ -1900,7 +1975,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { std::move(swap_promise)); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); EXPECT_EQ(1u, scroll_info->swap_promises.size()); EXPECT_EQ(latency_info.trace_id(), scroll_info->swap_promises[0]->TraceId()); } @@ -1918,19 +1994,19 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { LayerImpl *child; LayerImpl *child_clip; - scoped_ptr<LayerImpl> scroll_parent_clip = + std::unique_ptr<LayerImpl> scroll_parent_clip = LayerImpl::Create(host_impl_->active_tree(), 6); - scoped_ptr<LayerImpl> scroll_parent = CreateScrollableLayer( - 7, gfx::Size(10, 10), scroll_parent_clip.get()); + std::unique_ptr<LayerImpl> scroll_parent = + CreateScrollableLayer(7, gfx::Size(10, 10), scroll_parent_clip.get()); parent = scroll_parent.get(); scroll_parent_clip->AddChild(std::move(scroll_parent)); viewport_scroll->AddChild(std::move(scroll_parent_clip)); - scoped_ptr<LayerImpl> scroll_child_clip = + std::unique_ptr<LayerImpl> scroll_child_clip = LayerImpl::Create(host_impl_->active_tree(), 8); - scoped_ptr<LayerImpl> scroll_child = CreateScrollableLayer( - 9, gfx::Size(10, 10), scroll_child_clip.get()); + std::unique_ptr<LayerImpl> scroll_child = + CreateScrollableLayer(9, gfx::Size(10, 10), scroll_child_clip.get()); child = scroll_child.get(); scroll_child->SetPosition(gfx::PointF(20.f, 20.f)); scroll_child_clip->AddChild(std::move(scroll_child)); @@ -1938,10 +2014,11 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { child_clip = scroll_child_clip.get(); viewport_scroll->AddChild(std::move(scroll_child_clip)); - child_clip->SetScrollParent(parent); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + child_clip->test_properties()->scroll_parent = parent; + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(child_clip); - parent->SetScrollChildren(scroll_children.release()); + parent->test_properties()->scroll_children.reset(scroll_children.release()); SetNeedsRebuildPropertyTrees(); DrawFrame(); @@ -2025,7 +2102,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { EXPECT_TRUE(did_request_redraw_); EXPECT_TRUE(did_request_commit_); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); } @@ -2044,7 +2121,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { host_impl_->PinchGestureEnd(); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale); } @@ -2070,7 +2147,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { host_impl_->PinchGestureEnd(); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); @@ -2099,7 +2176,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { host_impl_->PinchGestureEnd(); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); EXPECT_TRUE(scroll_info->scrolls.empty()); @@ -2129,7 +2206,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { host_impl_->PinchGestureEnd(); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), @@ -2163,7 +2240,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { host_impl_->PinchGestureEnd(); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 2.f); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), @@ -2202,11 +2279,9 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { did_request_redraw_ = false; did_request_next_frame_ = false; host_impl_->active_tree()->SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( - gfx::Vector2d(), - false, - 2.f, - duration))); + std::unique_ptr<PendingPageScaleAnimation>( + new PendingPageScaleAnimation(gfx::Vector2d(), false, 2.f, + duration))); host_impl_->ActivateSyncTree(); EXPECT_FALSE(did_request_redraw_); EXPECT_TRUE(did_request_next_frame_); @@ -2239,7 +2314,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { EXPECT_FALSE(did_request_next_frame_); host_impl_->DidFinishImplFrame(); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 2); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), @@ -2262,11 +2337,9 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { did_request_redraw_ = false; did_request_next_frame_ = false; host_impl_->active_tree()->SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation> (new PendingPageScaleAnimation( - gfx::Vector2d(25, 25), - true, - min_page_scale, - duration))); + std::unique_ptr<PendingPageScaleAnimation>( + new PendingPageScaleAnimation(gfx::Vector2d(25, 25), true, + min_page_scale, duration))); host_impl_->ActivateSyncTree(); EXPECT_FALSE(did_request_redraw_); EXPECT_TRUE(did_request_next_frame_); @@ -2291,7 +2364,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { EXPECT_TRUE(did_request_commit_); host_impl_->DidFinishImplFrame(); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); // Pushed to (0,0) via clamping against contents layer size. @@ -2329,11 +2402,9 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { scroll_layer->id(), gfx::ScrollOffset(50, 50)); host_impl_->active_tree()->SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( - gfx::Vector2d(), - true, - 1.f, - duration))); + std::unique_ptr<PendingPageScaleAnimation>( + new PendingPageScaleAnimation(gfx::Vector2d(), true, 1.f, + duration))); host_impl_->ActivateSyncTree(); begin_frame_args.frame_time = start_time; host_impl_->WillBeginImplFrame(begin_frame_args); @@ -2352,7 +2423,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { EXPECT_TRUE(did_request_commit_); host_impl_->DidFinishImplFrame(); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 1); ExpectNone(*scroll_info, scroll_layer->id()); @@ -2397,12 +2468,9 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { // Make sure TakePageScaleAnimation works properly. host_impl_->sync_tree()->SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( - gfx::Vector2d(), - false, - target_scale, - duration))); - scoped_ptr<PendingPageScaleAnimation> psa = + std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( + gfx::Vector2d(), false, target_scale, duration))); + std::unique_ptr<PendingPageScaleAnimation> psa = host_impl_->sync_tree()->TakePendingPageScaleAnimation(); EXPECT_EQ(target_scale, psa->scale); EXPECT_EQ(duration, psa->duration); @@ -2413,11 +2481,8 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { did_request_redraw_ = false; did_request_next_frame_ = false; host_impl_->sync_tree()->SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( - gfx::Vector2d(), - false, - target_scale, - duration))); + std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( + gfx::Vector2d(), false, target_scale, duration))); begin_frame_args.frame_time = halfway_through_animation; host_impl_->WillBeginImplFrame(begin_frame_args); host_impl_->Animate(); @@ -2479,7 +2544,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { EXPECT_FALSE(did_request_next_frame_); host_impl_->DidFinishImplFrame(); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, target_scale); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), @@ -2511,7 +2576,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { did_complete_page_scale_animation_ = false; host_impl_->active_tree()->SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( + std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation( gfx::Vector2d(), false, 2.f, duration))); host_impl_->ActivateSyncTree(); begin_frame_args.frame_time = start_time; @@ -2600,7 +2665,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { new LayerTreeHostImplOverridePhysicalTime( settings, this, &task_runner_provider_, &shared_bitmap_manager_, &task_graph_runner_, &stats_instrumentation_); - host_impl_ = make_scoped_ptr(host_impl_override_time); + host_impl_ = base::WrapUnique(host_impl_override_time); output_surface_ = CreateOutputSurface(); host_impl_->SetVisible(true); host_impl_->InitializeRenderer(output_surface_.get()); @@ -2610,7 +2675,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { host_impl_->SetViewportSize( gfx::Size(content_size.width() / 2, content_size.height() / 2)); - scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 400, VERTICAL, 10, 0, false, true); EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); @@ -2794,7 +2859,7 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { CreateHostImpl(settings, CreateOutputSurface()); host_impl_->CreatePendingTree(); CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size); - scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400, VERTICAL, 10, 0, false, true); LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); @@ -2822,6 +2887,9 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { EffectNode* pending_tree_node = host_impl_->pending_tree()->property_trees()->effect_tree.Node( scrollbar_layer->effect_tree_index()); + host_impl_->pending_tree() + ->property_trees() + ->always_use_active_tree_opacity_effect_ids.push_back(400); EXPECT_FLOAT_EQ(1.f, active_tree_node->data.opacity); EXPECT_FLOAT_EQ(1.f, scrollbar_layer->opacity()); EXPECT_FLOAT_EQ(0.f, pending_tree_node->data.opacity); @@ -2861,13 +2929,13 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) { outer_viewport_size); LayerImpl* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - scoped_ptr<SolidColorScrollbarLayerImpl> horiz_scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), horiz_id, HORIZONTAL, 5, 5, true, true); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); child->SetBounds(content_size); - scoped_ptr<LayerImpl> child_clip = + std::unique_ptr<LayerImpl> child_clip = LayerImpl::Create(host_impl_->active_tree(), child_clip_id); child->SetBounds(inner_viewport_size); @@ -2898,22 +2966,22 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { viewport_size); LayerImpl* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - scoped_ptr<SolidColorScrollbarLayerImpl> vert_1_scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> vert_1_scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_1_id, VERTICAL, 5, 5, true, true); - scoped_ptr<SolidColorScrollbarLayerImpl> horiz_1_scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_1_scrollbar = SolidColorScrollbarLayerImpl::Create( host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true); - scoped_ptr<SolidColorScrollbarLayerImpl> vert_2_scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> vert_2_scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_2_id, VERTICAL, 5, 5, true, true); - scoped_ptr<SolidColorScrollbarLayerImpl> horiz_2_scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_2_scrollbar = SolidColorScrollbarLayerImpl::Create( host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); child->SetBounds(content_size); - scoped_ptr<LayerImpl> child_clip = + std::unique_ptr<LayerImpl> child_clip = LayerImpl::Create(host_impl_->active_tree(), child_clip_id); child->SetBounds(viewport_size); LayerImpl* child_ptr = child.get(); @@ -3019,7 +3087,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( LayerImpl* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); // The scrollbar is on the left side. - scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 6, VERTICAL, 5, 5, true, true); scrollbar->SetScrollLayerId(root_scroll->id()); @@ -3195,8 +3263,8 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { class DidDrawCheckLayer : public LayerImpl { public: - static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr(new DidDrawCheckLayer(tree_impl, id)); + static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { + return base::WrapUnique(new DidDrawCheckLayer(tree_impl, id)); } bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) override { @@ -3229,13 +3297,13 @@ class DidDrawCheckLayer : public LayerImpl { did_draw_called_ = false; } - static void IgnoreResult(scoped_ptr<CopyOutputResult> result) {} + static void IgnoreResult(std::unique_ptr<CopyOutputResult> result) {} void AddCopyRequest() { - std::vector<scoped_ptr<CopyOutputRequest>> requests; + std::vector<std::unique_ptr<CopyOutputRequest>> requests; requests.push_back( CopyOutputRequest::CreateRequest(base::Bind(&IgnoreResult))); - SetForceRenderSurface(true); + test_properties()->force_render_surface = true; PassCopyRequests(&requests); } @@ -3267,7 +3335,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) { host_impl_->active_tree()->root_layer()); root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; DidDrawCheckLayer* layer = static_cast<DidDrawCheckLayer*>(root->children()[0]); @@ -3308,7 +3376,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>( host_impl_->active_tree()->root_layer()); root->SetMasksToBounds(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); DidDrawCheckLayer* layer = static_cast<DidDrawCheckLayer*>(root->children()[0]); @@ -3363,7 +3431,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { static_cast<DidDrawCheckLayer*>(root->children()[0]); root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; DidDrawCheckLayer* top_layer = static_cast<DidDrawCheckLayer*>(root->children()[1]); // This layer covers the occluded_layer above. Make this layer large so it can @@ -3395,7 +3463,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; DidDrawCheckLayer* layer1 = static_cast<DidDrawCheckLayer*>(root->children()[0]); @@ -3403,8 +3471,8 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { DidDrawCheckLayer* layer2 = static_cast<DidDrawCheckLayer*>(layer1->children()[0]); - layer1->SetForceRenderSurface(true); - layer1->SetShouldFlattenTransform(true); + layer1->test_properties()->force_render_surface = true; + layer1->test_properties()->should_flatten_transform = true; EXPECT_FALSE(root->did_draw_called()); EXPECT_FALSE(layer1->did_draw_called()); @@ -3427,7 +3495,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { class MissingTextureAnimatingLayer : public DidDrawCheckLayer { public: - static scoped_ptr<LayerImpl> Create( + static std::unique_ptr<LayerImpl> Create( LayerTreeImpl* tree_impl, int id, bool tile_missing, @@ -3435,7 +3503,7 @@ class MissingTextureAnimatingLayer : public DidDrawCheckLayer { bool animating, ResourceProvider* resource_provider, scoped_refptr<AnimationTimeline> timeline) { - return make_scoped_ptr(new MissingTextureAnimatingLayer( + return base::WrapUnique(new MissingTextureAnimatingLayer( tree_impl, id, tile_missing, had_incomplete_tile, animating, resource_provider, timeline)); } @@ -3560,7 +3628,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) { DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; LayerTreeHostImpl::FrameData frame; SetNeedsRebuildPropertyTrees(); @@ -3629,7 +3697,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawWhenDrawAndSwapFullViewportEveryFrame) { CreateHostImpl(DefaultSettings(), FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice()))); + base::WrapUnique(new SoftwareOutputDevice()))); const gfx::Transform external_transform; const gfx::Rect external_viewport; @@ -3659,7 +3727,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; SetNeedsRebuildPropertyTrees(); host_impl_->OnDraw(external_transform, external_viewport, external_clip, @@ -3717,9 +3785,10 @@ TEST_F(LayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_->active_tree(), 1); root->SetScrollClipLayer(Layer::INVALID_ID); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); SetNeedsRebuildPropertyTrees(); DrawFrame(); @@ -3771,7 +3840,7 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { } bool CreateHostImpl(const LayerTreeSettings& settings, - scoped_ptr<OutputSurface> output_surface) override { + std::unique_ptr<OutputSurface> output_surface) override { bool init = LayerTreeHostImplTest::CreateHostImpl( settings, std::move(output_surface)); if (init) { @@ -3804,26 +3873,27 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f); host_impl_->DidChangeTopControlsPosition(); - scoped_ptr<LayerImpl> root = LayerImpl::Create(tree_impl, 1); - scoped_ptr<LayerImpl> root_clip = LayerImpl::Create(tree_impl, 2); - scoped_ptr<LayerImpl> page_scale = LayerImpl::Create(tree_impl, 3); + std::unique_ptr<LayerImpl> root = LayerImpl::Create(tree_impl, 1); + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(tree_impl, 2); + std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(tree_impl, 3); - scoped_ptr<LayerImpl> outer_scroll = LayerImpl::Create(tree_impl, 4); - scoped_ptr<LayerImpl> outer_clip = LayerImpl::Create(tree_impl, 5); + std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(tree_impl, 4); + std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(tree_impl, 5); root_clip->SetBounds(inner_viewport_size); root->SetScrollClipLayer(root_clip->id()); root->SetBounds(outer_viewport_size); root->SetPosition(gfx::PointF()); root->SetDrawsContent(false); - root->SetIsContainerForFixedPositionLayers(true); - root_clip->SetForceRenderSurface(true); + root_clip->test_properties()->force_render_surface = true; + root->test_properties()->is_container_for_fixed_position_layers = true; outer_clip->SetBounds(outer_viewport_size); outer_scroll->SetScrollClipLayer(outer_clip->id()); outer_scroll->SetBounds(scroll_layer_size); outer_scroll->SetPosition(gfx::PointF()); outer_scroll->SetDrawsContent(false); - outer_scroll->SetIsContainerForFixedPositionLayers(true); + outer_scroll->test_properties()->is_container_for_fixed_position_layers = + true; int inner_viewport_scroll_layer_id = root->id(); int outer_viewport_scroll_layer_id = outer_scroll->id(); @@ -4131,9 +4201,9 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) { host_impl_->active_tree()->OuterViewportScrollLayer(); int id = outer_viewport_scroll_layer->id(); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), id + 2); - scoped_ptr<LayerImpl> child_clip = + std::unique_ptr<LayerImpl> child_clip = LayerImpl::Create(host_impl_->active_tree(), id + 3); child_clip->SetBounds(sub_content_layer_size); @@ -4141,7 +4211,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) { child->SetBounds(sub_content_size); child->SetPosition(gfx::PointF()); child->SetDrawsContent(true); - child->SetIsContainerForFixedPositionLayers(true); + child->test_properties()->is_container_for_fixed_position_layers = true; // scroll child to limit SetScrollOffsetDelta(child.get(), gfx::Vector2dF(0, 100.f)); @@ -4609,17 +4679,17 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { gfx::Size surface_size(10, 10); gfx::Size contents_size(20, 20); - scoped_ptr<LayerImpl> content_layer = + std::unique_ptr<LayerImpl> content_layer = LayerImpl::Create(host_impl_->active_tree(), 1); content_layer->SetDrawsContent(true); content_layer->SetPosition(gfx::PointF()); content_layer->SetBounds(contents_size); - scoped_ptr<LayerImpl> scroll_clip_layer = + std::unique_ptr<LayerImpl> scroll_clip_layer = LayerImpl::Create(host_impl_->active_tree(), 3); scroll_clip_layer->SetBounds(surface_size); - scoped_ptr<LayerImpl> scroll_layer = + std::unique_ptr<LayerImpl> scroll_layer = LayerImpl::Create(host_impl_->active_tree(), 2); scroll_layer->SetScrollClipLayer(3); scroll_layer->SetBounds(contents_size); @@ -4627,7 +4697,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { scroll_layer->AddChild(std::move(content_layer)); scroll_clip_layer->AddChild(std::move(scroll_layer)); - scroll_clip_layer->SetForceRenderSurface(true); + scroll_clip_layer->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(scroll_clip_layer)); host_impl_->SetViewportSize(surface_size); SetNeedsRebuildPropertyTrees(); @@ -4646,10 +4716,11 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { gfx::Size surface_size(10, 10); gfx::Size contents_size(20, 20); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(surface_size); root->AddChild(CreateScrollableLayer(2, contents_size, root.get())); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); host_impl_->SetViewportSize(surface_size); SetNeedsRebuildPropertyTrees(); @@ -4667,9 +4738,10 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { gfx::Size surface_size(10, 10); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_->active_tree(), 1); root->AddChild(CreateScrollableLayer(2, surface_size, root.get())); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); host_impl_->SetViewportSize(surface_size); SetNeedsRebuildPropertyTrees(); @@ -4689,16 +4761,17 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { gfx::Size surface_size(10, 10); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetForceRenderSurface(true); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_->active_tree(), 1); + root->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size, root.get()); host_impl_->SetViewportSize(surface_size); gfx::Transform matrix; matrix.RotateAboutXAxis(180.0); child->SetTransform(matrix); - child->SetDoubleSided(false); + child->test_properties()->double_sided = false; root->AddChild(std::move(child)); host_impl_->active_tree()->SetRootLayer(std::move(root)); @@ -4719,9 +4792,9 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { gfx::Size surface_size(10, 10); - scoped_ptr<LayerImpl> clip_layer = + std::unique_ptr<LayerImpl> clip_layer = LayerImpl::Create(host_impl_->active_tree(), 3); - scoped_ptr<LayerImpl> content_layer = + std::unique_ptr<LayerImpl> content_layer = CreateScrollableLayer(1, surface_size, clip_layer.get()); content_layer->set_main_thread_scrolling_reasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); @@ -4729,11 +4802,11 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { // Note: we can use the same clip layer for both since both calls to // CreateScrollableLayer() use the same surface size. - scoped_ptr<LayerImpl> scroll_layer = + std::unique_ptr<LayerImpl> scroll_layer = CreateScrollableLayer(2, surface_size, clip_layer.get()); scroll_layer->AddChild(std::move(content_layer)); clip_layer->AddChild(std::move(scroll_layer)); - clip_layer->SetForceRenderSurface(true); + clip_layer->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(clip_layer)); host_impl_->SetViewportSize(surface_size); @@ -4782,7 +4855,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { // Set new page scale from main thread. host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f); - scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(), expected_scroll_delta)); @@ -4834,7 +4908,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { DrawOneFrame(); // The scroll delta is not scaled because the main thread did not scale. - scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(), expected_scroll_delta)); @@ -4863,9 +4938,9 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { LayerImpl* child = scroll->children()[0]; child->SetDrawsContent(true); - scoped_ptr<LayerImpl> scrollable_child_clip = + std::unique_ptr<LayerImpl> scrollable_child_clip = LayerImpl::Create(host_impl_->active_tree(), 6); - scoped_ptr<LayerImpl> scrollable_child = + std::unique_ptr<LayerImpl> scrollable_child = CreateScrollableLayer(7, surface_size, scrollable_child_clip.get()); scrollable_child_clip->AddChild(std::move(scrollable_child)); child->AddChild(std::move(scrollable_child_clip)); @@ -4929,7 +5004,8 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { DrawOneFrame(); - scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(), expected_scroll_delta)); @@ -4946,13 +5022,14 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { // parent layer isn't scrolled. gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(surface_size); - root->SetForceRenderSurface(true); - scoped_ptr<LayerImpl> grand_child = + root->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, content_size, root.get()); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size, root.get()); LayerImpl* grand_child_layer = grand_child.get(); child->AddChild(std::move(grand_child)); @@ -4982,7 +5059,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); // The grand child should have scrolled up to its limit. @@ -5001,19 +5078,20 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { // the scroll doesn't bubble up to the parent layer. gfx::Size surface_size(20, 20); gfx::Size viewport_size(10, 10); - scoped_ptr<LayerImpl> root_ptr = + std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl_->active_tree(), 1); - scoped_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 2); - root_clip->SetForceRenderSurface(true); - scoped_ptr<LayerImpl> root_scrolling = + root_clip->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(3, surface_size, root_clip.get()); - root_scrolling->SetIsContainerForFixedPositionLayers(true); + root_scrolling->test_properties()->is_container_for_fixed_position_layers = + true; - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = CreateScrollableLayer(5, surface_size, root_clip.get()); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(4, surface_size, root_clip.get()); LayerImpl* grand_child_layer = grand_child.get(); child->AddChild(std::move(grand_child)); @@ -5049,7 +5127,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); // The grand child should have scrolled up to its limit. @@ -5133,18 +5211,18 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { // should be applied to one of its ancestors if possible. gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - scoped_ptr<LayerImpl> root_ptr = + std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl_->active_tree(), 4); - scoped_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); - root_clip->SetForceRenderSurface(true); - scoped_ptr<LayerImpl> root_scroll = + root_clip->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer(1, content_size, root_clip.get()); // Make 'root' the clip layer for child: since they have the same sizes the // child will have zero max_scroll_offset and scrolls will bubble. - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size, root_scroll.get()); - child->SetIsContainerForFixedPositionLayers(true); + child->test_properties()->is_container_for_fixed_position_layers = true; root_scroll->SetBounds(content_size); int root_scroll_id = root_scroll->id(); @@ -5168,7 +5246,7 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); // Only the root scroll should have scrolled. @@ -5180,14 +5258,14 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { gfx::Size surface_size(10, 10); - scoped_ptr<LayerImpl> root_ptr = + std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl_->active_tree(), 1); - scoped_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 2); - scoped_ptr<LayerImpl> root_scroll = + std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer(3, surface_size, root_clip.get()); - root_scroll->SetIsContainerForFixedPositionLayers(true); - root_clip->SetForceRenderSurface(true); + root_clip->test_properties()->force_render_surface = true; + root_scroll->test_properties()->is_container_for_fixed_position_layers = true; root_clip->AddChild(std::move(root_scroll)); root_ptr->AddChild(std::move(root_clip)); host_impl_->active_tree()->SetRootLayer(std::move(root_ptr)); @@ -5201,15 +5279,16 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { SetNeedsRebuildPropertyTrees(); DrawFrame(); host_impl_->active_tree()->ClearLayers(); - scoped_ptr<LayerImpl> root_ptr2 = + std::unique_ptr<LayerImpl> root_ptr2 = LayerImpl::Create(host_impl_->active_tree(), 4); - scoped_ptr<LayerImpl> root_clip2 = + std::unique_ptr<LayerImpl> root_clip2 = LayerImpl::Create(host_impl_->active_tree(), 5); - scoped_ptr<LayerImpl> root_scroll2 = + std::unique_ptr<LayerImpl> root_scroll2 = CreateScrollableLayer(6, surface_size, root_clip2.get()); - root_scroll2->SetIsContainerForFixedPositionLayers(true); + root_scroll2->test_properties()->is_container_for_fixed_position_layers = + true; root_clip2->AddChild(std::move(root_scroll2)); - root_clip2->SetForceRenderSurface(true); + root_clip2->test_properties()->force_render_surface = true; root_ptr2->AddChild(std::move(root_clip2)); host_impl_->active_tree()->SetRootLayer(std::move(root_ptr2)); host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 6, @@ -5250,7 +5329,8 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { host_impl_->ScrollEnd(EndState().get()); // The layer should have scrolled down in its local coordinates. - scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(), gfx::Vector2d(0, gesture_scroll_delta.x()))); @@ -5277,9 +5357,9 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { float child_layer_angle = -20.f; // Create a child layer that is rotated to a non-axis-aligned angle. - scoped_ptr<LayerImpl> clip_layer = + std::unique_ptr<LayerImpl> clip_layer = LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - scoped_ptr<LayerImpl> child = CreateScrollableLayer( + std::unique_ptr<LayerImpl> child = CreateScrollableLayer( child_layer_id, scroll_layer->bounds(), clip_layer.get()); gfx::Transform rotate_transform; rotate_transform.Translate(-50.0, -50.0); @@ -5293,8 +5373,8 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { // The rotation 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() * 0.5f, clip_layer->bounds().height(), 0.f)); + clip_layer->test_properties()->transform_origin = gfx::Point3F( + clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f); LayerImpl* child_ptr = child.get(); clip_layer->AddChild(std::move(child)); scroll_layer->AddChild(std::move(clip_layer)); @@ -5319,7 +5399,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { gfx::Vector2d expected_scroll_delta( 0, gesture_scroll_delta.y() * std::cos(MathUtil::Deg2Rad(child_layer_angle))); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id, expected_scroll_delta)); @@ -5344,7 +5424,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { gfx::Vector2d expected_scroll_delta( 0, -gesture_scroll_delta.x() * std::sin(MathUtil::Deg2Rad(child_layer_angle))); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id, expected_scroll_delta)); @@ -5362,9 +5442,9 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { int child_layer_id = 7; // Create a child layer that is rotated on its x axis, with perspective. - scoped_ptr<LayerImpl> clip_layer = + std::unique_ptr<LayerImpl> clip_layer = LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - scoped_ptr<LayerImpl> child = CreateScrollableLayer( + std::unique_ptr<LayerImpl> child = CreateScrollableLayer( child_layer_id, scroll_layer->bounds(), clip_layer.get()); LayerImpl* child_ptr = child.get(); gfx::Transform perspective_transform; @@ -5379,15 +5459,15 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { // 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->test_properties()->transform_origin = gfx::Point3F( + clip_layer->bounds().width(), clip_layer->bounds().height(), 0.f); clip_layer->AddChild(std::move(child)); scroll_layer->AddChild(std::move(clip_layer)); gfx::Size surface_size(50, 50); host_impl_->SetViewportSize(surface_size); - scoped_ptr<ScrollAndScaleSet> scroll_info; + std::unique_ptr<ScrollAndScaleSet> scroll_info; gfx::Vector2d gesture_scroll_deltas[4]; gesture_scroll_deltas[0] = gfx::Vector2d(4, 10); @@ -5461,7 +5541,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(); + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(), gfx::Vector2d(0, scroll_delta.y() / scale))); @@ -5832,17 +5913,17 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { // overscroll does not accumulate. InputHandlerScrollResult scroll_result; gfx::Size surface_size(10, 10); - scoped_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 4); - root_clip->SetForceRenderSurface(true); + root_clip->test_properties()->force_render_surface = true; - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size, root_clip.get()); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size, root_clip.get()); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size, root_clip.get()); LayerImpl* grand_child_layer = grand_child.get(); child->AddChild(std::move(grand_child)); @@ -6036,10 +6117,11 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { class BlendStateCheckLayer : public LayerImpl { public: - static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, - int id, - ResourceProvider* resource_provider) { - return make_scoped_ptr( + static std::unique_ptr<LayerImpl> Create( + LayerTreeImpl* tree_impl, + int id, + ResourceProvider* resource_provider) { + return base::WrapUnique( new BlendStateCheckLayer(tree_impl, id, resource_provider)); } @@ -6118,11 +6200,11 @@ class BlendStateCheckLayer : public LayerImpl { TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(false); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); } LayerImpl* root = host_impl_->active_tree()->root_layer(); @@ -6244,7 +6326,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); layer1->NoteLayerPropertyChanged(); - layer1->SetForceRenderSurface(true); + layer1->test_properties()->force_render_surface = true; layer1->SetExpectation(false, true); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false); @@ -6257,7 +6339,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); host_impl_->DidDrawAllLayers(frame); - layer1->SetForceRenderSurface(false); + layer1->test_properties()->force_render_surface = false; // Draw again, but with child non-opaque, to make sure // layer1 not culled. @@ -6376,10 +6458,10 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { child_(NULL), did_activate_pending_tree_(false) {} - scoped_ptr<OutputSurface> CreateFakeOutputSurface(bool software) { + std::unique_ptr<OutputSurface> CreateFakeOutputSurface(bool software) { if (software) { return FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice())); + base::WrapUnique(new SoftwareOutputDevice())); } return FakeOutputSurface::Create3d(); } @@ -6388,7 +6470,10 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { host_impl_->active_tree()->set_background_color(SK_ColorGRAY); host_impl_->active_tree()->SetRootLayer( LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->root_layer()->SetForceRenderSurface(true); + host_impl_->active_tree() + ->root_layer() + ->test_properties() + ->force_render_surface = true; host_impl_->active_tree()->root_layer()->AddChild( BlendStateCheckLayer::Create(host_impl_->active_tree(), 2, @@ -6670,8 +6755,8 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) { class FakeDrawableLayerImpl: public LayerImpl { public: - static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr(new FakeDrawableLayerImpl(tree_impl, id)); + static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { + return base::WrapUnique(new FakeDrawableLayerImpl(tree_impl, id)); } protected: FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id) @@ -6683,15 +6768,15 @@ class FakeDrawableLayerImpl: public LayerImpl { // viewport size is never set. TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) { scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(provider)); CreateHostImpl(DefaultSettings(), std::move(output_surface)); - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); EXPECT_FALSE(provider->TestContext3d()->reshape_called()); provider->TestContext3d()->clear_reshape_called(); @@ -6737,7 +6822,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { context_provider->BindToCurrentThread(); context_provider->TestContext3d()->set_have_post_sub_buffer(true); - scoped_ptr<FakeOutputSurface> output_surface( + std::unique_ptr<FakeOutputSurface> output_surface( FakeOutputSurface::Create3d(context_provider)); FakeOutputSurface* fake_output_surface = output_surface.get(); @@ -6745,7 +6830,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { // that we can force partial swap enabled. LayerTreeSettings settings = DefaultSettings(); settings.renderer_settings.partial_swap_enabled = true; - scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl = + std::unique_ptr<LayerTreeHostImpl> layer_tree_host_impl = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &shared_bitmap_manager_, NULL, &task_graph_runner_, 0); @@ -6755,10 +6840,10 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE)); layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500)); - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1); - root->SetForceRenderSurface(true); - scoped_ptr<LayerImpl> child = + root->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> child = FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2); child->SetPosition(gfx::PointF(12.f, 13.f)); child->SetBounds(gfx::Size(14, 15)); @@ -6819,15 +6904,15 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { } TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2); child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; root->AddChild(std::move(child)); host_impl_->active_tree()->SetRootLayer(std::move(root)); @@ -6842,8 +6927,8 @@ TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { class FakeLayerWithQuads : public LayerImpl { public: - static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr(new FakeLayerWithQuads(tree_impl, id)); + static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { + return base::WrapUnique(new FakeLayerWithQuads(tree_impl, id)); } void AppendQuads(RenderPass* render_pass, @@ -6954,7 +7039,7 @@ class MockContextHarness { }; TEST_F(LayerTreeHostImplTest, NoPartialSwap) { - scoped_ptr<MockContext> mock_context_owned(new MockContext); + std::unique_ptr<MockContext> mock_context_owned(new MockContext); MockContext* mock_context = mock_context_owned.get(); MockContextHarness harness(mock_context); @@ -6994,7 +7079,7 @@ TEST_F(LayerTreeHostImplTest, NoPartialSwap) { } TEST_F(LayerTreeHostImplTest, PartialSwap) { - scoped_ptr<MockContext> context_owned(new MockContext); + std::unique_ptr<MockContext> context_owned(new MockContext); MockContext* mock_context = context_owned.get(); MockContextHarness harness(mock_context); @@ -7031,7 +7116,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwap) { Mock::VerifyAndClearExpectations(&mock_context); } -static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( +static std::unique_ptr<LayerTreeHostImpl> SetupLayersForOpacity( LayerTreeSettings settings, bool partial_swap, LayerTreeHostImplClient* client, @@ -7041,7 +7126,7 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( RenderingStatsInstrumentation* stats_instrumentation, OutputSurface* output_surface) { settings.renderer_settings.partial_swap_enabled = partial_swap; - scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( + std::unique_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( settings, client, task_runner_provider, stats_instrumentation, manager, nullptr, task_graph_runner, 0); my_host_impl->SetVisible(true); @@ -7068,18 +7153,18 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( Layers 1, 2 have render surfaces */ - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(my_host_impl->active_tree(), 1); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(my_host_impl->active_tree(), 2); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3); gfx::Rect root_rect(0, 0, 100, 100); gfx::Rect child_rect(10, 10, 50, 50); gfx::Rect grand_child_rect(5, 5, 150, 150); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; root->SetPosition(gfx::PointF(root_rect.origin())); root->SetBounds(root_rect.size()); root->draw_properties().visible_layer_rect = root_rect; @@ -7090,7 +7175,7 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( child->SetBounds(gfx::Size(child_rect.width(), child_rect.height())); child->draw_properties().visible_layer_rect = child_rect; child->SetDrawsContent(false); - child->SetForceRenderSurface(true); + child->test_properties()->force_render_surface = true; grand_child->SetPosition(gfx::PointF(grand_child_rect.origin())); grand_child->SetBounds(grand_child_rect.size()); @@ -7111,9 +7196,9 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); provider->BindToCurrentThread(); provider->TestContext3d()->set_have_post_sub_buffer(true); - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(provider)); - scoped_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( + std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( DefaultSettings(), true, this, &task_runner_provider_, &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_, output_surface.get()); @@ -7141,9 +7226,9 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); provider->BindToCurrentThread(); provider->TestContext3d()->set_have_post_sub_buffer(true); - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(provider)); - scoped_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( + std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( DefaultSettings(), false, this, &task_runner_provider_, &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_, output_surface.get()); @@ -7166,36 +7251,29 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { } TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { - scoped_ptr<TestWebGraphicsContext3D> context = + std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); - scoped_ptr<OutputSurface> output_surface( + std::unique_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(std::move(context))); CreateHostImpl(DefaultSettings(), std::move(output_surface)); - scoped_ptr<LayerImpl> root_layer = + std::unique_ptr<LayerImpl> root_layer = LayerImpl::Create(host_impl_->active_tree(), 1); root_layer->SetBounds(gfx::Size(10, 10)); - root_layer->SetForceRenderSurface(true); + root_layer->test_properties()->force_render_surface = true; scoped_refptr<VideoFrame> softwareFrame = media::VideoFrame::CreateColorFrame( gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); FakeVideoFrameProvider provider; provider.set_frame(softwareFrame); - scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( + std::unique_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->SetDrawsContent(true); root_layer->AddChild(std::move(video_layer)); - scoped_ptr<IOSurfaceLayerImpl> io_surface_layer = - IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5); - io_surface_layer->SetBounds(gfx::Size(10, 10)); - io_surface_layer->SetDrawsContent(true); - io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10)); - root_layer->AddChild(std::move(io_surface_layer)); - host_impl_->active_tree()->SetRootLayer(std::move(root_layer)); EXPECT_EQ(0u, context3d->NumTextures()); @@ -7225,7 +7303,7 @@ class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D { }; TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { - scoped_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned( + std::unique_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned( new MockDrawQuadsToFillScreenContext); MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get(); @@ -7261,7 +7339,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { class LayerTreeHostImplTestWithDelegatingRenderer : public LayerTreeHostImplTest { protected: - scoped_ptr<OutputSurface> CreateOutputSurface() override { + std::unique_ptr<OutputSurface> CreateOutputSurface() override { return FakeOutputSurface::CreateDelegating3d(); } @@ -7303,15 +7381,15 @@ class LayerTreeHostImplTestWithDelegatingRenderer }; TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) { - scoped_ptr<SolidColorLayerImpl> root = + std::unique_ptr<SolidColorLayerImpl> root = SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; // Child layer is in the bottom right corner. - scoped_ptr<SolidColorLayerImpl> child = + std::unique_ptr<SolidColorLayerImpl> child = SolidColorLayerImpl::Create(host_impl_->active_tree(), 2); child->SetPosition(gfx::PointF(9.f, 9.f)); child->SetBounds(gfx::Size(1, 1)); @@ -7362,14 +7440,14 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f / 16.f, 16.f); - scoped_ptr<LayerImpl> scoped_root = + std::unique_ptr<LayerImpl> scoped_root = LayerImpl::Create(host_impl_->pending_tree(), 1); LayerImpl* root = scoped_root.get(); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->pending_tree()->SetRootLayer(std::move(scoped_root)); - scoped_ptr<LayerImpl> scoped_scrolling_layer = + std::unique_ptr<LayerImpl> scoped_scrolling_layer = LayerImpl::Create(host_impl_->pending_tree(), 2); LayerImpl* scrolling_layer = scoped_scrolling_layer.get(); root->AddChild(std::move(scoped_scrolling_layer)); @@ -7378,7 +7456,7 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(content_layer_bounds)); - scoped_ptr<FakePictureLayerImpl> scoped_content_layer = + std::unique_ptr<FakePictureLayerImpl> scoped_content_layer = FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), 3, raster_source); LayerImpl* content_layer = scoped_content_layer.get(); @@ -7473,7 +7551,7 @@ TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { CountingSoftwareDevice* software_device = new CountingSoftwareDevice(); EXPECT_TRUE(CreateHostImpl( DefaultSettings(), - FakeOutputSurface::CreateSoftware(make_scoped_ptr(software_device)))); + FakeOutputSurface::CreateSoftware(base::WrapUnique(software_device)))); host_impl_->SetViewportSize(gfx::Size(50, 50)); SetupScrollAndContentsLayers(gfx::Size(100, 100)); @@ -7495,7 +7573,7 @@ TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { EXPECT_EQ(1, software_device->frames_ended_); // Call another API method that is likely to hit nullptr in this mode. - scoped_ptr<base::trace_event::TracedValue> state( + std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); host_impl_->ActivationStateAsValueInto(state.get()); } @@ -7503,9 +7581,9 @@ TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) { set_reduce_memory_result(false); - EXPECT_TRUE(CreateHostImpl(DefaultSettings(), - FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new CountingSoftwareDevice)))); + EXPECT_TRUE(CreateHostImpl( + DefaultSettings(), FakeOutputSurface::CreateSoftware( + base::WrapUnique(new CountingSoftwareDevice)))); const gfx::Transform external_transform; const gfx::Rect external_viewport; @@ -7515,12 +7593,12 @@ TEST_F(LayerTreeHostImplTest, external_transform); // SolidColorLayerImpl will be drawn. - scoped_ptr<SolidColorLayerImpl> root_layer = + std::unique_ptr<SolidColorLayerImpl> root_layer = SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); // VideoLayerImpl will not be drawn. FakeVideoFrameProvider provider; - scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( + std::unique_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->SetDrawsContent(true); @@ -7626,10 +7704,11 @@ TEST_F(LayerTreeHostImplTestPrepareTiles, PrepareTilesWhenInvisible) { } TEST_F(LayerTreeHostImplTest, UIResourceManagement) { - scoped_ptr<TestWebGraphicsContext3D> context = + std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); - scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<FakeOutputSurface> output_surface = + FakeOutputSurface::Create3d(); CreateHostImpl(DefaultSettings(), std::move(output_surface)); EXPECT_EQ(0u, context3d->NumTextures()); @@ -7669,7 +7748,7 @@ TEST_F(LayerTreeHostImplTest, UIResourceManagement) { } TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { - scoped_ptr<TestWebGraphicsContext3D> context = + std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); CreateHostImpl(DefaultSettings(), FakeOutputSurface::Create3d()); @@ -7682,10 +7761,9 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { // correct width/height are passed directly to UIResourceBitmap. SkImageInfo info = SkImageInfo::Make(4, 2, kAlpha_8_SkColorType, kPremul_SkAlphaType); - skia::RefPtr<SkPixelRef> pixel_ref = - skia::AdoptRef(SkMallocPixelRef::NewAllocate(info, 0, 0)); + sk_sp<SkPixelRef> pixel_ref(SkMallocPixelRef::NewAllocate(info, 0, 0)); pixel_ref->setImmutable(); - UIResourceBitmap bitmap(pixel_ref, size); + UIResourceBitmap bitmap(std::move(pixel_ref), size); UIResourceId ui_resource_id = 1; host_impl_->CreateUIResource(ui_resource_id, bitmap); EXPECT_EQ(1u, context3d->NumTextures()); @@ -7693,8 +7771,8 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { EXPECT_NE(0u, id1); } -void ShutdownReleasesContext_Callback(scoped_ptr<CopyOutputResult> result) { -} +void ShutdownReleasesContext_Callback( + std::unique_ptr<CopyOutputResult> result) {} TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { scoped_refptr<TestContextProvider> context_provider = @@ -7705,7 +7783,7 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - std::vector<scoped_ptr<CopyOutputRequest>> requests; + std::vector<std::unique_ptr<CopyOutputRequest>> requests; requests.push_back(CopyOutputRequest::CreateRequest( base::Bind(&ShutdownReleasesContext_Callback))); @@ -7735,16 +7813,16 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { // bubble). gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - scoped_ptr<LayerImpl> root_ptr = + std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl_->active_tree(), 4); - scoped_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); - root_clip->SetForceRenderSurface(true); + root_clip->test_properties()->force_render_surface = true; - scoped_ptr<LayerImpl> root_scroll = + std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer(1, content_size, root_clip.get()); - root_scroll->SetIsContainerForFixedPositionLayers(true); - scoped_ptr<LayerImpl> child = + root_scroll->test_properties()->is_container_for_fixed_position_layers = true; + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size, root_clip.get()); root_scroll->AddChild(std::move(child)); @@ -7775,7 +7853,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); // Only the child should have scrolled. @@ -7788,19 +7866,20 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { // Scroll a child layer beyond its maximum scroll range and make sure the // the scroll doesn't bubble up to the parent layer. gfx::Size surface_size(10, 10); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetForceRenderSurface(true); - scoped_ptr<LayerImpl> root_scrolling = + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_->active_tree(), 1); + root->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size, root.get()); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = CreateScrollableLayer(4, surface_size, root.get()); grand_child->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child->id(), gfx::ScrollOffset(0, 2)); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(3, surface_size, root.get()); child->layer_tree_impl() ->property_trees() @@ -7816,7 +7895,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { SetNeedsRebuildPropertyTrees(); DrawFrame(); { - scoped_ptr<ScrollAndScaleSet> scroll_info; + std::unique_ptr<ScrollAndScaleSet> scroll_info; LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0]->children()[0]; LayerImpl* grand_child = child->children()[0]; @@ -7876,13 +7955,13 @@ TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) { // When flinging via wheel, we shouldn't bubble. gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - scoped_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); - root_clip->SetForceRenderSurface(true); - scoped_ptr<LayerImpl> root_scroll = + root_clip->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer(1, content_size, root_clip.get()); int root_scroll_id = root_scroll->id(); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size, root_clip.get()); root_scroll->AddChild(std::move(child)); @@ -7908,7 +7987,7 @@ TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) { host_impl_->ScrollEnd(EndState().get()); - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); // The root shouldn't have scrolled. @@ -7933,7 +8012,7 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) { host_impl_->active_tree()->LayerById(page_scale_layer_id); int occluder_layer_id = 6; - scoped_ptr<LayerImpl> occluder_layer = + std::unique_ptr<LayerImpl> occluder_layer = LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); occluder_layer->SetDrawsContent(true); occluder_layer->SetBounds(content_size); @@ -7965,18 +8044,18 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { scroll_layer->SetDrawsContent(true); int occluder_layer_id = 6; - scoped_ptr<LayerImpl> occluder_layer = + std::unique_ptr<LayerImpl> occluder_layer = LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); occluder_layer->SetDrawsContent(true); occluder_layer->SetBounds(content_size); occluder_layer->SetPosition(gfx::PointF(-10.f, -10.f)); int child_scroll_clip_layer_id = 7; - scoped_ptr<LayerImpl> child_scroll_clip = + std::unique_ptr<LayerImpl> child_scroll_clip = LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id); int child_scroll_layer_id = 8; - scoped_ptr<LayerImpl> child_scroll = CreateScrollableLayer( + std::unique_ptr<LayerImpl> child_scroll = CreateScrollableLayer( child_scroll_layer_id, content_size, child_scroll_clip.get()); child_scroll->SetPosition(gfx::PointF(10.f, 10.f)); @@ -8006,7 +8085,7 @@ TEST_F(LayerTreeHostImplTest, NotScrollInvisibleScroller) { host_impl_->active_tree()->LayerById(scroll_layer_id); int child_scroll_layer_id = 7; - scoped_ptr<LayerImpl> child_scroll = + std::unique_ptr<LayerImpl> child_scroll = CreateScrollableLayer(child_scroll_layer_id, content_size, root); child_scroll->SetDrawsContent(false); @@ -8036,15 +8115,15 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleDescendent) { LayerImpl* root = host_impl_->active_tree()->LayerById(1); LayerImpl* root_scroll_layer = host_impl_->active_tree()->LayerById(2); - scoped_ptr<LayerImpl> invisible_scroll_layer = + std::unique_ptr<LayerImpl> invisible_scroll_layer = CreateScrollableLayer(7, content_size, root); invisible_scroll_layer->SetDrawsContent(false); - scoped_ptr<LayerImpl> child_layer = + std::unique_ptr<LayerImpl> child_layer = LayerImpl::Create(host_impl_->active_tree(), 8); child_layer->SetDrawsContent(false); - scoped_ptr<LayerImpl> grand_child_layer = + std::unique_ptr<LayerImpl> grand_child_layer = LayerImpl::Create(host_impl_->active_tree(), 9); grand_child_layer->SetDrawsContent(true); grand_child_layer->SetBounds(content_size); @@ -8083,7 +8162,7 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) { host_impl_->active_tree()->LayerById(scroll_layer_id); int scroll_child_id = 6; - scoped_ptr<LayerImpl> scroll_child = + std::unique_ptr<LayerImpl> scroll_child = LayerImpl::Create(host_impl_->active_tree(), scroll_child_id); scroll_child->SetDrawsContent(true); scroll_child->SetBounds(content_size); @@ -8091,19 +8170,21 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) { scroll_child->SetPosition(gfx::PointF(10.f, 10.f)); int invisible_scroll_layer_id = 7; - scoped_ptr<LayerImpl> invisible_scroll = + std::unique_ptr<LayerImpl> invisible_scroll = CreateScrollableLayer(invisible_scroll_layer_id, content_size, root); invisible_scroll->SetDrawsContent(false); int container_id = 8; - scoped_ptr<LayerImpl> container = + std::unique_ptr<LayerImpl> container = LayerImpl::Create(host_impl_->active_tree(), container_id); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child.get()); - invisible_scroll->SetScrollChildren(scroll_children.release()); + invisible_scroll->test_properties()->scroll_children.reset( + scroll_children.release()); - scroll_child->SetScrollParent(invisible_scroll.get()); + scroll_child->test_properties()->scroll_parent = invisible_scroll.get(); container->AddChild(std::move(invisible_scroll)); container->AddChild(std::move(scroll_child)); @@ -8127,12 +8208,12 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) { // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed // to CompositorFrameMetadata after SwapBuffers(); TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { - scoped_ptr<SolidColorLayerImpl> root = + std::unique_ptr<SolidColorLayerImpl> root = SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); @@ -8146,7 +8227,7 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { ui::LatencyInfo latency_info; latency_info.AddLatencyNumber( ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0); - scoped_ptr<SwapPromise> swap_promise( + std::unique_ptr<SwapPromise> swap_promise( new LatencyInfoSwapPromise(latency_info)); host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise)); host_impl_->SetNeedsRedraw(); @@ -8167,12 +8248,12 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { int root_layer_id = 1; - scoped_ptr<SolidColorLayerImpl> root = + std::unique_ptr<SolidColorLayerImpl> root = SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); root->SetPosition(gfx::PointF()); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetForceRenderSurface(true); + root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayer(std::move(root)); @@ -8250,12 +8331,10 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { int forward_to_main_count = 0; { - scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor(NULL, - host_impl_.get(), - &set_needs_commit_count, - &set_needs_redraw_count, - &forward_to_main_count)); + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor( + NULL, host_impl_.get(), &set_needs_commit_count, + &set_needs_redraw_count, &forward_to_main_count)); host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); @@ -8270,12 +8349,10 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { EXPECT_EQ(0, forward_to_main_count); { - scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor(NULL, - host_impl_.get(), - &set_needs_commit_count, - &set_needs_redraw_count, - &forward_to_main_count)); + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor( + NULL, host_impl_.get(), &set_needs_commit_count, + &set_needs_redraw_count, &forward_to_main_count)); host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10)); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(2, set_needs_redraw_count); @@ -8283,12 +8360,10 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { } { - scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor(NULL, - host_impl_.get(), - &set_needs_commit_count, - &set_needs_redraw_count, - &forward_to_main_count)); + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor( + NULL, host_impl_.get(), &set_needs_commit_count, + &set_needs_redraw_count, &forward_to_main_count)); // Empty damage rect won't signal the monitor. host_impl_->SetNeedsRedrawRect(gfx::Rect()); EXPECT_EQ(0, set_needs_commit_count); @@ -8300,12 +8375,10 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { set_needs_commit_count = 0; set_needs_redraw_count = 0; forward_to_main_count = 0; - scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor(NULL, - host_impl_.get(), - &set_needs_commit_count, - &set_needs_redraw_count, - &forward_to_main_count)); + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor( + NULL, host_impl_.get(), &set_needs_commit_count, + &set_needs_redraw_count, &forward_to_main_count)); SetupScrollAndContentsLayers(gfx::Size(100, 100)); // Scrolling normally should not trigger any forwarding. @@ -8831,31 +8904,33 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { const int kInnerViewportClipLayerId = 4; const int kPageScaleLayerId = 5; - scoped_ptr<LayerImpl> inner_scroll = + std::unique_ptr<LayerImpl> inner_scroll = LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); - inner_scroll->SetIsContainerForFixedPositionLayers(true); + inner_scroll->test_properties()->is_container_for_fixed_position_layers = + true; inner_scroll->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(), gfx::ScrollOffset()); - scoped_ptr<LayerImpl> inner_clip = + std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); inner_clip->SetBounds(inner_viewport); - scoped_ptr<LayerImpl> page_scale = + std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); inner_scroll->SetScrollClipLayer(inner_clip->id()); inner_scroll->SetBounds(outer_viewport); inner_scroll->SetPosition(gfx::PointF()); - scoped_ptr<LayerImpl> outer_clip = + std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId); outer_clip->SetBounds(outer_viewport); - outer_clip->SetIsContainerForFixedPositionLayers(true); + outer_clip->test_properties()->is_container_for_fixed_position_layers = + true; - scoped_ptr<LayerImpl> outer_scroll = + std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); outer_scroll->SetScrollClipLayer(outer_clip->id()); outer_scroll->layer_tree_impl() @@ -8865,8 +8940,7 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { outer_scroll->SetBounds(content_size); outer_scroll->SetPosition(gfx::PointF()); - scoped_ptr<LayerImpl> contents = - LayerImpl::Create(layer_tree_impl, 8); + std::unique_ptr<LayerImpl> contents = LayerImpl::Create(layer_tree_impl, 8); contents->SetDrawsContent(true); contents->SetBounds(content_size); contents->SetPosition(gfx::PointF()); @@ -8877,7 +8951,7 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { page_scale->AddChild(std::move(inner_scroll)); inner_clip->AddChild(std::move(page_scale)); - inner_clip->SetForceRenderSurface(true); + inner_clip->test_properties()->force_render_surface = true; layer_tree_impl->SetRootLayer(std::move(inner_clip)); layer_tree_impl->SetViewportLayersFromIds( Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId, @@ -9056,7 +9130,7 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport, outer_scroll); LayerImpl* child_scroll = child.get(); outer_scroll->children()[0]->AddChild(std::move(child)); @@ -9064,7 +9138,7 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, SetNeedsRebuildPropertyTrees(); DrawFrame(); { - scoped_ptr<ScrollAndScaleSet> scroll_info; + std::unique_ptr<ScrollAndScaleSet> scroll_info; gfx::Vector2d scroll_delta(0, inner_viewport.height()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -9124,7 +9198,7 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport, outer_scroll); LayerImpl* child_scroll = child.get(); outer_scroll->children()[0]->AddChild(std::move(child)); @@ -9291,7 +9365,7 @@ TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) { class ResourcelessSoftwareLayerTreeHostImplTest : public LayerTreeHostImplTest { protected: - scoped_ptr<OutputSurface> CreateOutputSurface() override { + std::unique_ptr<OutputSurface> CreateOutputSurface() override { return FakeOutputSurface::Create3dWithResourcelessSoftwareSupport(); } }; @@ -9335,7 +9409,7 @@ TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, host_impl_->CreatePendingTree(); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(viewport_size)); - scoped_ptr<FakePictureLayerImpl> layer( + std::unique_ptr<FakePictureLayerImpl> layer( FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), 11, raster_source)); layer->SetBounds(viewport_size); @@ -9480,7 +9554,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { host_impl_->active_tree()->OuterViewportScrollLayer()->children()[0]; content_layer->AddChild(LayerImpl::Create(host_impl_->active_tree(), 100)); LayerImpl* test_layer = host_impl_->active_tree()->LayerById(100); - test_layer->SetForceRenderSurface(true); + test_layer->test_properties()->force_render_surface = true; test_layer->SetDrawsContent(true); test_layer->SetBounds(layer_size); gfx::Transform perspective_transform; @@ -9646,7 +9720,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { UpdateState(gfx::Point(0, y), gfx::Vector2d(0, 50)).get()); EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y + 50), InputHandler::WHEEL)); - scoped_ptr<ScrollState> scroll_state_end = EndState(); + std::unique_ptr<ScrollState> scroll_state_end = EndState(); host_impl_->ScrollEnd(scroll_state_end.get()); EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(), InputHandler::WHEEL)); @@ -10005,6 +10079,47 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) { host_impl_->DidFinishImplFrame(); } +// Test that smooth scrolls clamp correctly when bounds change mid-animation. +TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) { + const gfx::Size old_content_size(1000, 1000); + const gfx::Size new_content_size(750, 750); + const gfx::Size viewport_size(500, 500); + + LayerImpl* content_layer = + CreateBasicVirtualViewportLayers(viewport_size, old_content_size); + SetNeedsRebuildPropertyTrees(); + DrawFrame(); + + base::TimeTicks start_time = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(100); + BeginFrameArgs begin_frame_args = + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE); + + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(500, 500)); + LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer(); + + begin_frame_args.frame_time = start_time; + host_impl_->WillBeginImplFrame(begin_frame_args); + host_impl_->Animate(); + host_impl_->UpdateAnimationState(true); + host_impl_->DidFinishImplFrame(); + + content_layer->SetBounds(new_content_size); + scrolling_layer->SetBounds(new_content_size); + SetNeedsRebuildPropertyTrees(); + DrawFrame(); + + begin_frame_args.frame_time = + start_time + base::TimeDelta::FromMilliseconds(200); + host_impl_->WillBeginImplFrame(begin_frame_args); + host_impl_->Animate(); + host_impl_->UpdateAnimationState(true); + host_impl_->DidFinishImplFrame(); + + EXPECT_EQ(gfx::ScrollOffset(250, 250), + scrolling_layer->CurrentScrollOffset()); +} + TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { host_impl_->CreatePendingTree(); @@ -10012,7 +10127,7 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { scoped_refptr<RasterSource> raster_source_with_tiles( FakeRasterSource::CreateFilled(gfx::Size(10, 10))); - scoped_ptr<FakePictureLayerImpl> layer = + std::unique_ptr<FakePictureLayerImpl> layer = FakePictureLayerImpl::Create(host_impl_->pending_tree(), 11); layer->SetBounds(gfx::Size(10, 10)); layer->set_gpu_raster_max_texture_size(host_impl_->device_viewport_size()); @@ -10023,21 +10138,21 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { layer->tilings()->tiling_at(0)->set_resolution( TileResolution::HIGH_RESOLUTION); layer->tilings()->tiling_at(0)->CreateAllTilesForTesting(); - layer->tilings()->tiling_at(0)->ComputeTilePriorityRects( - gfx::Rect(gfx::Size(10, 10)), 1.f, 1.0, Occlusion()); + layer->tilings()->UpdateTilePriorities(gfx::Rect(gfx::Size(10, 10)), 1.f, 1.0, + Occlusion(), true); host_impl_->pending_tree()->SetRootLayer(std::move(layer)); FakePictureLayerImpl* root_layer = static_cast<FakePictureLayerImpl*>( host_impl_->pending_tree()->root_layer()); root_layer->set_has_valid_tile_priorities(true); - scoped_ptr<RasterTilePriorityQueue> non_empty_raster_priority_queue_all = + std::unique_ptr<RasterTilePriorityQueue> non_empty_raster_priority_queue_all = host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL); EXPECT_FALSE(non_empty_raster_priority_queue_all->IsEmpty()); root_layer->set_has_valid_tile_priorities(false); - scoped_ptr<RasterTilePriorityQueue> empty_raster_priority_queue_all = + std::unique_ptr<RasterTilePriorityQueue> empty_raster_priority_queue_all = host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL); EXPECT_TRUE(empty_raster_priority_queue_all->IsEmpty()); @@ -10050,7 +10165,7 @@ TEST_F(LayerTreeHostImplTest, DidBecomeActive) { LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - scoped_ptr<FakePictureLayerImpl> pending_layer = + std::unique_ptr<FakePictureLayerImpl> pending_layer = FakePictureLayerImpl::Create(pending_tree, 10); FakePictureLayerImpl* raw_pending_layer = pending_layer.get(); pending_tree->SetRootLayer(std::move(pending_layer)); @@ -10060,7 +10175,7 @@ TEST_F(LayerTreeHostImplTest, DidBecomeActive) { pending_tree->DidBecomeActive(); EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); - scoped_ptr<FakePictureLayerImpl> mask_layer = + std::unique_ptr<FakePictureLayerImpl> mask_layer = FakePictureLayerImpl::Create(pending_tree, 11); FakePictureLayerImpl* raw_mask_layer = mask_layer.get(); raw_pending_layer->SetMaskLayer(std::move(mask_layer)); @@ -10072,9 +10187,9 @@ TEST_F(LayerTreeHostImplTest, DidBecomeActive) { EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); - scoped_ptr<FakePictureLayerImpl> replica_layer = + std::unique_ptr<FakePictureLayerImpl> replica_layer = FakePictureLayerImpl::Create(pending_tree, 12); - scoped_ptr<FakePictureLayerImpl> replica_mask_layer = + std::unique_ptr<FakePictureLayerImpl> replica_mask_layer = FakePictureLayerImpl::Create(pending_tree, 13); FakePictureLayerImpl* raw_replica_mask_layer = replica_mask_layer.get(); replica_layer->SetMaskLayer(std::move(replica_mask_layer)); @@ -10153,7 +10268,7 @@ TEST_F(LayerTreeHostImplCountingLostSurfaces, TwiceLostSurface) { size_t CountRenderPassesWithId(const RenderPassList& list, RenderPassId id) { return std::count_if( list.begin(), list.end(), - [id](const scoped_ptr<RenderPass>& p) { return p->id == id; }); + [id](const std::unique_ptr<RenderPass>& p) { return p->id == id; }); } TEST_F(LayerTreeHostImplTest, RemoveUnreferencedRenderPass) { @@ -10372,7 +10487,7 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) { EXPECT_FALSE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); - scoped_ptr<TestWebGraphicsContext3D> context_with_msaa = + std::unique_ptr<TestWebGraphicsContext3D> context_with_msaa = TestWebGraphicsContext3D::Create(); context_with_msaa->SetMaxSamples(8); @@ -10445,8 +10560,8 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // 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( + static std::unique_ptr<MockReclaimResourcesOutputSurface> Create3d() { + return base::WrapUnique(new MockReclaimResourcesOutputSurface( TestContextProvider::Create(), TestContextProvider::CreateWorker(), false)); } @@ -10468,7 +10583,7 @@ class MockReclaimResourcesOutputSurface : public FakeOutputSurface { // ensures that BeginCommit triggers ForceReclaimResources. See // crbug.com/489515. TEST_F(LayerTreeHostImplTest, BeginCommitReclaimsResources) { - scoped_ptr<MockReclaimResourcesOutputSurface> output_surface( + std::unique_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(); @@ -10530,7 +10645,8 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { LayerImpl* in_subtree_of_page_scale_layer = host_impl_->active_tree()->LayerById(100); - in_subtree_of_page_scale_layer->SetForceRenderSurface(true); + in_subtree_of_page_scale_layer->test_properties()->force_render_surface = + true; SetNeedsRebuildPropertyTrees(); RebuildPropertyTrees(); DrawFrame(); @@ -10613,5 +10729,31 @@ TEST_F(LayerTreeHostImplTest, JitterTest) { } } +// Checks that if we lose a GPU raster enabled OutputSurface and replace it +// with a software OutputSurface, LayerTreeHostImpl correctly re-computes GPU +// rasterization status. +TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnOutputSurfaceChange) { + LayerTreeSettings settings = DefaultSettings(); + settings.gpu_rasterization_forced = true; + + host_impl_ = LayerTreeHostImpl::Create( + settings, this, &task_runner_provider_, &stats_instrumentation_, + &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_, + 0); + host_impl_->SetVisible(true); + + // InitializeRenderer with a gpu-raster enabled output surface. + auto gpu_raster_output_surface = + FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()); + host_impl_->InitializeRenderer(gpu_raster_output_surface.get()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + + // Re-initialize with a software output surface. + output_surface_ = FakeOutputSurface::CreateSoftware( + base::WrapUnique(new SoftwareOutputDevice)); + host_impl_->InitializeRenderer(output_surface_.get()); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc index 278c7c51373..9923f24bec4 100644 --- a/chromium/cc/trees/layer_tree_host_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_perftest.cc @@ -284,8 +284,8 @@ class BrowserCompositorInvalidateLayerTreePerfTest name_stream << "name" << next_fence_sync_; gpu_mailbox.SetName( reinterpret_cast<const int8_t*>(name_stream.str().c_str())); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(&EmptyReleaseCallback)); + std::unique_ptr<SingleReleaseCallback> callback = + SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)); gpu::SyncToken next_sync_token(gpu::CommandBufferNamespace::GPU_IO, 0, gpu::CommandBufferId::FromUnsafeValue(1), diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index 9d356c48ea5..4e1f7d52200 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -144,9 +144,7 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest { scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create(); layer->SetIsDrawable(true); layer->SetBounds(gfx::Size(width, height)); - skia::RefPtr<const SkImage> image = - skia::AdoptRef(backing_store->newImageSnapshot()); - layer->SetImage(std::move(image)); + layer->SetImage(backing_store->makeImageSnapshot()); return layer; } @@ -168,9 +166,7 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest { bounds.width() - kMaskOffset * 2, bounds.height() - kMaskOffset * 2), paint); - skia::RefPtr<const SkImage> image = - skia::AdoptRef(surface->newImageSnapshot()); - mask->SetImage(std::move(image)); + mask->SetImage(surface->makeImageSnapshot()); layer->SetMaskLayer(mask.get()); } @@ -216,7 +212,7 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest { CreateSolidColorLayer(child_rect, color); lane->SetBlendMode(blend_mode); lane->SetOpacity(opacity); - lane->SetForceRenderSurface(true); + lane->SetForceRenderSurfaceForTesting(true); if (flags & kUseMasks) SetupMaskLayer(lane); if (flags & kUseColorMatrix) { diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index 34592e052a5..bfa8f81d312 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -226,6 +226,62 @@ TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_Software) { RunPixelTestType(50, 2.f, PIXEL_TEST_SOFTWARE); } +class LayerTreeHostNullFilterPixelTest : public LayerTreeHostFiltersPixelTest { + void InitializeSettings(LayerTreeSettings* settings) override {} + + protected: + void RunPixelTestType(PixelTestType test_type) { + scoped_refptr<SolidColorLayer> foreground = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorGREEN); + + FilterOperations filters; + filters.Append(FilterOperation::CreateReferenceFilter(nullptr)); + foreground->SetFilters(filters); + + RunPixelTest(test_type, foreground, + base::FilePath(FILE_PATH_LITERAL("green.png"))); + } +}; + +TEST_F(LayerTreeHostNullFilterPixelTest, GL) { + RunPixelTestType(PIXEL_TEST_GL); +} + +TEST_F(LayerTreeHostNullFilterPixelTest, Software) { + RunPixelTestType(PIXEL_TEST_SOFTWARE); +} + +class LayerTreeHostCroppedFilterPixelTest + : public LayerTreeHostFiltersPixelTest { + void InitializeSettings(LayerTreeSettings* settings) override {} + + protected: + void RunPixelTestType(PixelTestType test_type) { + scoped_refptr<SolidColorLayer> foreground = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorGREEN); + + // Check that a filter with a zero-height crop rect crops out its + // result completely. + FilterOperations filters; + SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(0, 0, 100, 0)); + sk_sp<SkImageFilter> offset( + SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect)); + filters.Append(FilterOperation::CreateReferenceFilter(offset)); + foreground->SetFilters(filters); + + RunPixelTest(test_type, foreground, + base::FilePath(FILE_PATH_LITERAL("white.png"))); + } +}; + +TEST_F(LayerTreeHostCroppedFilterPixelTest, GL) { + RunPixelTestType(PIXEL_TEST_GL); +} + +TEST_F(LayerTreeHostCroppedFilterPixelTest, Software) { + RunPixelTestType(PIXEL_TEST_SOFTWARE); +} + class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest { protected: void RunPixelTestType(PixelTestType test_type) { @@ -246,12 +302,11 @@ class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest { matrix[2] = matrix[6] = matrix[10] = matrix[18] = SK_Scalar1; // We filter only the bottom 200x100 pixels of the foreground. SkImageFilter::CropRect crop_rect(SkRect::MakeXYWH(0, 100, 200, 100)); - sk_sp<SkColorFilter> color_filter = - SkColorFilter::MakeMatrixFilterRowMajor255(matrix); - skia::RefPtr<SkImageFilter> filter = skia::AdoptRef( - SkColorFilterImageFilter::Create(color_filter.get(), NULL, &crop_rect)); FilterOperations filters; - filters.Append(FilterOperation::CreateReferenceFilter(filter)); + filters.Append( + FilterOperation::CreateReferenceFilter(SkColorFilterImageFilter::Make( + SkColorFilter::MakeMatrixFilterRowMajor255(matrix), nullptr, + &crop_rect))); // Make the foreground layer's render surface be clipped by the background // layer. @@ -445,7 +500,7 @@ class ImageScaledRenderSurface : public LayerTreeHostFiltersPixelTest { gfx::Transform render_surface_transform; render_surface_transform.Scale(1.5f, 1.5f); render_surface_layer->SetTransform(render_surface_transform); - render_surface_layer->SetForceRenderSurface(true); + render_surface_layer->SetForceRenderSurfaceForTesting(true); background->AddChild(render_surface_layer); @@ -478,6 +533,111 @@ TEST_F(ImageScaledRenderSurface, ImageRenderSurfaceScaled_Software) { base::FilePath(FILE_PATH_LITERAL("scaled_render_surface_layer_sw.png"))); } +class RotatedFilterTest : public LayerTreeHostFiltersPixelTest { + protected: + void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(300, 300), SK_ColorWHITE); + + gfx::Rect rect(50, 50, 100, 100); + + scoped_refptr<SolidColorLayer> child = + CreateSolidColorLayer(rect, SK_ColorBLUE); + + gfx::Transform transform; + transform.Translate(50.0f, 50.0f); + transform.RotateAboutZAxis(1.0); + transform.Translate(-50.0f, -50.0f); + child->SetTransform(transform); + FilterOperations filters; + // We need a clamping brightness filter here to force the Skia filter path. + filters.Append(FilterOperation::CreateBrightnessFilter(1.1f)); + filters.Append(FilterOperation::CreateGrayscaleFilter(1.0f)); + child->SetFilters(filters); + + background->AddChild(child); + +#if defined(OS_WIN) + // Windows has 1 pixel off by 1: crbug.com/259915 + float percentage_pixels_large_error = 0.00111112f; // 1px / (300*300) + float percentage_pixels_small_error = 0.0f; + float average_error_allowed_in_bad_pixels = 1.f; + int large_error_allowed = 1; + int small_error_allowed = 0; + pixel_comparator_.reset(new FuzzyPixelComparator( + true, // discard_alpha + percentage_pixels_large_error, percentage_pixels_small_error, + average_error_allowed_in_bad_pixels, large_error_allowed, + small_error_allowed)); +#endif + + RunPixelTest(test_type, background, image_name); + } +}; + +TEST_F(RotatedFilterTest, RotatedFilterTest_GL) { + RunPixelTestType(PIXEL_TEST_GL, + base::FilePath(FILE_PATH_LITERAL("rotated_filter_gl.png"))); +} + +TEST_F(RotatedFilterTest, RotatedFilterTest_Software) { + RunPixelTestType(PIXEL_TEST_SOFTWARE, + base::FilePath(FILE_PATH_LITERAL("rotated_filter_sw.png"))); +} + +class RotatedDropShadowFilterTest : public LayerTreeHostFiltersPixelTest { + protected: + void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(300, 300), SK_ColorWHITE); + + gfx::Rect rect(50, 50, 100, 100); + + scoped_refptr<SolidColorLayer> child = + CreateSolidColorLayer(rect, SK_ColorBLUE); + + gfx::Transform transform; + transform.Translate(50.0f, 50.0f); + transform.RotateAboutZAxis(1.0); + transform.Translate(-50.0f, -50.0f); + child->SetTransform(transform); + FilterOperations filters; + filters.Append(FilterOperation::CreateDropShadowFilter( + gfx::Point(10.0f, 10.0f), 0.0f, SK_ColorBLACK)); + child->SetFilters(filters); + + background->AddChild(child); + +#if defined(OS_WIN) + // Windows has 2 pixels off by 1: crbug.com/259915 + float percentage_pixels_large_error = 0.00222223f; // 1px / (300*300) + float percentage_pixels_small_error = 0.0f; + float average_error_allowed_in_bad_pixels = 1.f; + int large_error_allowed = 1; + int small_error_allowed = 0; + pixel_comparator_.reset(new FuzzyPixelComparator( + true, // discard_alpha + percentage_pixels_large_error, percentage_pixels_small_error, + average_error_allowed_in_bad_pixels, large_error_allowed, + small_error_allowed)); +#endif + + RunPixelTest(test_type, background, image_name); + } +}; + +TEST_F(RotatedDropShadowFilterTest, RotatedDropShadowFilterTest_GL) { + RunPixelTestType( + PIXEL_TEST_GL, + base::FilePath(FILE_PATH_LITERAL("rotated_drop_shadow_filter_gl.png"))); +} + +TEST_F(RotatedDropShadowFilterTest, RotatedDropShadowFilterTest_Software) { + RunPixelTestType( + PIXEL_TEST_SOFTWARE, + base::FilePath(FILE_PATH_LITERAL("rotated_drop_shadow_filter_sw.png"))); +} + class EnlargedTextureWithAlphaThresholdFilter : public LayerTreeHostFiltersPixelTest { protected: @@ -561,9 +721,8 @@ class EnlargedTextureWithCropOffsetFilter FilterOperations filters; SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(10, 10, 80, 80)); - skia::RefPtr<SkImageFilter> filter( - skia::AdoptRef(SkOffsetImageFilter::Create(0, 0, nullptr, &cropRect))); - filters.Append(FilterOperation::CreateReferenceFilter(filter)); + filters.Append(FilterOperation::CreateReferenceFilter( + SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect))); filter_layer->SetFilters(filters); background->AddChild(filter_layer); @@ -607,12 +766,10 @@ class FilterWithGiantCropRectPixelTest : public LayerTreeHostFiltersPixelTest { FilterOperations filters; SkImageFilter::CropRect cropRect( SkRect::MakeXYWH(-40000, -40000, 80000, 80000)); - sk_sp<SkColorFilter> color_filter = - SkColorFilter::MakeMatrixFilterRowMajor255(matrix); - skia::RefPtr<SkImageFilter> filter( - skia::AdoptRef(SkColorFilterImageFilter::Create(color_filter.get(), - nullptr, &cropRect))); - filters.Append(FilterOperation::CreateReferenceFilter(filter)); + filters.Append( + FilterOperation::CreateReferenceFilter((SkColorFilterImageFilter::Make( + SkColorFilter::MakeMatrixFilterRowMajor255(matrix), nullptr, + &cropRect)))); filter_layer->SetFilters(filters); background->SetMasksToBounds(masks_to_bounds); background->AddChild(filter_layer); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index 4b950136cb0..a6380781470 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -39,7 +39,7 @@ class MaskContentLayerClient : public ContentLayerClient { scoped_refptr<DisplayItemList> PaintContentsToDisplayList( PaintingControlSetting picture_control) override { SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas = skia::SharePtr( + sk_sp<SkCanvas> canvas = sk_ref_sp( recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(bounds_)))); SkPaint paint; @@ -110,9 +110,7 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { client.PaintContentsToDisplayList( ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); mask_display_list->Raster(canvas, nullptr, gfx::Rect(mask_bounds), 1.0f); - skia::RefPtr<const SkImage> image = - skia::AdoptRef(surface->newImageSnapshot()); - mask->SetImage(std::move(image)); + mask->SetImage(surface->makeImageSnapshot()); scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder( gfx::Rect(25, 25, 50, 50), kCSSGreen, 1, SK_ColorBLACK); @@ -307,7 +305,7 @@ class CheckerContentLayerClient : public ContentLayerClient { scoped_refptr<DisplayItemList> PaintContentsToDisplayList( PaintingControlSetting picture_control) override { SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas = skia::SharePtr( + sk_sp<SkCanvas> canvas = sk_ref_sp( recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(bounds_)))); SkPaint paint; @@ -351,7 +349,7 @@ class CircleContentLayerClient : public ContentLayerClient { scoped_refptr<DisplayItemList> PaintContentsToDisplayList( PaintingControlSetting picture_control) override { SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas = skia::SharePtr( + sk_sp<SkCanvas> canvas = sk_ref_sp( recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(bounds_)))); SkPaint paint; diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc index 3b6dc81d460..3466a633add 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -60,8 +60,8 @@ class LayerTreeHostReadbackPixelTest RunPixelTestWithReadbackTarget(type, content_root, target, file_name); } - scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest() override { - scoped_ptr<CopyOutputRequest> request; + std::unique_ptr<CopyOutputRequest> CreateCopyOutputRequest() override { + std::unique_ptr<CopyOutputRequest> request; if (readback_type_ == READBACK_BITMAP) { request = CopyOutputRequest::CreateBitmapRequest( @@ -104,24 +104,24 @@ class LayerTreeHostReadbackPixelTest } } - void ReadbackResultAsBitmap(scoped_ptr<CopyOutputResult> result) { + void ReadbackResultAsBitmap(std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(task_runner_provider()->IsMainThread()); EXPECT_TRUE(result->HasBitmap()); result_bitmap_ = result->TakeBitmap(); EndTest(); } - void ReadbackResultAsTexture(scoped_ptr<CopyOutputResult> result) { + void ReadbackResultAsTexture(std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(task_runner_provider()->IsMainThread()); EXPECT_TRUE(result->HasTexture()); TextureMailbox texture_mailbox; - scoped_ptr<SingleReleaseCallback> release_callback; + std::unique_ptr<SingleReleaseCallback> release_callback; result->TakeTexture(&texture_mailbox, &release_callback); EXPECT_TRUE(texture_mailbox.IsValid()); EXPECT_TRUE(texture_mailbox.IsTexture()); - scoped_ptr<SkBitmap> bitmap = + std::unique_ptr<SkBitmap> bitmap = CopyTextureMailboxToBitmap(result->size(), texture_mailbox); release_callback->Run(gpu::SyncToken(), false); @@ -134,8 +134,7 @@ class LayerTreeHostReadbackPixelTest int insert_copy_request_after_frame_count_; }; -void IgnoreReadbackResult(scoped_ptr<CopyOutputResult> result) { -} +void IgnoreReadbackResult(std::unique_ptr<CopyOutputResult> result) {} TEST_P(LayerTreeHostReadbackPixelTest, ReadbackRootLayer) { scoped_refptr<SolidColorLayer> background = diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index 764e37dcf20..a7833ddd087 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -98,7 +98,7 @@ class LayerTreeHostTilesPixelTest : public LayerTreePixelTest { } base::FilePath ref_file_; - scoped_ptr<SkBitmap> result_bitmap_; + std::unique_ptr<SkBitmap> result_bitmap_; RasterMode raster_mode_; }; @@ -116,8 +116,8 @@ class BlueYellowClient : public ContentLayerClient { DisplayItemList::Create(PaintableRegion(), settings); SkPictureRecorder recorder; - skia::RefPtr<SkCanvas> canvas = skia::SharePtr( - recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(size_)))); + sk_sp<SkCanvas> canvas = + sk_ref_sp(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); diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index 5829fe44dda..7f6e735de53 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -11,14 +11,14 @@ #include "base/auto_reset.h" #include "base/location.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/animation/timing_function.h" #include "cc/debug/frame_rate_counter.h" #include "cc/input/scroll_elasticity_helper.h" #include "cc/layers/content_layer_client.h" -#include "cc/layers/io_surface_layer.h" #include "cc/layers/layer_impl.h" #include "cc/layers/painted_scrollbar_layer.h" #include "cc/layers/picture_layer.h" @@ -32,7 +32,6 @@ #include "cc/output/swap_promise.h" #include "cc/playback/display_item_list_settings.h" #include "cc/quads/draw_quad.h" -#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/test/fake_content_layer_client.h" @@ -53,7 +52,6 @@ #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "gpu/GLES2/gl2extchromium.h" -#include "skia/ext/refptr.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" @@ -430,10 +428,11 @@ SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawVisibility); class LayerTreeHostFreeWorkerContextResourcesTest : public LayerTreeHostTest { public: - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { - auto output_surface = make_scoped_ptr(new testing::StrictMock< - MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface>( - delegating_renderer())); + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + auto output_surface = base::WrapUnique( + new testing::StrictMock< + MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface>( + delegating_renderer())); // At init, we expect one call to set visibility to true. testing::Expectation visibility_true = @@ -649,6 +648,8 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { } void VerifyAfterValues(LayerImpl* layer) { + EffectTree& tree = layer->layer_tree_impl()->property_trees()->effect_tree; + EffectNode* node = tree.Node(layer->effect_tree_index()); switch (static_cast<Properties>(index_)) { case STARTUP: case DONE: @@ -657,7 +658,7 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString()); break; case HIDE_LAYER_AND_SUBTREE: - EXPECT_TRUE(layer->hide_layer_and_subtree()); + EXPECT_EQ(tree.EffectiveOpacity(node), 0.f); break; case DRAWS_CONTENT: EXPECT_TRUE(layer->DrawsContent()); @@ -687,16 +688,184 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo); +class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest { + protected: + void SetupTree() override { + root_ = Layer::Create(); + child_ = Layer::Create(); + root_->AddChild(child_); + layer_tree_host()->SetRootLayer(root_); + LayerTreeHostTest::SetupTree(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + switch (layer_tree_host()->source_frame_number()) { + case 1: + // child_ should create transform, effect, clip node. + child_->SetForceRenderSurfaceForTesting(true); + break; + case 2: + // child_ should create a scroll node. + child_->SetScrollClipLayerId(root_->id()); + break; + case 3: + // child_ should not create any property tree node. + child_->SetForceRenderSurfaceForTesting(false); + child_->SetScrollClipLayerId(Layer::INVALID_ID); + } + } + + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + PropertyTrees* property_trees = impl->sync_tree()->property_trees(); + auto root_transform_id_to_index = + property_trees->transform_id_to_index_map.find(root_->id()); + auto child_transform_id_to_index = + property_trees->transform_id_to_index_map.find(child_->id()); + auto root_effect_id_to_index = + property_trees->effect_id_to_index_map.find(root_->id()); + auto child_effect_id_to_index = + property_trees->effect_id_to_index_map.find(child_->id()); + auto root_clip_id_to_index = + property_trees->clip_id_to_index_map.find(root_->id()); + auto child_clip_id_to_index = + property_trees->clip_id_to_index_map.find(child_->id()); + auto root_scroll_id_to_index = + property_trees->scroll_id_to_index_map.find(root_->id()); + auto child_scroll_id_to_index = + property_trees->scroll_id_to_index_map.find(child_->id()); + switch (impl->sync_tree()->source_frame_number()) { + case 0: + // root_ should create every property tree node and child_ should not + // create any. + EXPECT_NE(root_transform_id_to_index, + property_trees->transform_id_to_index_map.end()); + EXPECT_EQ(root_transform_id_to_index->second, + root_->transform_tree_index()); + EXPECT_NE(root_effect_id_to_index, + property_trees->effect_id_to_index_map.end()); + EXPECT_EQ(root_effect_id_to_index->second, root_->effect_tree_index()); + EXPECT_NE(root_clip_id_to_index, + property_trees->clip_id_to_index_map.end()); + EXPECT_EQ(root_clip_id_to_index->second, root_->clip_tree_index()); + EXPECT_NE(root_scroll_id_to_index, + property_trees->scroll_id_to_index_map.end()); + EXPECT_EQ(root_scroll_id_to_index->second, root_->scroll_tree_index()); + EXPECT_EQ(child_transform_id_to_index, + property_trees->transform_id_to_index_map.end()); + EXPECT_EQ(child_effect_id_to_index, + property_trees->effect_id_to_index_map.end()); + EXPECT_EQ(child_clip_id_to_index, + property_trees->clip_id_to_index_map.end()); + EXPECT_EQ(child_scroll_id_to_index, + property_trees->scroll_id_to_index_map.end()); + break; + case 1: + // child_ should create a transfrom, clip, effect nodes but not a scroll + // node. + EXPECT_NE(property_trees->transform_id_to_index_map.find(child_->id()), + property_trees->transform_id_to_index_map.end()); + EXPECT_EQ(child_transform_id_to_index->second, + child_->transform_tree_index()); + EXPECT_NE(property_trees->effect_id_to_index_map.find(child_->id()), + property_trees->effect_id_to_index_map.end()); + EXPECT_EQ(child_effect_id_to_index->second, + child_->effect_tree_index()); + EXPECT_NE(property_trees->clip_id_to_index_map.find(child_->id()), + property_trees->clip_id_to_index_map.end()); + EXPECT_EQ(child_clip_id_to_index->second, child_->clip_tree_index()); + EXPECT_EQ(property_trees->scroll_id_to_index_map.find(child_->id()), + property_trees->scroll_id_to_index_map.end()); + break; + case 2: + // child_ should create a scroll node. + EXPECT_NE(property_trees->scroll_id_to_index_map.find(child_->id()), + property_trees->scroll_id_to_index_map.end()); + EXPECT_EQ(child_scroll_id_to_index->second, + child_->scroll_tree_index()); + break; + case 3: + // child_ should not create any property tree nodes. + EXPECT_EQ(property_trees->transform_id_to_index_map.find(child_->id()), + property_trees->transform_id_to_index_map.end()); + EXPECT_EQ(property_trees->effect_id_to_index_map.find(child_->id()), + property_trees->effect_id_to_index_map.end()); + EXPECT_EQ(property_trees->clip_id_to_index_map.find(child_->id()), + property_trees->clip_id_to_index_map.end()); + EXPECT_EQ(property_trees->scroll_id_to_index_map.find(child_->id()), + property_trees->scroll_id_to_index_map.end()); + + EndTest(); + break; + } + } + + void AfterTest() override {} + + private: + scoped_refptr<Layer> root_; + scoped_refptr<Layer> child_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushNodeOwnerToNodeIdMap); + +class LayerTreeHostTestDamageWithReplica : public LayerTreeHostTest { + protected: + void SetupTree() override { + scoped_refptr<Layer> root = Layer::Create(); + layer_tree_host()->SetRootLayer(root); + LayerTreeHostTest::SetupTree(); + } + + void BeginTest() override { + index_ = 0; + PostSetNeedsCommitToMainThread(); + } + + void DidCommit() override { + switch (layer_tree_host()->source_frame_number()) { + case 0: + break; + case 1: + scoped_refptr<Layer> replica_layer = Layer::Create(); + layer_tree_host()->root_layer()->SetReplicaLayer(replica_layer.get()); + break; + } + } + + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + switch (index_) { + case 0: + impl->sync_tree()->ResetAllChangeTracking(); + EXPECT_FALSE(impl->sync_tree()->root_layer()->LayerPropertyChanged()); + PostSetNeedsCommitToMainThread(); + index_++; + break; + case 1: + EXPECT_TRUE(impl->sync_tree()->root_layer()->LayerPropertyChanged()); + EndTest(); + break; + } + } + + void AfterTest() override {} + + int index_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDamageWithReplica); + // Verify damage status of property trees is preserved after commit. class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { protected: void SetupTree() override { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> child = Layer::Create(); + root_ = Layer::Create(); + child_ = Layer::Create(); // This is to force the child to create a transform and effect node. - child->SetForceRenderSurface(true); - root->AddChild(std::move(child)); - layer_tree_host()->SetRootLayer(root); + child_->SetForceRenderSurfaceForTesting(true); + root_->AddChild(child_); + layer_tree_host()->SetRootLayer(root_); LayerTreeHostTest::SetupTree(); } @@ -730,20 +899,21 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { switch (static_cast<Animations>(index_)) { case OPACITY: index_++; - impl->active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + impl->active_tree()->ResetAllChangeTracking(); impl->active_tree()->root_layer()->OnOpacityAnimated(0.5f); PostSetNeedsCommitToMainThread(); break; case TRANSFORM: index_++; - EXPECT_TRUE(impl->active_tree()->root_layer()->LayerPropertyChanged()); - impl->active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::EFFECT_TREE); - EXPECT_FALSE(impl->active_tree()->root_layer()->LayerPropertyChanged()); + EXPECT_TRUE(impl->active_tree() + ->LayerById(root_->id()) + ->LayerPropertyChanged()); + impl->active_tree()->ResetAllChangeTracking(); EXPECT_FALSE(impl->active_tree() - ->root_layer() - ->child_at(0) + ->LayerById(root_->id()) + ->LayerPropertyChanged()); + EXPECT_FALSE(impl->active_tree() + ->LayerById(child_->id()) ->LayerPropertyChanged()); transform.Translate(10, 10); impl->active_tree()->root_layer()->OnTransformAnimated(transform); @@ -753,15 +923,12 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { index_++; EXPECT_TRUE(impl->active_tree()->root_layer()->LayerPropertyChanged()); EXPECT_TRUE(impl->active_tree() - ->root_layer() - ->child_at(0) + ->LayerById(child_->id()) ->LayerPropertyChanged()); - impl->active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::TRANSFORM_TREE); + impl->active_tree()->ResetAllChangeTracking(); EXPECT_FALSE(impl->active_tree()->root_layer()->LayerPropertyChanged()); EXPECT_FALSE(impl->active_tree() - ->root_layer() - ->child_at(0) + ->LayerById(child_->id()) ->LayerPropertyChanged()); filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); impl->active_tree()->root_layer()->OnFilterAnimated(filters); @@ -775,11 +942,68 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { } void AfterTest() override {} + + private: int index_; + scoped_refptr<Layer> root_; + scoped_refptr<Layer> child_; }; SINGLE_THREAD_TEST_F(LayerTreeHostTestPropertyTreesChangedSync); +class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest { + protected: + void SetupTree() override { + root_ = Layer::Create(); + layer_tree_host()->SetRootLayer(root_); + LayerTreeHostTest::SetupTree(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + EffectTree& effect_tree = layer_tree_host()->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(root_->effect_tree_index()); + switch (layer_tree_host()->source_frame_number()) { + case 1: + node->data.opacity = 0.5f; + node->data.is_currently_animating_opacity = true; + break; + case 2: + node->data.is_currently_animating_opacity = false; + break; + } + } + + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + EffectTree& effect_tree = impl->sync_tree()->property_trees()->effect_tree; + EffectNode* node = + effect_tree.Node(impl->sync_tree()->root_layer()->effect_tree_index()); + switch (impl->sync_tree()->source_frame_number()) { + case 0: + impl->sync_tree()->root_layer()->OnOpacityAnimated(0.75f); + PostSetNeedsCommitToMainThread(); + break; + case 1: + EXPECT_EQ(node->data.opacity, 0.75f); + impl->sync_tree()->root_layer()->OnOpacityAnimated(0.75f); + PostSetNeedsCommitToMainThread(); + break; + case 2: + EXPECT_EQ(node->data.opacity, 0.5f); + EndTest(); + break; + } + } + + void AfterTest() override {} + + private: + scoped_refptr<Layer> root_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestEffectTreeSync); + // Verify damage status is updated even when the transform tree doesn't need // to be updated at draw time. class LayerTreeHostTestTransformTreeDamageIsUpdated : public LayerTreeHostTest { @@ -1430,7 +1654,7 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { case 3: // Test owning the surface. parent_layer_->SetOpacity(0.5f); - parent_layer_->SetForceRenderSurface(true); + parent_layer_->SetForceRenderSurfaceForTesting(true); break; case 4: EndTest(); @@ -1460,7 +1684,7 @@ class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest { void SetupTree() override { client_.set_fill_with_nonsolid_color(true); - scoped_ptr<FakeRecordingSource> recording(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); root_layer_ = FakePictureLayer::CreateWithRecordingSource( &client_, std::move(recording)); root_layer_->SetBounds(gfx::Size(50, 50)); @@ -1846,16 +2070,13 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers // Device scale factor should come over to impl. EXPECT_NEAR(impl->active_tree()->device_scale_factor(), 1.5f, 0.00001f); - // Both layers are on impl. - ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size()); - // Device viewport is scaled. EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize()); FakePictureLayerImpl* root = static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>( - impl->active_tree()->root_layer()->children()[0]); + impl->active_tree()->LayerById(child_layer_->id())); // Positions remain in layout pixels. EXPECT_EQ(gfx::PointF(), root->position()); @@ -2358,148 +2579,6 @@ class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation); -class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { - public: - MockIOSurfaceWebGraphicsContext3D() { - test_capabilities_.gpu.iosurface = true; - test_capabilities_.gpu.texture_rectangle = true; - } - - GLuint createTexture() override { return 1; } - MOCK_METHOD1(activeTexture, void(GLenum texture)); - MOCK_METHOD2(bindTexture, void(GLenum target, - GLuint texture_id)); - MOCK_METHOD3(texParameteri, void(GLenum target, - GLenum pname, - GLint param)); - MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target, - GLint width, - GLint height, - GLuint ioSurfaceId, - GLuint plane)); - MOCK_METHOD4(drawElements, void(GLenum mode, - GLsizei count, - GLenum type, - GLintptr offset)); - MOCK_METHOD1(deleteTexture, void(GLenum texture)); - MOCK_METHOD3(produceTextureDirectCHROMIUM, - void(GLuint texture, GLenum target, const GLbyte* mailbox)); -}; - -class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { - protected: - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { - scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned( - new MockIOSurfaceWebGraphicsContext3D); - mock_context_ = mock_context_owned.get(); - - if (delegating_renderer()) - return FakeOutputSurface::CreateDelegating3d( - std::move(mock_context_owned)); - else - return FakeOutputSurface::Create3d(std::move(mock_context_owned)); - } - - void SetupTree() override { - LayerTreeHostTest::SetupTree(); - - layer_tree_host()->root_layer()->SetIsDrawable(false); - - io_surface_id_ = 9; - io_surface_size_ = gfx::Size(6, 7); - - scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create(); - io_surface_layer->SetBounds(gfx::Size(10, 10)); - io_surface_layer->SetIsDrawable(true); - io_surface_layer->SetContentsOpaque(true); - io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); - layer_tree_host()->root_layer()->AddChild(io_surface_layer); - } - - void BeginTest() override { PostSetNeedsCommitToMainThread(); } - - void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_EQ(0u, host_impl->resource_provider()->num_resources()); - // In WillDraw, the IOSurfaceLayer sets up the io surface texture. - - EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0); - EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1)) - .Times(AtLeast(1)); - EXPECT_CALL(*mock_context_, - texParameteri( - GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)) - .Times(1); - EXPECT_CALL(*mock_context_, - texParameteri( - GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)) - .Times(1); - EXPECT_CALL(*mock_context_, - texParameteri(GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE)).Times(1); - EXPECT_CALL(*mock_context_, - texParameteri(GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE)).Times(1); - - EXPECT_CALL(*mock_context_, - texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, - io_surface_size_.width(), - io_surface_size_.height(), - io_surface_id_, - 0)).Times(1); - - EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber()); - } - - DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) override { - Mock::VerifyAndClearExpectations(&mock_context_); - ResourceProvider* resource_provider = host_impl->resource_provider(); - EXPECT_EQ(1u, resource_provider->num_resources()); - CHECK_EQ(1u, frame->render_passes.size()); - CHECK_LE(1u, frame->render_passes[0]->quad_list.size()); - const DrawQuad* quad = frame->render_passes[0]->quad_list.front(); - CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material); - 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_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), - resource_provider->GetResourceTextureTarget( - io_surface_draw_quad->io_surface_resource_id())); - - if (delegating_renderer()) { - // The io surface layer's resource should be sent to the parent. - EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM( - _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1); - } else { - // The io surface layer's texture is drawn. - EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1)); - EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _)) - .Times(AtLeast(1)); - } - - return draw_result; - } - - void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - Mock::VerifyAndClearExpectations(&mock_context_); - - EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1)); - EndTest(); - } - - void AfterTest() override {} - - int io_surface_id_; - MockIOSurfaceWebGraphicsContext3D* mock_context_; - gfx::Size io_surface_size_; -}; - -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing); - class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { public: void BeginTest() override { @@ -2561,7 +2640,7 @@ class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { parent_layer_ = FakePictureLayer::Create(&client_); parent_layer_->SetIsDrawable(true); parent_layer_->SetBounds(gfx::Size(50, 50)); - parent_layer_->SetForceRenderSurface(true); + parent_layer_->SetForceRenderSurfaceForTesting(true); child_layer_ = FakePictureLayer::Create(&client_); child_layer_->SetIsDrawable(true); @@ -2575,13 +2654,13 @@ class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { client_.set_bounds(root_layer_->bounds()); } - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { if (delegating_renderer()) { return FakeOutputSurface::CreateDelegatingSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); } else { return FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); } } @@ -2740,7 +2819,7 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest { FakeScopedUIResource::Create(layer_tree_host()); } - scoped_ptr<FakeScopedUIResource> ui_resources_[5]; + std::unique_ptr<FakeScopedUIResource> ui_resources_[5]; int num_ui_resources_; }; @@ -2748,9 +2827,10 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource); class PushPropertiesCountingLayerImpl : public LayerImpl { public: - static scoped_ptr<PushPropertiesCountingLayerImpl> Create( - LayerTreeImpl* tree_impl, int id) { - return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id)); + static std::unique_ptr<PushPropertiesCountingLayerImpl> Create( + LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new PushPropertiesCountingLayerImpl(tree_impl, id)); } ~PushPropertiesCountingLayerImpl() override {} @@ -2763,7 +2843,8 @@ class PushPropertiesCountingLayerImpl : public LayerImpl { layer)->push_properties_count_ = push_properties_count_; } - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { + std::unique_ptr<LayerImpl> CreateLayerImpl( + LayerTreeImpl* tree_impl) override { return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); } @@ -2797,7 +2878,8 @@ class PushPropertiesCountingLayer : public Layer { // Something to make this layer push properties, but no other layer. void MakePushProperties() { SetContentsOpaque(!contents_opaque()); } - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { + std::unique_ptr<LayerImpl> CreateLayerImpl( + LayerTreeImpl* tree_impl) override { return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); } @@ -3082,90 +3164,84 @@ class LayerTreeHostTestImplLayersPushProperties ++expected_push_properties_grandchild2_impl_; break; case 6: - // First child is removed. Structure of the tree changes here so swap - // some of the values. child_impl becomes child2_impl. - expected_push_properties_child_impl_ = - expected_push_properties_child2_impl_; - expected_push_properties_child2_impl_ = 0; - // grandchild_impl becomes grandchild2_impl. - expected_push_properties_grandchild_impl_ = - expected_push_properties_grandchild2_impl_; - expected_push_properties_grandchild2_impl_ = 0; + // First child is removed. Structure of the tree changes. + expected_push_properties_child_impl_ = 0; + expected_push_properties_grandchild_impl_ = 0; - // grandchild_impl is now the leaf that always pushes. It is pushed. - ++expected_push_properties_grandchild_impl_; + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild2_impl_; break; case 7: // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; // Child is added back. New layers are initialized. - ++expected_push_properties_grandchild2_impl_; - ++expected_push_properties_child2_impl_; + ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_child_impl_; break; case 8: // Leaf is removed. - expected_push_properties_grandchild2_impl_ = 0; + expected_push_properties_grandchild_impl_ = 0; // Always pushing. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; break; case 9: // Leaf is added back - ++expected_push_properties_grandchild2_impl_; + ++expected_push_properties_grandchild_impl_; // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; break; case 10: // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; break; case 11: // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; break; case 12: // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; // This child position was changed. So the subtree needs to push // properties. - ++expected_push_properties_child2_impl_; - ++expected_push_properties_grandchild2_impl_; + ++expected_push_properties_child_impl_; + ++expected_push_properties_grandchild_impl_; break; case 13: // The position of this child was changed. - ++expected_push_properties_child_impl_; + ++expected_push_properties_child2_impl_; // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; break; case 14: // Second child is removed from tree. Don't discard counts because // they are added back before commit. // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; // Second child added back. - ++expected_push_properties_child2_impl_; - ++expected_push_properties_grandchild2_impl_; + ++expected_push_properties_child_impl_; + ++expected_push_properties_grandchild_impl_; break; case 15: // The position of this child was changed. - ++expected_push_properties_grandchild2_impl_; + ++expected_push_properties_grandchild_impl_; // The leaf that always pushes is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; break; case 16: // Second child is invalidated with SetNeedsDisplay - ++expected_push_properties_child2_impl_; + ++expected_push_properties_child_impl_; // The leaf that always pushed is pushed. - ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_grandchild2_impl_; break; } @@ -3180,23 +3256,24 @@ class LayerTreeHostTestImplLayersPushProperties root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( host_impl->RootLayer()); - if (root_impl_ && root_impl_->children().size() > 0) { + LayerTreeImpl* impl = root_impl_->layer_tree_impl(); + if (impl->LayerById(child_->id())) { child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( - root_impl_->children()[0]); + impl->LayerById(child_->id())); - if (child_impl_ && child_impl_->children().size() > 0) + if (impl->LayerById(grandchild_->id())) grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( - child_impl_->children()[0]); + impl->LayerById(grandchild_->id())); } - if (root_impl_ && root_impl_->children().size() > 1) { + if (impl->LayerById(child2_->id())) { child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( - root_impl_->children()[1]); + impl->LayerById(child2_->id())); - if (child2_impl_ && child2_impl_->children().size() > 0) + if (impl->LayerById(leaf_always_pushing_layer_->id())) leaf_always_pushing_layer_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( - child2_impl_->children()[0]); + impl->LayerById(leaf_always_pushing_layer_->id())); } if (root_impl_) @@ -3255,7 +3332,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed // avoid causing a second commit to be scheduled. If a property change // is made during this, however, it needs to be pushed in the upcoming // commit. - scoped_ptr<base::AutoReset<bool>> ignore = + std::unique_ptr<base::AutoReset<bool>> ignore = scrollbar_layer_->IgnoreSetNeedsCommit(); scrollbar_layer_->SetBounds(gfx::Size(30, 30)); @@ -3865,27 +3942,6 @@ class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate); -// IOSurfaceLayer must support being invalidated and then passing that along -// to the compositor thread, even though no resources are updated in -// response to that invalidation. -class LayerTreeHostTestIOSurfaceLayerInvalidate - : public LayerInvalidateCausesDraw { - public: - void SetupTree() override { - LayerTreeHostTest::SetupTree(); - scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create(); - layer->SetBounds(gfx::Size(10, 10)); - uint32_t fake_io_surface_id = 7; - layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds()); - layer->SetIsDrawable(true); - layer_tree_host()->root_layer()->AddChild(layer); - - invalidate_layer_ = layer; - } -}; - -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceLayerInvalidate); - class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { protected: void SetupTree() override { @@ -3934,9 +3990,7 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* parent = root->children()[0]; - LayerImpl* child = parent->children()[0]; + LayerImpl* child = impl->active_tree()->LayerById(child_layer_->id()); switch (impl->active_tree()->source_frame_number()) { case 1: @@ -4015,6 +4069,7 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { page_scale_layer->AddChild(inner_viewport_scroll_layer); scoped_refptr<Layer> content_layer = FakePictureLayer::Create(&client_); + content_layer_id_ = content_layer->id(); content_layer->SetBounds(gfx::Size(10, 10)); inner_viewport_scroll_layer->AddChild(content_layer); @@ -4037,7 +4092,7 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { num_draws_++; LayerImpl* content_layer_impl = - host_impl->active_tree()->InnerViewportScrollLayer()->children()[0]; + host_impl->active_tree()->LayerById(content_layer_id_); gfx::Transform expected_draw_transform; switch (num_draws_) { case 1: @@ -4075,6 +4130,7 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { FakeContentLayerClient client_; scoped_refptr<Layer> root_layer_; ScrollElasticityHelper* scroll_elasticity_helper_; + int content_layer_id_; int num_draws_; }; @@ -4087,7 +4143,7 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface : first_output_surface_memory_limit_(4321234), second_output_surface_memory_limit_(1234321) {} - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { if (!first_context_provider_.get()) { first_context_provider_ = TestContextProvider::Create(); } else { @@ -4098,13 +4154,13 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface scoped_refptr<TestContextProvider> provider(second_context_provider_.get() ? second_context_provider_ : first_context_provider_); - scoped_ptr<FakeOutputSurface> output_surface; + std::unique_ptr<FakeOutputSurface> output_surface; if (delegating_renderer()) output_surface = FakeOutputSurface::CreateDelegating3d(provider); else output_surface = FakeOutputSurface::Create3d(provider); output_surface->SetMemoryPolicyToSetAtBind( - make_scoped_ptr(new ManagedMemoryPolicy( + base::WrapUnique(new ManagedMemoryPolicy( second_context_provider_.get() ? second_output_surface_memory_limit_ : first_output_surface_memory_limit_, gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, @@ -4229,12 +4285,12 @@ class PinnedLayerTreeSwapPromise : public LayerTreeHostTest { void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { int frame = host_impl->active_tree()->source_frame_number(); if (frame == -1) { - host_impl->active_tree()->QueuePinnedSwapPromise(make_scoped_ptr( + host_impl->active_tree()->QueuePinnedSwapPromise(base::WrapUnique( new TestSwapPromise(&pinned_active_swap_promise_result_))); host_impl->pending_tree()->QueueSwapPromise( - make_scoped_ptr(new TestSwapPromise(&pending_swap_promise_result_))); + base::WrapUnique(new TestSwapPromise(&pending_swap_promise_result_))); host_impl->active_tree()->QueueSwapPromise( - make_scoped_ptr(new TestSwapPromise(&active_swap_promise_result_))); + base::WrapUnique(new TestSwapPromise(&active_swap_promise_result_))); } } @@ -4273,7 +4329,7 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { void WillBeginMainFrame() override { ASSERT_LE(commit_count_, 2); - scoped_ptr<SwapPromise> swap_promise( + std::unique_ptr<SwapPromise> swap_promise( new TestSwapPromise(&swap_promise_result_[commit_count_])); layer_tree_host()->QueueSwapPromise(std::move(swap_promise)); } @@ -4387,7 +4443,7 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest { case 1: layer_->SetBounds(gfx::Size(10, 11)); layer_tree_host()->QueueSwapPromise( - make_scoped_ptr(new TestSwapPromise(&swap_promise_result_))); + base::WrapUnique(new TestSwapPromise(&swap_promise_result_))); break; case 2: break; @@ -4460,7 +4516,7 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility void SetVisibleFalseAndQueueSwapPromise() { layer_tree_host()->SetVisible(false); - scoped_ptr<SwapPromise> swap_promise( + std::unique_ptr<SwapPromise> swap_promise( new TestSwapPromise(&swap_promise_result_)); layer_tree_host()->QueueSwapPromise(std::move(swap_promise)); } @@ -4504,7 +4560,7 @@ class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest { void LoseOutputSurfaceAndQueueSwapPromise() { layer_tree_host()->DidLoseOutputSurface(); - scoped_ptr<SwapPromise> swap_promise( + std::unique_ptr<SwapPromise> swap_promise( new TestSwapPromise(&swap_promise_result_)); layer_tree_host()->QueueSwapPromise(std::move(swap_promise)); } @@ -4583,9 +4639,8 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { int set_needs_redraw_count = 0; { - scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor(layer_tree_host(), - NULL, + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor(layer_tree_host(), NULL, &set_needs_commit_count, &set_needs_redraw_count)); layer_tree_host()->SetNeedsCommit(); @@ -4600,9 +4655,8 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { EXPECT_EQ(0, set_needs_redraw_count); { - scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor(layer_tree_host(), - NULL, + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor(layer_tree_host(), NULL, &set_needs_commit_count, &set_needs_redraw_count)); layer_tree_host()->SetNeedsUpdateLayers(); @@ -4611,9 +4665,8 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { } { - scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor(layer_tree_host(), - NULL, + std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor(layer_tree_host(), NULL, &set_needs_commit_count, &set_needs_redraw_count)); layer_tree_host()->SetNeedsAnimate(); @@ -4665,7 +4718,7 @@ class LayerTreeHostTestHighResRequiredAfterEvictingUIResources void AfterTest() override {} FakeContentLayerClient client_; - scoped_ptr<FakeScopedUIResource> ui_resource_; + std::unique_ptr<FakeScopedUIResource> ui_resource_; }; // This test is flaky, see http://crbug.com/386199 @@ -4681,7 +4734,8 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { void SetupTree() override { LayerTreeHostTest::SetupTree(); - scoped_ptr<FakeRecordingSource> recording_source(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording_source( + new FakeRecordingSource); recording_source_ = recording_source.get(); scoped_refptr<FakePictureLayer> layer = @@ -4736,7 +4790,8 @@ class LayerTreeHostTestEmptyLayerGpuRasterization : public LayerTreeHostTest { void SetupTree() override { LayerTreeHostTest::SetupTree(); - scoped_ptr<FakeRecordingSource> recording_source(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording_source( + new FakeRecordingSource); recording_source_ = recording_source.get(); scoped_refptr<FakePictureLayer> layer = @@ -4793,7 +4848,8 @@ class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { void SetupTree() override { LayerTreeHostTest::SetupTree(); - scoped_ptr<FakeRecordingSource> recording_source(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording_source( + new FakeRecordingSource); recording_source_ = recording_source.get(); scoped_refptr<FakePictureLayer> layer = @@ -4862,7 +4918,8 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { void SetupTree() override { LayerTreeHostTest::SetupTree(); - scoped_ptr<FakeRecordingSource> recording_source(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording_source( + new FakeRecordingSource); recording_source_ = recording_source.get(); scoped_refptr<FakePictureLayer> layer = @@ -5043,77 +5100,6 @@ class LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime // LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime); SINGLE_THREAD_TEST_F(LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime); -class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest { - public: - LayerTreeHostTestSendBeginFramesToChildren() - : begin_frame_sent_to_children_(false) { - } - - void BeginTest() override { - // Kick off the test with a commit. - PostSetNeedsCommitToMainThread(); - } - - void SendBeginFramesToChildren(const BeginFrameArgs& args) override { - begin_frame_sent_to_children_ = true; - EndTest(); - } - - void DidBeginMainFrame() override { - // Children requested BeginFrames. - layer_tree_host()->SetChildrenNeedBeginFrames(true); - } - - void AfterTest() override { - // Ensure that BeginFrame message is sent to children during parent - // scheduler handles its BeginFrame. - EXPECT_TRUE(begin_frame_sent_to_children_); - } - - private: - bool begin_frame_sent_to_children_; -}; - -SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren); - -class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS - : public LayerTreeHostTest { - public: - LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS() - : begin_frame_sent_to_children_(false) { - } - - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_external_begin_frame_source = true; - } - - void BeginTest() override { - // Kick off the test with a commit. - PostSetNeedsCommitToMainThread(); - } - - void SendBeginFramesToChildren(const BeginFrameArgs& args) override { - begin_frame_sent_to_children_ = true; - EndTest(); - } - - void DidBeginMainFrame() override { - // Children requested BeginFrames. - layer_tree_host()->SetChildrenNeedBeginFrames(true); - } - - void AfterTest() override { - // Ensure that BeginFrame message is sent to children during parent - // scheduler handles its BeginFrame. - EXPECT_TRUE(begin_frame_sent_to_children_); - } - - private: - bool begin_frame_sent_to_children_; -}; - -SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS); - class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest { public: LayerTreeHostTestActivateOnInvisible() @@ -5177,20 +5163,20 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise void BeginTest() override { // Successful composite. - scoped_ptr<SwapPromise> swap_promise0( + std::unique_ptr<SwapPromise> swap_promise0( new TestSwapPromise(&swap_promise_result_[0])); layer_tree_host()->QueueSwapPromise(std::move(swap_promise0)); layer_tree_host()->Composite(base::TimeTicks::Now()); // Fail to swap (no damage). - scoped_ptr<SwapPromise> swap_promise1( + std::unique_ptr<SwapPromise> swap_promise1( new TestSwapPromise(&swap_promise_result_[1])); layer_tree_host()->QueueSwapPromise(std::move(swap_promise1)); layer_tree_host()->SetNeedsCommit(); layer_tree_host()->Composite(base::TimeTicks::Now()); // Fail to draw (not visible). - scoped_ptr<SwapPromise> swap_promise2( + std::unique_ptr<SwapPromise> swap_promise2( new TestSwapPromise(&swap_promise_result_[2])); layer_tree_host()->QueueSwapPromise(std::move(swap_promise2)); layer_tree_host()->SetNeedsDisplayOnAllLayers(); @@ -5308,7 +5294,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); - scoped_ptr<FakeRecordingSource> recording(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); recording->SetPlaybackAllowedEvent(&playback_allowed_event_); scoped_refptr<FakePictureLayer> layer = FakePictureLayer::CreateWithRecordingSource(&client_, @@ -5478,8 +5464,8 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds); class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy : public LayerTreeHostTestCrispUpAfterPinchEnds { protected: - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { - scoped_ptr<TestWebGraphicsContext3D> context3d = + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<TestWebGraphicsContext3D> context3d = TestWebGraphicsContext3D::Create(); context3d->set_support_image(true); context3d->set_support_sync_query(true); @@ -5513,7 +5499,7 @@ class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest { root->SetBounds(gfx::Size(500, 500)); client_.set_bounds(root->bounds()); - scoped_ptr<FakeRecordingSource> recording(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); scoped_refptr<FakePictureLayer> layer = FakePictureLayer::CreateWithRecordingSource(&client_, std::move(recording)); @@ -5554,7 +5540,7 @@ class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest { void SetupTree() override { client_.set_fill_with_nonsolid_color(true); - scoped_ptr<FakeRecordingSource> recording(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); scoped_refptr<FakePictureLayer> root = FakePictureLayer::CreateWithRecordingSource(&client_, std::move(recording)); @@ -5610,7 +5596,7 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); - scoped_ptr<FakeRecordingSource> recording(new FakeRecordingSource); + std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); recording->SetPlaybackAllowedEvent(&playback_allowed_event_); scoped_refptr<FakePictureLayer> layer = FakePictureLayer::CreateWithRecordingSource(&client_, @@ -5822,94 +5808,6 @@ class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles); -class LayerTreeHostTestFrameTimingRequestsSaveTimestamps - : public LayerTreeHostTest { - public: - LayerTreeHostTestFrameTimingRequestsSaveTimestamps() - : check_results_on_commit_(false) {} - - void SetupTree() override { - scoped_refptr<FakePictureLayer> root_layer = - FakePictureLayer::Create(&client_); - root_layer->SetBounds(gfx::Size(200, 200)); - root_layer->SetIsDrawable(true); - - scoped_refptr<FakePictureLayer> child_layer = - FakePictureLayer::Create(&client_); - child_layer->SetBounds(gfx::Size(1500, 1500)); - child_layer->SetIsDrawable(true); - - std::vector<FrameTimingRequest> requests; - requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100))); - requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100))); - child_layer->SetFrameTimingRequests(requests); - - root_layer->AddChild(child_layer); - layer_tree_host()->SetRootLayer(root_layer); - LayerTreeHostTest::SetupTree(); - client_.set_bounds(root_layer->bounds()); - } - - void BeginTest() override { PostSetNeedsCommitToMainThread(); } - - void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { - if (!check_results_on_commit_) - return; - - // Since in reality, the events will be read by LayerTreeHost during commit, - // we check the requests here to ensure that they are correct at the next - // commit time (as opposed to checking in DrawLayers for instance). - // TODO(vmpstr): Change this to read things from the main thread when this - // information is propagated to the main thread (not yet implemented). - FrameTimingTracker* tracker = host_impl->frame_timing_tracker(); - - // Check composite events. - { - scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set = - tracker->GroupCompositeCountsByRectId(); - EXPECT_EQ(1u, timing_set->size()); - auto rect_1_it = timing_set->find(1); - EXPECT_TRUE(rect_1_it != timing_set->end()); - const auto& timing_events = rect_1_it->second; - EXPECT_EQ(1u, timing_events.size()); - EXPECT_EQ(host_impl->active_tree()->source_frame_number(), - timing_events[0].frame_id); - EXPECT_GT(timing_events[0].timestamp, base::TimeTicks()); - } - - // Check main frame events. - { - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> timing_set = - tracker->GroupMainFrameCountsByRectId(); - EXPECT_EQ(2u, timing_set->size()); - auto rect_1_it = timing_set->find(1); - EXPECT_TRUE(rect_1_it != timing_set->end()); - const auto& timing_events = rect_1_it->second; - EXPECT_EQ(1u, timing_events.size()); - EXPECT_EQ(host_impl->active_tree()->source_frame_number(), - timing_events[0].frame_id); - EXPECT_GT(timing_events[0].timestamp, base::TimeTicks()); - EXPECT_GT(timing_events[0].end_time, timing_events[0].timestamp); - } - - EndTest(); - } - - void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - check_results_on_commit_ = true; - PostSetNeedsCommitToMainThread(); - } - - void AfterTest() override {} - - private: - FakeContentLayerClient client_; - bool check_results_on_commit_; -}; - -// Frame timing is not implemented in single thread proxy. -MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps); - class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest { public: LayerTreeHostTestActivationCausesPrepareTiles() @@ -6004,7 +5902,7 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} + static void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -6577,16 +6475,14 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { LayerTreeHostCommon::CallFunctionForEveryLayer( - host_impl->sync_tree(), - [this](LayerImpl* layer) { + host_impl->sync_tree(), [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()); - }, - CallFunctionLayerType::ALL_LAYERS); + }); EndTest(); } diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index b8a63e3522e..16efbec7040 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -10,10 +10,8 @@ #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/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/animation/transform_operations.h" @@ -40,7 +38,7 @@ class LayerTreeHostAnimationTest : public LayerTreeTest { player_ = AnimationPlayer::Create(player_id_); player_child_ = AnimationPlayer::Create(player_child_id_); - player_->set_layer_animation_delegate(this); + player_->set_animation_delegate(this); } void AttachPlayersToTimeline() { @@ -146,7 +144,7 @@ class LayerTreeHostAnimationTestAddAnimation void BeginTest() override { AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); PostAddInstantAnimationToMainThreadPlayer(player_.get()); } @@ -161,9 +159,8 @@ class LayerTreeHostAnimationTestAddAnimation int group) override { EXPECT_LT(base::TimeTicks(), monotonic_time); - LayerAnimationController* controller = - player_->element_animations()->layer_animation_controller(); - Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); + Animation* animation = + player_->element_animations()->GetAnimation(TargetProperty::OPACITY); if (animation) player_->RemoveAnimation(animation->id()); @@ -188,7 +185,7 @@ class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws void BeginTest() override { AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); PostAddAnimationToMainThreadPlayer(player_.get()); } @@ -226,15 +223,14 @@ class LayerTreeHostAnimationTestAnimationsGetDeleted void BeginTest() override { AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); + player_->AttachElement(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() + ->active_element_animations_for_testing() .empty(); if (!started_animating_ && have_animations) { started_animating_ = true; @@ -248,8 +244,8 @@ class LayerTreeHostAnimationTestAnimationsGetDeleted void NotifyAnimationFinished(base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) override { - // Animations on the impl-side controller only get deleted during a commit, - // so we need to schedule a commit. + // Animations on the impl-side ElementAnimations only get deleted during + // a commit, so we need to schedule a commit. layer_tree_host()->SetNeedsCommit(); } @@ -273,7 +269,7 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction layer_tree_host()->root_layer()->AddChild(picture_); AttachPlayersToTimeline(); - player_child_->AttachLayer(picture_->id()); + player_child_->AttachElement(picture_->id()); } void BeginTest() override { @@ -296,10 +292,9 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction scoped_refptr<AnimationPlayer> player_child_impl = timeline_impl->GetPlayerById(player_child_id_); - LayerAnimationController* controller_impl = - player_child_impl->element_animations()->layer_animation_controller(); Animation* animation = - controller_impl->GetAnimation(TargetProperty::OPACITY); + player_child_impl->element_animations()->GetAnimation( + TargetProperty::OPACITY); const FloatAnimationCurve* curve = animation->curve()->ToFloatAnimationCurve(); @@ -339,8 +334,8 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes layer_tree_host()->root_layer()->AddChild(picture_); AttachPlayersToTimeline(); - player_child_->set_layer_animation_delegate(this); - player_child_->AttachLayer(picture_->id()); + player_child_->set_animation_delegate(this); + player_child_->AttachElement(picture_->id()); } void BeginTest() override { @@ -350,11 +345,10 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes void NotifyAnimationStarted(base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) override { - LayerAnimationController* controller = - player_child_->element_animations()->layer_animation_controller(); - Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); + Animation* animation = player_child_->element_animations()->GetAnimation( + TargetProperty::OPACITY); main_start_time_ = animation->start_time(); - controller->RemoveAnimation(animation->id()); + player_child_->element_animations()->RemoveAnimation(animation->id()); EndTest(); } @@ -365,9 +359,9 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes 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(TargetProperty::OPACITY); + Animation* animation = + player_child_impl->element_animations()->GetAnimation( + TargetProperty::OPACITY); if (!animation) return; @@ -395,18 +389,17 @@ class LayerTreeHostAnimationTestAnimationFinishedEvents public: void BeginTest() override { AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); PostAddInstantAnimationToMainThreadPlayer(player_.get()); } void NotifyAnimationFinished(base::TimeTicks monotonic_time, TargetProperty::Type target_property, int group) override { - LayerAnimationController* controller = - player_->element_animations()->layer_animation_controller(); - Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); + Animation* animation = + player_->element_animations()->GetAnimation(TargetProperty::OPACITY); if (animation) - controller->RemoveAnimation(animation->id()); + player_->element_animations()->RemoveAnimation(animation->id()); EndTest(); } @@ -432,7 +425,7 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity LayerTreeHostAnimationTest::SetupTree(); AttachPlayersToTimeline(); - player_->AttachLayer(update_check_layer_->id()); + player_->AttachElement(update_check_layer_->id()); } void BeginTest() override { @@ -445,11 +438,9 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity 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(TargetProperty::OPACITY); - controller_impl->RemoveAnimation(animation_impl->id()); + Animation* animation_impl = player_impl->element_animations()->GetAnimation( + TargetProperty::OPACITY); + player_impl->element_animations()->RemoveAnimation(animation_impl->id()); EndTest(); } @@ -482,12 +473,12 @@ class LayerTreeHostAnimationTestLayerAddedWithAnimation AttachPlayersToTimeline(); scoped_refptr<Layer> layer = Layer::Create(); - player_->AttachLayer(layer->id()); - player_->set_layer_animation_delegate(this); + player_->AttachElement(layer->id()); + player_->set_animation_delegate(this); // Any valid AnimationCurve will do here. - scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); - scoped_ptr<Animation> animation( + std::unique_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); + std::unique_ptr<Animation> animation( Animation::Create(std::move(curve), 1, 1, TargetProperty::OPACITY)); player_->AddAnimation(std::move(animation)); @@ -633,8 +624,8 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations layer_tree_host()->root_layer()->AddChild(picture_); AttachPlayersToTimeline(); - player_child_->AttachLayer(picture_->id()); - player_child_->set_layer_animation_delegate(this); + player_child_->AttachElement(picture_->id()); + player_child_->set_animation_delegate(this); } void InitializeSettings(LayerTreeSettings* settings) override { @@ -722,7 +713,7 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated layer_tree_host()->root_layer()->AddChild(scroll_layer_); AttachPlayersToTimeline(); - player_child_->AttachLayer(scroll_layer_->id()); + player_child_->AttachElement(scroll_layer_->id()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -730,11 +721,11 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: { - scoped_ptr<ScrollOffsetAnimationCurve> curve( + std::unique_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create( gfx::ScrollOffset(500.f, 550.f), EaseInOutTimingFunction::Create())); - scoped_ptr<Animation> animation(Animation::Create( + std::unique_ptr<Animation> animation(Animation::Create( std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); animation->set_needs_synchronized_start_time(true); bool impl_scrolling_supported = @@ -762,6 +753,63 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); +// Verifies that when a main thread scrolling reason gets added, the +// notification to takover the animation on the main thread gets sent. +class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover + : public LayerTreeHostAnimationTest { + public: + LayerTreeHostAnimationTestScrollOffsetAnimationTakeover() {} + + void SetupTree() override { + LayerTreeHostAnimationTest::SetupTree(); + + scroll_layer_ = FakePictureLayer::Create(&client_); + scroll_layer_->SetBounds(gfx::Size(10000, 10000)); + client_.set_bounds(scroll_layer_->bounds()); + scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); + layer_tree_host()->root_layer()->AddChild(scroll_layer_); + + AttachPlayersToTimeline(); + player_child_->AttachElement(scroll_layer_->id()); + // Allows NotifyAnimationTakeover to get called. + player_child_->set_animation_delegate(this); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + // Add a main thread scrolling reason after the first commit to trigger + // the takeover path. + if (layer_tree_host()->source_frame_number() == 1) { + scroll_layer_->AddMainThreadScrollingReasons( + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + } + } + + void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + if (host_impl->sync_tree()->source_frame_number() == 0) { + host_impl->animation_host()->ImplOnlyScrollAnimationCreate( + scroll_layer_->id(), gfx::ScrollOffset(650.f, 750.f), + gfx::ScrollOffset(10, 20)); + } + } + + void NotifyAnimationTakeover(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + double animation_start_time, + std::unique_ptr<AnimationCurve> curve) override { + EndTest(); + } + + void AfterTest() override {} + + private: + FakeContentLayerClient client_; + scoped_refptr<FakePictureLayer> scroll_layer_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationTakeover); + // 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 @@ -782,15 +830,15 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); layer_tree_host()->root_layer()->AddChild(scroll_layer_); - scoped_ptr<ScrollOffsetAnimationCurve> curve( + std::unique_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f), EaseInOutTimingFunction::Create())); - scoped_ptr<Animation> animation(Animation::Create( + std::unique_ptr<Animation> animation(Animation::Create( std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); animation->set_needs_synchronized_start_time(true); AttachPlayersToTimeline(); - player_child_->AttachLayer(scroll_layer_->id()); + player_child_->AttachElement(scroll_layer_->id()); player_child_->AddAnimation(std::move(animation)); } @@ -803,7 +851,6 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval case 1: { Animation* animation = player_child_->element_animations() - ->layer_animation_controller() ->GetAnimation(TargetProperty::SCROLL_OFFSET); player_child_->RemoveAnimation(animation->id()); scroll_layer_->SetScrollOffset(final_postion_); @@ -815,49 +862,21 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval } void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { - host_impl->BlockNotifyReadyToActivateForTesting(true); + host_impl->BlockNotifyReadyToActivateForTesting( + ShouldBlockActivation(host_impl)); } 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(TargetProperty::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 = ScrollDelta(scroll_layer_impl); - if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f) - return; - - host_impl->BlockNotifyReadyToActivateForTesting(false); + host_impl->BlockNotifyReadyToActivateForTesting( + ShouldBlockActivation(host_impl)); } 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]; + host_impl->pending_tree()->LayerById(scroll_layer_->id()); EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); } @@ -865,7 +884,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval if (host_impl->active_tree()->source_frame_number() != 1) return; LayerImpl* scroll_layer_impl = - host_impl->active_tree()->root_layer()->children()[0]; + host_impl->active_tree()->LayerById(scroll_layer_->id()); EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); EndTest(); } @@ -875,6 +894,35 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval } private: + bool ShouldBlockActivation(LayerTreeHostImpl* host_impl) { + if (!host_impl->pending_tree()) + return false; + + if (!host_impl->active_tree()->root_layer()) + return false; + + 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()->LayerById(scroll_layer_->id()); + Animation* animation = player_impl->element_animations()->GetAnimation( + TargetProperty::SCROLL_OFFSET); + + if (!animation || animation->run_state() != Animation::RUNNING) + return false; + + // Block activation until the running animation has a chance to produce a + // scroll delta. + gfx::Vector2dF scroll_delta = ScrollDelta(scroll_layer_impl); + if (scroll_delta.x() > 0.f || scroll_delta.y() > 0.f) + return false; + + return true; + } + FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> scroll_layer_; const gfx::ScrollOffset final_postion_; @@ -898,7 +946,7 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers void DidCommit() override { if (layer_tree_host()->source_frame_number() == 1) { - player_->AttachLayer(layer_tree_host()->root_layer()->id()); + player_->AttachElement(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); @@ -907,8 +955,8 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers 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); + player_child_->AttachElement(layer->id()); + player_child_->set_animation_delegate(this); AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true); } } @@ -952,22 +1000,21 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers if (!player_impl->element_animations()) return; - LayerAnimationController* root_controller_impl = - player_impl->element_animations()->layer_animation_controller(); - Animation* root_animation = - root_controller_impl->GetAnimation(TargetProperty::OPACITY); + Animation* root_animation = player_impl->element_animations()->GetAnimation( + TargetProperty::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(TargetProperty::OPACITY); + player_child_impl->element_animations()->GetAnimation( + TargetProperty::OPACITY); EXPECT_EQ(Animation::RUNNING, child_animation->run_state()); EXPECT_EQ(root_animation->start_time(), child_animation->start_time()); - root_controller_impl->AbortAnimations(TargetProperty::OPACITY); - root_controller_impl->AbortAnimations(TargetProperty::TRANSFORM); - child_controller_impl->AbortAnimations(TargetProperty::OPACITY); + player_impl->element_animations()->AbortAnimations(TargetProperty::OPACITY); + player_impl->element_animations()->AbortAnimations( + TargetProperty::TRANSFORM); + player_child_impl->element_animations()->AbortAnimations( + TargetProperty::OPACITY); EndTest(); } @@ -996,7 +1043,7 @@ class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit layer_->SetTransform(start_transform); layer_tree_host()->root_layer()->AddChild(layer_); - player_->AttachLayer(layer_->id()); + player_->AttachElement(layer_->id()); AttachPlayersToTimeline(); } @@ -1026,13 +1073,9 @@ class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit scoped_refptr<AnimationPlayer> player_impl = timeline_impl->GetPlayerById(player_id_); - LayerAnimationController* controller_impl = - player_impl->element_animations()->layer_animation_controller(); - - LayerImpl* root = host_impl->sync_tree()->root_layer(); - LayerImpl* child = root->children()[0]; - Animation* animation = - controller_impl->GetAnimation(TargetProperty::TRANSFORM); + LayerImpl* child = host_impl->sync_tree()->LayerById(layer_->id()); + Animation* animation = player_impl->element_animations()->GetAnimation( + TargetProperty::TRANSFORM); // The animation should be starting for the first frame. EXPECT_EQ(Animation::STARTING, animation->run_state()); @@ -1045,7 +1088,8 @@ class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit // And the sync tree layer should know it is animating. EXPECT_TRUE(child->screen_space_transform_is_animating()); - controller_impl->AbortAnimations(TargetProperty::TRANSFORM); + player_impl->element_animations()->AbortAnimations( + TargetProperty::TRANSFORM); EndTest(); } @@ -1071,7 +1115,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get()); timeline_->AttachPlayer(player_.get()); - player_->AttachLayer(layer_->id()); + player_->AttachElement(layer_->id()); DCHECK(player_->element_animations()); AddOpacityTransitionToPlayer(player_.get(), 10000.0, 0.1f, 0.9f, true); @@ -1082,36 +1126,27 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 0: - EXPECT_TRUE(player_->element_animations() - ->has_active_value_observer_for_testing()); - EXPECT_FALSE(player_->element_animations() - ->has_pending_value_observer_for_testing()); - EXPECT_TRUE(layer_tree_host() - ->animation_host() - ->animation_registrar() - ->needs_animate_layers()); + EXPECT_TRUE( + player_->element_animations()->has_element_in_active_list()); + EXPECT_FALSE( + player_->element_animations()->has_element_in_pending_list()); + EXPECT_TRUE(layer_tree_host()->animation_host()->NeedsAnimateLayers()); break; case 1: layer_->RemoveFromParent(); - EXPECT_FALSE(player_->element_animations() - ->has_active_value_observer_for_testing()); - EXPECT_FALSE(player_->element_animations() - ->has_pending_value_observer_for_testing()); - EXPECT_TRUE(layer_tree_host() - ->animation_host() - ->animation_registrar() - ->needs_animate_layers()); + EXPECT_FALSE( + player_->element_animations()->has_element_in_active_list()); + EXPECT_FALSE( + player_->element_animations()->has_element_in_pending_list()); + EXPECT_TRUE(layer_tree_host()->animation_host()->NeedsAnimateLayers()); break; case 2: layer_tree_host()->root_layer()->AddChild(layer_); - EXPECT_TRUE(player_->element_animations() - ->has_active_value_observer_for_testing()); - EXPECT_FALSE(player_->element_animations() - ->has_pending_value_observer_for_testing()); - EXPECT_TRUE(layer_tree_host() - ->animation_host() - ->animation_registrar() - ->needs_animate_layers()); + EXPECT_TRUE( + player_->element_animations()->has_element_in_active_list()); + EXPECT_FALSE( + player_->element_animations()->has_element_in_pending_list()); + EXPECT_TRUE(layer_tree_host()->animation_host()->NeedsAnimateLayers()); break; } } @@ -1124,25 +1159,19 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded switch (host_impl->active_tree()->source_frame_number()) { case 0: - EXPECT_TRUE(player_impl->element_animations() - ->has_active_value_observer_for_testing()); - EXPECT_TRUE(host_impl->animation_host() - ->animation_registrar() - ->needs_animate_layers()); + EXPECT_TRUE( + player_impl->element_animations()->has_element_in_active_list()); + EXPECT_TRUE(host_impl->animation_host()->NeedsAnimateLayers()); break; case 1: - EXPECT_FALSE(player_impl->element_animations() - ->has_active_value_observer_for_testing()); - EXPECT_TRUE(host_impl->animation_host() - ->animation_registrar() - ->needs_animate_layers()); + EXPECT_FALSE( + player_impl->element_animations()->has_element_in_active_list()); + EXPECT_TRUE(host_impl->animation_host()->NeedsAnimateLayers()); break; case 2: - EXPECT_TRUE(player_impl->element_animations() - ->has_active_value_observer_for_testing()); - EXPECT_TRUE(host_impl->animation_host() - ->animation_registrar() - ->needs_animate_layers()); + EXPECT_TRUE( + player_impl->element_animations()->has_element_in_active_list()); + EXPECT_TRUE(host_impl->animation_host()->NeedsAnimateLayers()); EndTest(); break; } @@ -1168,8 +1197,8 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); - player_child_->AttachLayer(layer_->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); + player_child_->AttachElement(layer_->id()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -1193,17 +1222,15 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating // 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) { + AnimationHost::ElementToAnimationsMap element_animations_copy = + host_impl->animation_host()->active_element_animations_for_testing(); + EXPECT_EQ(2u, element_animations_copy.size()); + for (auto& it : element_animations_copy) { int id = it.first; if (id == host_impl->RootLayer()->id()) { Animation* anim = it.second->GetAnimation(TargetProperty::TRANSFORM); EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); - } else if (id == host_impl->RootLayer()->children()[0]->id()) { + } else if (id == layer_->id()) { Animation* anim = it.second->GetAnimation(TargetProperty::OPACITY); EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); } @@ -1232,8 +1259,8 @@ class LayerTreeHostAnimationTestRemoveAnimation AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); - player_child_->AttachLayer(layer_->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); + player_child_->AttachElement(layer_->id()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -1244,10 +1271,9 @@ class LayerTreeHostAnimationTestRemoveAnimation AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5); break; case 2: - LayerAnimationController* controller = - player_child_->element_animations()->layer_animation_controller(); Animation* animation = - controller->GetAnimation(TargetProperty::TRANSFORM); + player_child_->element_animations()->GetAnimation( + TargetProperty::TRANSFORM); player_child_->RemoveAnimation(animation->id()); gfx::Transform transform; transform.Translate(10.f, 10.f); @@ -1268,8 +1294,7 @@ class LayerTreeHostAnimationTestRemoveAnimation } void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - LayerImpl* root = host_impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = host_impl->active_tree()->LayerById(layer_->id()); switch (host_impl->active_tree()->source_frame_number()) { case 0: // No animation yet. @@ -1313,7 +1338,7 @@ class LayerTreeHostAnimationTestIsAnimating layer_tree_host()->root_layer()->AddChild(layer_); AttachPlayersToTimeline(); - player_->AttachLayer(layer_->id()); + player_->AttachElement(layer_->id()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -1324,18 +1349,15 @@ class LayerTreeHostAnimationTestIsAnimating AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5); break; case 2: - LayerAnimationController* controller = - player_->element_animations()->layer_animation_controller(); - Animation* animation = - controller->GetAnimation(TargetProperty::TRANSFORM); + Animation* animation = player_->element_animations()->GetAnimation( + TargetProperty::TRANSFORM); player_->RemoveAnimation(animation->id()); break; } } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - LayerImpl* root = host_impl->sync_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = host_impl->sync_tree()->LayerById(layer_->id()); switch (host_impl->sync_tree()->source_frame_number()) { case 0: // No animation yet. @@ -1355,8 +1377,7 @@ class LayerTreeHostAnimationTestIsAnimating } void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - LayerImpl* root = host_impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = host_impl->active_tree()->LayerById(layer_->id()); switch (host_impl->active_tree()->source_frame_number()) { case 0: // No animation yet. @@ -1399,8 +1420,8 @@ class LayerTreeHostAnimationTestAnimationFinishesDuringCommit AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); - player_child_->AttachLayer(layer_->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); + player_child_->AttachElement(layer_->id()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -1429,8 +1450,7 @@ class LayerTreeHostAnimationTestAnimationFinishesDuringCommit case 2: gfx::Transform expected_transform; expected_transform.Translate(5.f, 5.f); - LayerImpl* layer_impl = - host_impl->sync_tree()->root_layer()->children()[0]; + LayerImpl* layer_impl = host_impl->sync_tree()->LayerById(layer_->id()); EXPECT_EQ(expected_transform, layer_impl->DrawTransform()); EndTest(); break; @@ -1474,8 +1494,8 @@ class LayerTreeHostAnimationTestNotifyAnimationFinished layer_tree_host()->root_layer()->AddChild(picture_); AttachPlayersToTimeline(); - player_->AttachLayer(picture_->id()); - player_->set_layer_animation_delegate(this); + player_->AttachElement(picture_->id()); + player_->set_animation_delegate(this); } void BeginTest() override { @@ -1514,7 +1534,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostAnimationTestNotifyAnimationFinished); // Check that SetTransformIsPotentiallyAnimatingChanged is called -// if we destroy LayerAnimationController and ElementAnimations. +// if we destroy ElementAnimations. class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction : public LayerTreeHostAnimationTest { public: @@ -1524,7 +1544,7 @@ class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction LayerTreeHostAnimationTest::SetupTree(); AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5); } @@ -1608,8 +1628,8 @@ class LayerTreeHostAnimationTestRebuildPropertyTreesOnAnimationSetNeedsCommit AttachPlayersToTimeline(); - player_->AttachLayer(layer_tree_host()->root_layer()->id()); - player_child_->AttachLayer(layer_->id()); + player_->AttachElement(layer_tree_host()->root_layer()->id()); + player_child_->AttachElement(layer_->id()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index 7f17e0f9caa..2f4c2424bae 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -2,13 +2,11 @@ // 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 <stddef.h> #include <stdint.h> +#include "base/memory/ptr_util.h" #include "cc/layers/heads_up_display_layer.h" -#include "cc/layers/io_surface_layer.h" #include "cc/layers/layer_impl.h" #include "cc/layers/painted_scrollbar_layer.h" #include "cc/layers/picture_layer.h" @@ -35,6 +33,7 @@ #include "cc/test/test_context_provider.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" @@ -77,18 +76,18 @@ class LayerTreeHostContextTest : public LayerTreeTest { context3d_ = NULL; } - virtual scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() { + virtual std::unique_ptr<TestWebGraphicsContext3D> CreateContext3d() { return TestWebGraphicsContext3D::Create(); } - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { if (times_to_fail_create_) { --times_to_fail_create_; ExpectCreateToFail(); - return make_scoped_ptr(new FailureOutputSurface(delegating_renderer())); + return base::WrapUnique(new FailureOutputSurface(delegating_renderer())); } - scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); + std::unique_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); base::AutoLock lock(context3d_lock_); context3d_ = context3d.get(); @@ -189,7 +188,7 @@ class LayerTreeHostContextTestLostContextSucceeds } void CreateAndSetOutputSurface() { - scoped_ptr<OutputSurface> surface( + std::unique_ptr<OutputSurface> surface( LayerTreeHostContextTest::CreateOutputSurface()); CHECK(surface); layer_tree_host()->SetOutputSurface(std::move(surface)); @@ -368,7 +367,7 @@ class LayerTreeHostClientNotVisibleDoesNotCreateOutputSurface EndTest(); } - scoped_ptr<OutputSurface> CreateOutputSurface() override { + std::unique_ptr<OutputSurface> CreateOutputSurface() override { EXPECT_TRUE(false); return nullptr; } @@ -402,7 +401,7 @@ class LayerTreeHostClientTakeAwayOutputSurface } void CreateAndSetOutputSurface() { - scoped_ptr<OutputSurface> surface = + std::unique_ptr<OutputSurface> surface = LayerTreeHostContextTest::CreateOutputSurface(); CHECK(surface); setos_counter_++; @@ -412,7 +411,7 @@ class LayerTreeHostClientTakeAwayOutputSurface void HideAndReleaseOutputSurface() { EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); layer_tree_host()->SetVisible(false); - scoped_ptr<OutputSurface> surface = + std::unique_ptr<OutputSurface> surface = layer_tree_host()->ReleaseOutputSurface(); CHECK(surface); MainThreadTaskRunner()->PostTask( @@ -466,7 +465,7 @@ class MultipleCompositeDoesNotCreateOutputSurface layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(2)); } - scoped_ptr<OutputSurface> CreateOutputSurface() override { + std::unique_ptr<OutputSurface> CreateOutputSurface() override { EXPECT_TRUE(false); return nullptr; } @@ -505,7 +504,7 @@ class FailedCreateDoesNotCreateExtraOutputSurface return; ExpectCreateToFail(); layer_tree_host()->SetOutputSurface( - make_scoped_ptr(new FailureOutputSurface(false))); + base::WrapUnique(new FailureOutputSurface(false))); } void BeginTest() override { @@ -647,7 +646,7 @@ class LayerTreeHostContextTestLostContextSucceedsWithContent void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>( - host_impl->active_tree()->root_layer()->children()[0]); + host_impl->active_tree()->LayerById(layer_->id())); EXPECT_TRUE(picture_impl->HighResTiling() ->TileAt(0, 0) ->draw_info() @@ -857,10 +856,10 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest { 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]); + child_picture = static_cast<FakePictureLayerImpl*>( + host_impl->active_tree()->LayerById(child_->id())); + grandchild_picture = static_cast<FakePictureLayerImpl*>( + host_impl->active_tree()->LayerById(grandchild_->id())); ++num_commits_; switch (num_commits_) { @@ -918,9 +917,9 @@ class LayerTreeHostContextTestDontUseLostResources gpu::gles2::GLES2Interface* gl = child_output_surface_->context_provider()->ContextGL(); - scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); - scoped_ptr<RenderPass> pass_for_quad = RenderPass::Create(); + std::unique_ptr<RenderPass> pass_for_quad = RenderPass::Create(); pass_for_quad->SetNew( // AppendOneOfEveryQuadType() makes a RenderPass quad with this id. RenderPassId(2, 1), @@ -928,7 +927,7 @@ class LayerTreeHostContextTestDontUseLostResources gfx::Rect(0, 0, 10, 10), gfx::Transform()); - scoped_ptr<RenderPass> pass = RenderPass::Create(); + std::unique_ptr<RenderPass> pass = RenderPass::Create(); pass->SetNew(RenderPassId(1, 1), gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10), @@ -1005,15 +1004,15 @@ class LayerTreeHostContextTestDontUseLostResources color_video_frame_ = VideoFrame::CreateColorFrame( gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); ASSERT_TRUE(color_video_frame_); - hw_video_frame_ = VideoFrame::WrapNativeTexture( - media::PIXEL_FORMAT_ARGB, - gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D), + gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes] = { + gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D)}; + hw_video_frame_ = VideoFrame::WrapNativeTextures( + media::PIXEL_FORMAT_ARGB, holders, media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4), gfx::Rect(0, 0, 4, 4), gfx::Size(4, 4), base::TimeDelta()); ASSERT_TRUE(hw_video_frame_); - scaled_hw_video_frame_ = VideoFrame::WrapNativeTexture( - media::PIXEL_FORMAT_ARGB, - gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D), + scaled_hw_video_frame_ = VideoFrame::WrapNativeTextures( + media::PIXEL_FORMAT_ARGB, holders, media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4), gfx::Rect(0, 0, 3, 2), gfx::Size(4, 4), base::TimeDelta()); ASSERT_TRUE(scaled_hw_video_frame_); @@ -1022,20 +1021,14 @@ class LayerTreeHostContextTestDontUseLostResources hw_frame_provider_.set_frame(hw_video_frame_); scaled_hw_frame_provider_.set_frame(scaled_hw_video_frame_); - 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); - // Enable the hud. LayerTreeDebugState debug_state; debug_state.show_property_changed_rects = true; layer_tree_host()->SetDebugState(debug_state); scoped_refptr<PaintedScrollbarLayer> scrollbar = - PaintedScrollbarLayer::Create(scoped_ptr<Scrollbar>(new FakeScrollbar), - layer->id()); + PaintedScrollbarLayer::Create( + std::unique_ptr<Scrollbar>(new FakeScrollbar), layer->id()); scrollbar->SetBounds(gfx::Size(10, 10)); scrollbar->SetIsDrawable(true); root->AddChild(scrollbar); @@ -1069,7 +1062,7 @@ class LayerTreeHostContextTestDontUseLostResources return draw_result; } - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { // This will get called twice: // First when we create the initial output surface... if (layer_tree_host()->source_frame_number() > 0) { @@ -1097,9 +1090,9 @@ class LayerTreeHostContextTestDontUseLostResources bool lost_context_; FakeOutputSurfaceClient output_surface_client_; - scoped_ptr<FakeOutputSurface> child_output_surface_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; - scoped_ptr<ResourceProvider> child_resource_provider_; + std::unique_ptr<FakeOutputSurface> child_output_surface_; + std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<ResourceProvider> child_resource_provider_; scoped_refptr<VideoFrame> color_video_frame_; scoped_refptr<VideoFrame> hw_video_frame_; @@ -1228,7 +1221,7 @@ class UIResourceLostTest : public LayerTreeHostContextTest { protected: int time_step_; - scoped_ptr<FakeScopedUIResource> ui_resource_; + std::unique_ptr<FakeScopedUIResource> ui_resource_; private: void StepCompleteOnMainThreadInternal(int step) { diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index ab4a4569c6a..b92c687529b 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -4,6 +4,7 @@ #include <stddef.h> +#include "base/memory/ptr_util.h" #include "cc/layers/layer_iterator.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" @@ -111,10 +112,10 @@ class LayerTreeHostCopyRequestTestMultipleRequests } } - void CopyOutputCallback(size_t id, scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(size_t id, std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); EXPECT_TRUE(result->HasBitmap()); - scoped_ptr<SkBitmap> bitmap = result->TakeBitmap(); + std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap(); EXPECT_EQ(result->size().ToString(), gfx::Size(bitmap->width(), bitmap->height()).ToString()); callbacks_[id] = result->size(); @@ -122,12 +123,12 @@ class LayerTreeHostCopyRequestTestMultipleRequests void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); } - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { if (!use_gl_renderer_) { return FakeOutputSurface::CreateSoftware( - make_scoped_ptr(new SoftwareOutputDevice)); + base::WrapUnique(new SoftwareOutputDevice)); } - scoped_ptr<FakeOutputSurface> output_surface = + std::unique_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); TestContextSupport* context_support = static_cast<TestContextSupport*>( output_surface->context_provider()->ContextSupport()); @@ -223,7 +224,7 @@ class LayerTreeHostCopyRequestCompletionCausesCommit } } - static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + static void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_FALSE(result->IsEmpty()); } @@ -313,7 +314,7 @@ class LayerTreeHostCopyRequestTestLayerDestroyed } } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); EXPECT_TRUE(result->IsEmpty()); ++callback_count_; @@ -344,7 +345,7 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree // parent_layer_ owns a render surface. parent_layer_ = FakePictureLayer::Create(&client_); parent_layer_->SetBounds(gfx::Size(15, 15)); - parent_layer_->SetForceRenderSurface(true); + parent_layer_->SetForceRenderSurfaceForTesting(true); grand_parent_layer_->AddChild(parent_layer_); copy_layer_ = FakePictureLayer::Create(&client_); @@ -370,7 +371,7 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree AddCopyRequest(copy_layer_.get()); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { ++callback_count_; EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString()) @@ -445,7 +446,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest // parent_layer_ owns a render surface. parent_layer_ = FakePictureLayer::Create(&client_); parent_layer_->SetBounds(gfx::Size(15, 15)); - parent_layer_->SetForceRenderSurface(true); + parent_layer_->SetForceRenderSurfaceForTesting(true); grand_parent_layer_->AddChild(parent_layer_); copy_layer_ = FakePictureLayer::Create(&client_); @@ -468,7 +469,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest base::Unretained(this)))); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString()); EndTest(); @@ -477,10 +478,10 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { Renderer* renderer = host_impl->renderer(); - LayerImpl* root = host_impl->active_tree()->root_layer(); - LayerImpl* grand_parent = root->children()[0]; - LayerImpl* parent = grand_parent->children()[0]; - LayerImpl* copy_layer = parent->children()[0]; + LayerImpl* parent = + host_impl->active_tree()->LayerById(parent_layer_->id()); + LayerImpl* copy_layer = + host_impl->active_tree()->LayerById(copy_layer_->id()); // |parent| owns a surface, but it was hidden and not part of the copy // request so it should not allocate any resource. @@ -545,7 +546,7 @@ class LayerTreeHostCopyRequestTestClippedOut base::Unretained(this)))); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { // We should still get the content even if the copy requested layer was // completely clipped away. EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); @@ -591,7 +592,7 @@ class LayerTreeHostCopyRequestTestScaledLayer void BeginTest() override { PostSetNeedsCommitToMainThread(); - scoped_ptr<CopyOutputRequest> request = + std::unique_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateBitmapRequest(base::Bind( &LayerTreeHostCopyRequestTestScaledLayer::CopyOutputCallback, base::Unretained(this))); @@ -599,7 +600,7 @@ class LayerTreeHostCopyRequestTestScaledLayer copy_layer_->RequestCopyOfOutput(std::move(request)); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { // The request area is expressed in layer space, but the result's size takes // into account the transform from layer space to surface space. EXPECT_EQ(gfx::Size(10, 10), result->size()); @@ -653,8 +654,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { if (impl->active_tree()->source_frame_number() == 0) { - LayerImpl* root = impl->active_tree()->root_layer(); - EXPECT_TRUE(root->children()[0]->HasCopyRequest()); + EXPECT_TRUE(impl->active_tree()->LayerById(copy_layer_->id())); saw_copy_request_ = true; } } @@ -668,7 +668,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw } } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); // The first frame can't be drawn. @@ -705,7 +705,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( class LayerTreeHostCopyRequestTestLostOutputSurface : public LayerTreeHostCopyRequestTest { protected: - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { if (!first_context_provider_) { first_context_provider_ = TestContextProvider::Create(); return FakeOutputSurface::Create3d(first_context_provider_); @@ -731,7 +731,8 @@ class LayerTreeHostCopyRequestTestLostOutputSurface void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void ReceiveCopyRequestOutputAndCommit(scoped_ptr<CopyOutputResult> result) { + void ReceiveCopyRequestOutputAndCommit( + std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(layer_tree_host()->task_runner_provider()->IsMainThread()); EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString()); EXPECT_TRUE(result->HasTexture()); @@ -830,7 +831,7 @@ class LayerTreeHostCopyRequestTestLostOutputSurface FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; scoped_refptr<FakePictureLayer> copy_layer_; - scoped_ptr<CopyOutputResult> result_; + std::unique_ptr<CopyOutputResult> result_; }; SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( @@ -839,7 +840,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( class LayerTreeHostCopyRequestTestCountTextures : public LayerTreeHostCopyRequestTest { protected: - scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { + std::unique_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { context_provider_ = TestContextProvider::Create(); return FakeOutputSurface::Create3d(context_provider_); } @@ -922,12 +923,12 @@ class LayerTreeHostCopyRequestTestCreatesTexture base::Unretained(this)))); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_FALSE(result->IsEmpty()); EXPECT_TRUE(result->HasTexture()); TextureMailbox mailbox; - scoped_ptr<SingleReleaseCallback> release; + std::unique_ptr<SingleReleaseCallback> release; result->TakeTexture(&mailbox, &release); EXPECT_TRUE(release); @@ -954,12 +955,12 @@ class LayerTreeHostCopyRequestTestProvideTexture LayerTreeHostCopyRequestTestCountTextures::BeginTest(); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_FALSE(result->IsEmpty()); EXPECT_TRUE(result->HasTexture()); TextureMailbox mailbox; - scoped_ptr<SingleReleaseCallback> release; + std::unique_ptr<SingleReleaseCallback> release; result->TakeTexture(&mailbox, &release); EXPECT_FALSE(release); } @@ -967,7 +968,7 @@ class LayerTreeHostCopyRequestTestProvideTexture void RequestCopy(Layer* layer) override { // Request a copy to a provided texture. This should not create a new // texture. - scoped_ptr<CopyOutputRequest> request = + std::unique_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateRequest(base::Bind( &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback, base::Unretained(this))); @@ -1023,7 +1024,7 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy PostSetNeedsCommitToMainThread(); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(result->IsEmpty()); ++callback_count_; } @@ -1041,10 +1042,10 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy EXPECT_EQ(0, callback_count_); // Put a copy request on the layer, but then don't allow any // drawing to take place. - scoped_ptr<CopyOutputRequest> request = + std::unique_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateRequest( base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy:: - CopyOutputCallback, + CopyOutputCallback, base::Unretained(this))); copy_layer_->RequestCopyOfOutput(std::move(request)); @@ -1101,7 +1102,7 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy PostSetNeedsCommitToMainThread(); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_TRUE(result->IsEmpty()); ++callback_count_; } @@ -1119,10 +1120,10 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy EXPECT_EQ(0, callback_count_); // Put a copy request on the layer, but then don't allow any // drawing to take place. - scoped_ptr<CopyOutputRequest> request = + std::unique_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateRequest( base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy:: - CopyOutputCallback, + CopyOutputCallback, base::Unretained(this))); copy_layer_->RequestCopyOfOutput(std::move(request)); @@ -1191,7 +1192,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { LayerImpl* root = host_impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = host_impl->active_tree()->LayerById(child_->id()); bool saw_root = false; bool saw_child = false; @@ -1245,7 +1246,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest return draw_result; } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { EXPECT_FALSE(TestEnded()); copy_happened_ = true; TryEndTest(); diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index 76c26f6682e..a9afb92b67c 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -338,26 +338,26 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { layer_tree_host()->SetRootLayer(root_layer); scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); - scoped_refptr<Layer> content_layer = FakePictureLayer::Create(&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); + content_layer_ = FakePictureLayer::Create(&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); + 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()); + FakePaintedScrollbarLayer::Create(false, true, content_layer_->id()); scrollbar_layer->SetPosition(gfx::PointF(300.f, 300.f)); scrollbar_layer->SetBounds(gfx::Size(10, 100)); - scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(content_layer->id()); + scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(content_layer_->id()); root_layer->AddChild(scrollbar_layer); - gfx::RectF content_rect(content_layer->position(), - gfx::SizeF(content_layer->bounds())); + gfx::RectF content_rect(content_layer_->position(), + gfx::SizeF(content_layer_->bounds())); gfx::RectF scrollbar_rect(scrollbar_layer->position(), gfx::SizeF(scrollbar_layer->bounds())); EXPECT_FALSE(content_rect.Intersects(scrollbar_rect)); @@ -368,6 +368,9 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { private: FakeContentLayerClient client_; + + protected: + scoped_refptr<Layer> content_layer_; }; class LayerTreeHostDamageTestScrollbarDoesDamage @@ -410,9 +413,8 @@ class LayerTreeHostDamageTestScrollbarDoesDamage void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ++did_swaps_; EXPECT_TRUE(result); - LayerImpl* root = host_impl->active_tree()->root_layer(); - LayerImpl* scroll_clip_layer = root->children()[0]; - LayerImpl* scroll_layer = scroll_clip_layer->children()[0]; + LayerImpl* scroll_layer = + host_impl->active_tree()->LayerById(content_layer_->id()); switch (did_swaps_) { case 1: // Test that modifying the position of the content layer (not @@ -439,18 +441,13 @@ class LayerTreeHostDamageTestScrollbarDoesDamage void ModifyContentLayerPosition() { EXPECT_EQ(1, 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->SetPosition(gfx::PointF(10.f, 10.f)); + content_layer_->SetPosition(gfx::PointF(10.f, 10.f)); } 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( + content_layer_->SetBounds( gfx::Size(root->bounds().width() + 60, root->bounds().height() + 100)); } @@ -503,9 +500,8 @@ class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ++did_swaps_; EXPECT_TRUE(result); - LayerImpl* root = host_impl->active_tree()->root_layer(); - LayerImpl* scroll_clip_layer = root->children()[0]; - LayerImpl* scroll_layer = scroll_clip_layer->children()[0]; + LayerImpl* scroll_layer = + host_impl->active_tree()->LayerById(content_layer_->id()); switch (did_swaps_) { case 1: // Scroll on the thread. This should damage the scrollbar for the diff --git a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc index 9f35bd90bd3..1d3b3963c8d 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc @@ -34,12 +34,12 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer root->SetBounds(gfx::Size(100, 100)); root->SetIsDrawable(true); - scoped_refptr<Layer> child = Layer::Create(); - child->SetBounds(gfx::Size(50, 60)); - child->SetPosition(gfx::PointF(10.f, 5.5f)); - child->SetContentsOpaque(true); - child->SetIsDrawable(true); - root->AddChild(child); + child_ = Layer::Create(); + child_->SetBounds(gfx::Size(50, 60)); + child_->SetPosition(gfx::PointF(10.f, 5.5f)); + child_->SetContentsOpaque(true); + child_->SetIsDrawable(true); + root->AddChild(child_); layer_tree_host()->SetRootLayer(root); LayerTreeTest::SetupTree(); @@ -49,11 +49,11 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = impl->active_tree()->LayerById(child_->id()); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); EXPECT_OCCLUSION_EQ( Occlusion(child->DrawTransform(), SimpleEnclosedRegion(), @@ -67,6 +67,9 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer } void AfterTest() override {} + + private: + scoped_refptr<Layer> child_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnLayer); @@ -80,12 +83,12 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface root->SetBounds(gfx::Size(100, 100)); root->SetIsDrawable(true); - scoped_refptr<Layer> child = Layer::Create(); - child->SetBounds(gfx::Size(1, 1)); - child->SetPosition(gfx::PointF(10.f, 5.5f)); - child->SetIsDrawable(true); - child->SetForceRenderSurface(true); - root->AddChild(child); + child_ = Layer::Create(); + child_->SetBounds(gfx::Size(1, 1)); + child_->SetPosition(gfx::PointF(10.f, 5.5f)); + child_->SetIsDrawable(true); + child_->SetForceRenderSurfaceForTesting(true); + root->AddChild(child_); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 12)); @@ -102,13 +105,14 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = impl->active_tree()->LayerById(child_->id()); RenderSurfaceImpl* surface = child->render_surface(); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_EQ(child, child->render_target()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->has_render_surface()); + EXPECT_EQ(child->render_surface(), child->render_target()); EXPECT_OCCLUSION_EQ( Occlusion(surface->draw_transform(), SimpleEnclosedRegion(), @@ -118,6 +122,9 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface } void AfterTest() override {} + + private: + scoped_refptr<Layer> child_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -132,22 +139,22 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask root->SetBounds(gfx::Size(100, 100)); root->SetIsDrawable(true); - scoped_refptr<Layer> child = Layer::Create(); - child->SetBounds(gfx::Size(30, 40)); - child->SetPosition(gfx::PointF(10.f, 5.5f)); - child->SetIsDrawable(true); - root->AddChild(child); + child_ = Layer::Create(); + 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(); 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); + child_->AddChild(make_surface_bigger); scoped_refptr<Layer> mask = PictureLayer::Create(&client_); mask->SetBounds(gfx::Size(30, 40)); mask->SetIsDrawable(true); - child->SetMaskLayer(mask.get()); + child_->SetMaskLayer(mask.get()); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 12)); @@ -165,14 +172,15 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = impl->active_tree()->LayerById(child_->id()); RenderSurfaceImpl* surface = child->render_surface(); LayerImpl* mask = child->mask_layer(); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_EQ(child, child->render_target()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->has_render_surface()); + EXPECT_EQ(child->render_surface(), child->render_target()); gfx::Transform transform = surface->draw_transform(); transform.PreconcatTransform(child->DrawTransform()); @@ -186,7 +194,9 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask void AfterTest() override {} + private: FakeContentLayerClient client_; + scoped_refptr<Layer> child_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnMask); @@ -203,21 +213,21 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask gfx::Transform scale; scale.Scale(2, 2); - scoped_refptr<Layer> child = Layer::Create(); - child->SetBounds(gfx::Size(30, 40)); - child->SetTransform(scale); - root->AddChild(child); + child_ = Layer::Create(); + child_->SetBounds(gfx::Size(30, 40)); + child_->SetTransform(scale); + root->AddChild(child_); scoped_refptr<Layer> grand_child = Layer::Create(); grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetPosition(gfx::PointF(-10.f, -15.f)); grand_child->SetIsDrawable(true); - child->AddChild(grand_child); + child_->AddChild(grand_child); scoped_refptr<Layer> mask = PictureLayer::Create(&client_); mask->SetBounds(gfx::Size(30, 40)); mask->SetIsDrawable(true); - child->SetMaskLayer(mask.get()); + child_->SetMaskLayer(mask.get()); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 11)); @@ -234,8 +244,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = impl->active_tree()->LayerById(child_->id()); LayerImpl* mask = child->mask_layer(); gfx::Transform scale; @@ -250,7 +259,9 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask void AfterTest() override {} + private: FakeContentLayerClient client_; + scoped_refptr<Layer> child_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -268,23 +279,23 @@ class LayerTreeHostOcclusionTestDrawPropertiesInsideReplica root->SetBounds(gfx::Size(100, 100)); root->SetIsDrawable(true); - scoped_refptr<Layer> child = Layer::Create(); - child->SetBounds(gfx::Size(1, 1)); - child->SetPosition(gfx::PointF(10.f, 5.5f)); - child->SetIsDrawable(true); - child->SetForceRenderSurface(true); - root->AddChild(child); + child_ = Layer::Create(); + child_->SetBounds(gfx::Size(1, 1)); + child_->SetPosition(gfx::PointF(10.f, 5.5f)); + child_->SetIsDrawable(true); + child_->SetForceRenderSurfaceForTesting(true); + root->AddChild(child_); scoped_refptr<Layer> replica = Layer::Create(); gfx::Transform translate; translate.Translate(20.f, 4.f); replica->SetTransform(translate); - child->SetReplicaLayer(replica.get()); + child_->SetReplicaLayer(replica.get()); scoped_refptr<Layer> mask = PictureLayer::Create(&client_); mask->SetBounds(gfx::Size(30, 40)); mask->SetIsDrawable(true); - child->SetMaskLayer(mask.get()); + child_->SetMaskLayer(mask.get()); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 12)); @@ -302,14 +313,15 @@ class LayerTreeHostOcclusionTestDrawPropertiesInsideReplica void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; + LayerImpl* child = impl->active_tree()->LayerById(child_->id()); RenderSurfaceImpl* surface = child->render_surface(); LayerImpl* mask = child->mask_layer(); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_EQ(child, child->render_target()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->has_render_surface()); + EXPECT_EQ(child->render_surface(), child->render_target()); // No occlusion from on child, which is part of the replica. EXPECT_OCCLUSION_EQ(Occlusion(), @@ -327,7 +339,9 @@ class LayerTreeHostOcclusionTestDrawPropertiesInsideReplica void AfterTest() override {} + private: FakeContentLayerClient client_; + scoped_refptr<Layer> child_; }; SINGLE_AND_MULTI_THREAD_TEST_F( diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index c41a25259cd..319e609aef7 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -36,6 +36,8 @@ class LayerTreeHostPictureTestTwinLayer : public LayerTreeHostPictureTest { void SetupTree() override { SetupTreeWithSinglePictureLayer(gfx::Size(1, 1)); + picture_id1_ = root_picture_layer_->id(); + picture_id2_ = -1; } void BeginTest() override { @@ -52,13 +54,14 @@ class LayerTreeHostPictureTestTwinLayer case 2: // Drop the picture layer from the tree so the activate will have an // active layer without a pending twin. - layer_tree_host()->root_layer()->children()[0]->RemoveFromParent(); + root_picture_layer_->RemoveFromParent(); break; case 3: { // Add a new picture layer so the activate will have a pending layer // without an active twin. scoped_refptr<FakePictureLayer> picture = FakePictureLayer::Create(&client_); + picture_id2_ = picture->id(); layer_tree_host()->root_layer()->AddChild(picture); break; } @@ -73,16 +76,19 @@ class LayerTreeHostPictureTestTwinLayer } void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* pending_root_impl = impl->pending_tree()->root_layer(); LayerImpl* active_root_impl = impl->active_tree()->root_layer(); + int picture_id = impl->active_tree()->source_frame_number() < 2 + ? picture_id1_ + : picture_id2_; - if (pending_root_impl->children().empty()) { + if (!impl->pending_tree()->LayerById(picture_id)) { EXPECT_EQ(2, activates_); return; } FakePictureLayerImpl* pending_picture_impl = - static_cast<FakePictureLayerImpl*>(pending_root_impl->children()[0]); + static_cast<FakePictureLayerImpl*>( + impl->pending_tree()->LayerById(picture_id)); if (!active_root_impl) { EXPECT_EQ(0, activates_); @@ -90,14 +96,15 @@ class LayerTreeHostPictureTestTwinLayer return; } - if (active_root_impl->children().empty()) { + if (!impl->active_tree()->LayerById(picture_id)) { EXPECT_EQ(3, activates_); EXPECT_EQ(nullptr, pending_picture_impl->GetPendingOrActiveTwinLayer()); return; } FakePictureLayerImpl* active_picture_impl = - static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]); + static_cast<FakePictureLayerImpl*>( + impl->active_tree()->LayerById(picture_id)); // After the first activation, when we commit again, we'll have a pending // and active layer. Then we recreate a picture layer in the 4th activate @@ -111,12 +118,15 @@ class LayerTreeHostPictureTestTwinLayer } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* active_root_impl = impl->active_tree()->root_layer(); - if (active_root_impl->children().empty()) { + int picture_id = impl->active_tree()->source_frame_number() < 3 + ? picture_id1_ + : picture_id2_; + if (!impl->active_tree()->LayerById(picture_id)) { EXPECT_EQ(2, activates_); } else { FakePictureLayerImpl* active_picture_impl = - static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]); + static_cast<FakePictureLayerImpl*>( + impl->active_tree()->LayerById(picture_id)); EXPECT_EQ(nullptr, active_picture_impl->GetPendingOrActiveTwinLayer()); } @@ -126,6 +136,8 @@ class LayerTreeHostPictureTestTwinLayer void AfterTest() override { EXPECT_EQ(5, activates_); } int activates_; + int picture_id1_; + int picture_id2_; }; // There is no pending layers in single thread mode. @@ -153,7 +165,7 @@ class LayerTreeHostPictureTestResizeViewportWithGpuRaster void BeginTest() override { PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* child = impl->sync_tree()->root_layer()->children()[0]; + LayerImpl* child = impl->sync_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>(child); gfx::Size tile_size = @@ -222,7 +234,7 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* child = impl->active_tree()->root_layer()->children()[0]; + LayerImpl* child = impl->active_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>(child); switch (++frame_) { @@ -271,7 +283,7 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree } void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* child = impl->sync_tree()->root_layer()->children()[0]; + LayerImpl* child = impl->sync_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>(child); PictureLayerTiling* tiling = picture_impl->HighResTiling(); @@ -325,9 +337,7 @@ class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest { void BeginTest() override { PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->sync_tree()->root_layer(); - LayerImpl* child = root->children()[0]; - LayerImpl* gchild = child->children()[0]; + LayerImpl* gchild = impl->sync_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild); switch (impl->sync_tree()->source_frame_number()) { @@ -347,9 +357,7 @@ class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest { } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* child = root->children()[0]; - LayerImpl* gchild = child->children()[0]; + LayerImpl* gchild = impl->sync_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild); switch (impl->active_tree()->source_frame_number()) { @@ -434,9 +442,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale } void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->sync_tree()->root_layer(); - LayerImpl* pinch = root->children()[0]->children()[0]; - LayerImpl* gchild = pinch->children()[0]; + LayerImpl* gchild = impl->sync_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild); ready_to_draw_ = false; @@ -461,9 +467,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer(); - LayerImpl* pinch = root->children()[0]->children()[0]; - LayerImpl* gchild = pinch->children()[0]; + LayerImpl* gchild = impl->active_tree()->LayerById(picture_->id()); FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild); if (frame_ != last_frame_drawn_) diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc index 46a2d36e7d7..8c3779bffec 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc @@ -280,64 +280,136 @@ PROXY_MAIN_THREADED_TEST_F(ProxyMainThreadedSetNeedsCommitWhileAnimating); class ProxyMainThreadedCommitWaitsForActivation : public ProxyMainThreaded { protected: - ProxyMainThreadedCommitWaitsForActivation() : commits_completed_(0) {} + ProxyMainThreadedCommitWaitsForActivation() : num_commits_(0) {} ~ProxyMainThreadedCommitWaitsForActivation() override {} void BeginTest() override { proxy()->SetNeedsCommit(); } void ScheduledActionCommit() override { - switch (commits_completed_) { + switch (num_commits_) { case 0: - // The first commit does not wait for activation. Verify that the - // completion event is cleared. - EXPECT_FALSE(GetProxyImplForTest()->HasCommitCompletionEvent()); - EXPECT_FALSE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); - // Set next commit waits for activation and start another commit. - commits_completed_++; PostNextCommitWaitsForActivationToMainThread(); PostSetNeedsCommitToMainThread(); break; case 1: - // The second commit should be held until activation. - EXPECT_TRUE(GetProxyImplForTest()->HasCommitCompletionEvent()); - EXPECT_TRUE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); - - // Start another commit to verify that this is not held until - // activation. - commits_completed_++; PostSetNeedsCommitToMainThread(); break; - case 2: - // The third commit should not wait for activation. - EXPECT_FALSE(GetProxyImplForTest()->HasCommitCompletionEvent()); - EXPECT_FALSE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); - - commits_completed_++; } + num_commits_++; } - void DidActivateSyncTree() override { - // The next_commit_waits_for_activation should have been cleared after the - // sync tree is activated. - EXPECT_FALSE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); - if (commits_completed_ == 3) - EndTest(); + void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + CompletionEvent* activation_completion_event = + GetProxyImplForTest()->ActivationCompletionEventForTesting(); + switch (num_commits_) { + case 1: + EXPECT_FALSE(activation_completion_event); + break; + case 2: + EXPECT_TRUE(activation_completion_event); + EXPECT_FALSE(activation_completion_event->IsSignaled()); + break; + case 3: + EXPECT_FALSE(activation_completion_event); + EndTest(); + break; + } } void AfterTest() override { - // It is safe to read commits_completed_ on the main thread now since - // AfterTest() runs after the LayerTreeHost is destroyed and the impl thread - // tear down is finished. - EXPECT_EQ(3, commits_completed_); + // It is safe to read num_commits_ on the main thread now since AfterTest() + // runs after the LayerTreeHost is destroyed and the impl thread tear down + // is finished. + EXPECT_EQ(3, num_commits_); } private: - int commits_completed_; + int num_commits_; DISALLOW_COPY_AND_ASSIGN(ProxyMainThreadedCommitWaitsForActivation); }; PROXY_MAIN_THREADED_TEST_F(ProxyMainThreadedCommitWaitsForActivation); +// Test for a corner case of main frame before activation (MFBA) and commit +// waits for activation. If a commit (with wait for activation flag set) +// is ready before the activation for a previous commit then the activation +// should not signal the completion event of the second commit. +class ProxyMainThreadedCommitWaitsForActivationMFBA : public ProxyMainThreaded { + protected: + ProxyMainThreadedCommitWaitsForActivationMFBA() : num_commits_(0) {} + ~ProxyMainThreadedCommitWaitsForActivationMFBA() override {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->main_frame_before_activation_enabled = true; + ProxyMainThreaded::InitializeSettings(settings); + } + + void BeginTest() override { proxy()->SetNeedsCommit(); } + + // This is called right before NotifyReadyToCommit. + void StartCommitOnImpl() override { + switch (num_commits_) { + case 0: + // Block activation until next commit is ready. + GetProxyImplForTest()->BlockNotifyReadyToActivateForTesting(true); + break; + case 1: + // Unblock activation of first commit after second commit is ready. + ImplThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ProxyImplForTest::BlockNotifyReadyToActivateForTesting, + base::Unretained(GetProxyImplForTest()), false)); + break; + } + } + + void ScheduledActionCommit() override { + switch (num_commits_) { + case 0: + // Set next commit waits for activation and start another commit. + PostNextCommitWaitsForActivationToMainThread(); + PostSetNeedsCommitToMainThread(); + break; + case 1: + PostSetNeedsCommitToMainThread(); + break; + } + num_commits_++; + } + + void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + CompletionEvent* activation_completion_event = + GetProxyImplForTest()->ActivationCompletionEventForTesting(); + switch (num_commits_) { + case 1: + EXPECT_FALSE(activation_completion_event); + break; + case 2: + EXPECT_TRUE(activation_completion_event); + EXPECT_FALSE(activation_completion_event->IsSignaled()); + break; + case 3: + EXPECT_FALSE(activation_completion_event); + EndTest(); + break; + } + } + + void AfterTest() override { + // It is safe to read num_commits_ on the main thread now since AfterTest() + // runs after the LayerTreeHost is destroyed and the impl thread tear down + // is finished. + EXPECT_EQ(3, num_commits_); + } + + private: + int num_commits_; + + DISALLOW_COPY_AND_ASSIGN(ProxyMainThreadedCommitWaitsForActivationMFBA); +}; + +PROXY_MAIN_THREADED_TEST_F(ProxyMainThreadedCommitWaitsForActivationMFBA); + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.cc b/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.cc index 52401304836..f56109b077f 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.cc @@ -15,7 +15,7 @@ TEST(LayerTreeHostRecordGpuHistogramTest, SingleThreaded) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings; - scoped_ptr<FakeLayerTreeHost> host = + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client, &task_graph_runner, settings, CompositorMode::SINGLE_THREADED); host->RecordGpuRasterizationHistogram(); @@ -26,7 +26,7 @@ TEST(LayerTreeHostRecordGpuHistogramTest, Threaded) { FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings; - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( &host_client, &task_graph_runner, settings, CompositorMode::THREADED); host->RecordGpuRasterizationHistogram(); EXPECT_TRUE(host->gpu_rasterization_histogram_recorded()); diff --git a/chromium/cc/trees/layer_tree_host_unittest_remote_server.cc b/chromium/cc/trees/layer_tree_host_unittest_remote_server.cc index 9873dca1e6a..18c9fcc6bbd 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_remote_server.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_remote_server.cc @@ -2,12 +2,13 @@ // 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 <memory> -#include "base/memory/scoped_ptr.h" -#include "base/thread_task_runner_handle.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/test/fake_image_serialization_processor.h" #include "cc/test/test_task_graph_runner.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/proxy_common.h" #include "cc/trees/proxy_main.h" @@ -24,7 +25,7 @@ class LayerTreeHostTestRemoteServer : public testing::Test, LayerTreeHostTestRemoteServer() : calls_received_(0), image_serialization_processor_( - make_scoped_ptr(new FakeImageSerializationProcessor)) { + base::WrapUnique(new FakeImageSerializationProcessor)) { LayerTreeHost::InitParams params; params.client = this; params.task_graph_runner = &task_graph_runner_; @@ -54,12 +55,10 @@ class LayerTreeHostTestRemoteServer : public testing::Test, void DidCommit() override {} void DidCommitAndDrawFrame() override {} void DidCompleteSwapBuffers() override {} - void RecordFrameTimingEvents( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) - override{}; void DidCompletePageScaleAnimation() override {} - void SendBeginFramesToChildren(const BeginFrameArgs& args) override {} + void ReportFixedRasterScaleUseCounters( + bool has_blurry_content, + bool has_potential_performance_regression) override {} // RemoteProtoChannel implementation void SetProtoReceiver(RemoteProtoChannel::ProtoReceiver* receiver) override { @@ -70,9 +69,10 @@ class LayerTreeHostTestRemoteServer : public testing::Test, int calls_received_; TestTaskGraphRunner task_graph_runner_; LayerTreeSettings settings_; - scoped_ptr<LayerTreeHost> layer_tree_host_; + std::unique_ptr<LayerTreeHost> layer_tree_host_; RemoteProtoChannel::ProtoReceiver* receiver_; - scoped_ptr<FakeImageSerializationProcessor> image_serialization_processor_; + std::unique_ptr<FakeImageSerializationProcessor> + image_serialization_processor_; private: DISALLOW_COPY_AND_ASSIGN(LayerTreeHostTestRemoteServer); @@ -91,7 +91,7 @@ class LayerTreeHostTestRemoteServerBeginMainFrame TEST_F(LayerTreeHostTestRemoteServerBeginMainFrame, BeginMainFrameNotAborted) { layer_tree_host_->SetVisible(true); - scoped_ptr<BeginMainFrameAndCommitState> begin_frame_state; + std::unique_ptr<BeginMainFrameAndCommitState> begin_frame_state; begin_frame_state.reset(new BeginMainFrameAndCommitState()); begin_frame_state->scroll_info.reset(new ScrollAndScaleSet()); diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index b5fce204890..8e15150b16e 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -7,7 +7,7 @@ #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" @@ -29,30 +29,30 @@ namespace cc { namespace { -scoped_ptr<ScrollState> BeginState(const gfx::Point& point) { +std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) { ScrollStateData scroll_state_data; scroll_state_data.is_beginning = true; - scroll_state_data.start_position_x = point.x(); - scroll_state_data.start_position_y = point.y(); - scoped_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); + scroll_state_data.position_x = point.x(); + scroll_state_data.position_y = point.y(); + std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); return scroll_state; } -scoped_ptr<ScrollState> UpdateState(const gfx::Point& point, - const gfx::Vector2dF& delta) { +std::unique_ptr<ScrollState> UpdateState(const gfx::Point& point, + const gfx::Vector2dF& delta) { ScrollStateData scroll_state_data; scroll_state_data.delta_x = delta.x(); scroll_state_data.delta_y = delta.y(); - scroll_state_data.start_position_x = point.x(); - scroll_state_data.start_position_y = point.y(); - scoped_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); + scroll_state_data.position_x = point.x(); + scroll_state_data.position_y = point.y(); + std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); return scroll_state; } -scoped_ptr<ScrollState> EndState() { +std::unique_ptr<ScrollState> EndState() { ScrollStateData scroll_state_data; scroll_state_data.is_ending = true; - scoped_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); + std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data)); return scroll_state; } @@ -85,6 +85,10 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { num_scrolls_(0) {} void BeginTest() override { + outer_viewport_container_layer_id_ = layer_tree_host() + ->outer_viewport_scroll_layer() + ->scroll_clip_layer() + ->id(); layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( initial_scroll_); PostSetNeedsCommitToMainThread(); @@ -109,7 +113,7 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); - scroll_layer->SetScrollClipLayer(root->children()[0]->id()); + scroll_layer->SetScrollClipLayer(outer_viewport_container_layer_id_); scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); scroll_layer->ScrollBy(scroll_amount_); @@ -147,6 +151,7 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { gfx::ScrollOffset second_scroll_; gfx::Vector2dF scroll_amount_; int num_scrolls_; + int outer_viewport_container_layer_id_; }; MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple); @@ -492,6 +497,63 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll); +class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest { + public: + LayerTreeHostScrollTestScrollSnapping() : scroll_amount_(1.75, 0) {} + + void SetupTree() override { + LayerTreeHostScrollTest::SetupTree(); + layer_tree_host() + ->outer_viewport_scroll_layer() + ->scroll_clip_layer() + ->SetForceRenderSurfaceForTesting(true); + gfx::Transform translate; + translate.Translate(0.25f, 0.f); + layer_tree_host() + ->outer_viewport_scroll_layer() + ->scroll_clip_layer() + ->SetTransform(translate); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { + LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + gfx::Transform translate; + + // Check that screen space transform of the scrollable layer is correctly + // snapped to integers. + switch (impl->active_tree()->source_frame_number()) { + case 0: + EXPECT_EQ(gfx::Transform(), + scroll_layer->draw_properties().screen_space_transform); + PostSetNeedsCommitToMainThread(); + break; + case 1: + translate.Translate(-2, 0); + EXPECT_EQ(translate, + scroll_layer->draw_properties().screen_space_transform); + PostSetNeedsCommitToMainThread(); + break; + case 2: + translate.Translate(-3, 0); + EXPECT_EQ(translate, + scroll_layer->draw_properties().screen_space_transform); + EndTest(); + break; + } + scroll_layer->ScrollBy(scroll_amount_); + } + + void AfterTest() override {} + + private: + gfx::Vector2dF scroll_amount_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSnapping); + class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { public: LayerTreeHostScrollTestCaseWithChild() @@ -606,7 +668,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { FakePictureLayerImpl* root_scroll_layer_impl = static_cast<FakePictureLayerImpl*>(impl->OuterViewportScrollLayer()); FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( - root_scroll_layer_impl->children()[0]); + root_scroll_layer_impl->layer_tree_impl()->LayerById( + child_layer_->id())); LayerImpl* expected_scroll_layer_impl = NULL; LayerImpl* expected_no_scroll_layer_impl = NULL; @@ -1075,12 +1138,18 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset public: LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {} - void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { + outer_viewport_container_layer_id_ = layer_tree_host() + ->outer_viewport_scroll_layer() + ->scroll_clip_layer() + ->id(); + PostSetNeedsCommitToMainThread(); + } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); - scroll_layer->SetScrollClipLayer(root->children()[0]->id()); + scroll_layer->SetScrollClipLayer(outer_viewport_container_layer_id_); // Set max_scroll_offset = (100, 100). scroll_layer->SetBounds( @@ -1129,6 +1198,9 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset } void AfterTest() override {} + + private: + int outer_viewport_container_layer_id_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -1305,7 +1377,7 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { params.task_graph_runner = &task_graph_runner; params.settings = &settings; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); - scoped_ptr<LayerTreeHost> layer_tree_host = + std::unique_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::CreateThreaded(impl_thread.task_runner(), ¶ms); impl_thread.task_runner()->PostTask( @@ -1339,21 +1411,30 @@ class LayerTreeHostScrollTestLayerStructureChange Layer* root_scroll_layer = CreateScrollLayer(outer_scroll_layer, &root_scroll_layer_client_); - CreateScrollLayer(outer_scroll_layer, &sibling_scroll_layer_client_); - CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_); + Layer* sibling_scroll_layer = + CreateScrollLayer(outer_scroll_layer, &sibling_scroll_layer_client_); + Layer* child_scroll_layer = + CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_); + root_scroll_layer_id_ = root_scroll_layer->id(); + sibling_scroll_layer_id_ = sibling_scroll_layer->id(); + child_scroll_layer_id_ = child_scroll_layer->id(); fake_content_layer_client_.set_bounds(root_layer->bounds()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->OuterViewportScrollLayer(); switch (impl->active_tree()->source_frame_number()) { case 0: - SetScrollOffsetDelta(root->child_at(0), gfx::Vector2dF(5, 5)); - SetScrollOffsetDelta(root->child_at(0)->child_at(0), - gfx::Vector2dF(5, 5)); - SetScrollOffsetDelta(root->child_at(1), gfx::Vector2dF(5, 5)); + SetScrollOffsetDelta( + impl->active_tree()->LayerById(root_scroll_layer_id_), + gfx::Vector2dF(5, 5)); + SetScrollOffsetDelta( + impl->active_tree()->LayerById(child_scroll_layer_id_), + gfx::Vector2dF(5, 5)); + SetScrollOffsetDelta( + impl->active_tree()->LayerById(sibling_scroll_layer_id_), + gfx::Vector2dF(5, 5)); PostSetNeedsCommitToMainThread(); break; case 1: @@ -1414,6 +1495,9 @@ class LayerTreeHostScrollTestLayerStructureChange FakeLayerScrollClient root_scroll_layer_client_; FakeLayerScrollClient sibling_scroll_layer_client_; FakeLayerScrollClient child_scroll_layer_client_; + int root_scroll_layer_id_; + int sibling_scroll_layer_id_; + int child_scroll_layer_id_; FakeContentLayerClient fake_content_layer_client_; @@ -1429,5 +1513,360 @@ TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) { RunTest(CompositorMode::THREADED, false); } +class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { + public: + LayerTreeHostScrollTestScrollMFBA() + : initial_scroll_(10, 20), + second_scroll_(40, 5), + third_scroll_(20, 10), + scroll_amount_(2, -1), + num_commits_(0), + num_scrolls_(0) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->main_frame_before_activation_enabled = true; + } + + void BeginTest() override { + outer_viewport_container_layer_id_ = layer_tree_host() + ->outer_viewport_scroll_layer() + ->scroll_clip_layer() + ->id(); + layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( + initial_scroll_); + PostSetNeedsCommitToMainThread(); + } + + void StartCommitOnImpl() override { + switch (num_commits_) { + case 1: + // Ask for commit here because activation (and draw) will be blocked. + GetProxyImplForTest()->SetNeedsCommitOnImpl(); + // Block activation after second commit until third commit is ready. + GetProxyImplForTest()->BlockNotifyReadyToActivateForTesting(true); + break; + case 2: + // Unblock activation after third commit is ready. + GetProxyImplForTest()->BlockNotifyReadyToActivateForTesting(false); + break; + } + num_commits_++; + } + + void UpdateLayerTreeHost() override { + Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + switch (layer_tree_host()->source_frame_number()) { + case 0: + EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset()); + break; + case 1: + EXPECT_VECTOR_EQ( + gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_), + scroll_layer->scroll_offset()); + // Pretend like Javascript updated the scroll position itself. + scroll_layer->SetScrollOffset(second_scroll_); + break; + case 2: + // Third frame does not see a scroll delta because we only did one + // scroll for the second and third frames. + EXPECT_VECTOR_EQ(second_scroll_, scroll_layer->scroll_offset()); + // Pretend like Javascript updated the scroll position itself. + scroll_layer->SetScrollOffset(third_scroll_); + break; + } + } + + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { + LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + switch (impl->active_tree()->source_frame_number()) { + case 0: + EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); + EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting( + scroll_layer->id())); + Scroll(impl); + EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); + // Ask for commit after we've scrolled. + impl->SetNeedsCommit(); + break; + case 1: + EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); + EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting( + scroll_layer->id())); + Scroll(impl); + EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); + break; + case 2: + // The scroll hasn't been consumed by the main thread. + EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); + EXPECT_VECTOR_EQ(third_scroll_, ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting( + scroll_layer->id())); + EndTest(); + break; + } + } + + 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_++; + } + + void AfterTest() override { + EXPECT_EQ(3, num_commits_); + EXPECT_EQ(1, num_scrolls_); + } + + private: + void Scroll(LayerTreeHostImpl* impl) { + LayerImpl* root = impl->active_tree()->root_layer(); + LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + + scroll_layer->SetScrollClipLayer(outer_viewport_container_layer_id_); + scroll_layer->SetBounds( + gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); + scroll_layer->ScrollBy(scroll_amount_); + } + + gfx::ScrollOffset initial_scroll_; + gfx::ScrollOffset second_scroll_; + gfx::ScrollOffset third_scroll_; + gfx::Vector2dF scroll_amount_; + int num_commits_; + int num_scrolls_; + int outer_viewport_container_layer_id_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMFBA); + +class LayerTreeHostScrollTestScrollAbortedCommitMFBA + : public LayerTreeHostScrollTest { + public: + LayerTreeHostScrollTestScrollAbortedCommitMFBA() + : initial_scroll_(50, 60), + impl_scroll_(-3, 2), + second_main_scroll_(14, -3), + num_will_begin_main_frames_(0), + num_did_begin_main_frames_(0), + num_will_commits_(0), + num_did_commits_(0), + num_impl_commits_(0), + num_aborted_commits_(0), + num_impl_scrolls_(0), + num_draws_(0) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->main_frame_before_activation_enabled = true; + } + + void BeginTest() override { + layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( + initial_scroll_); + PostSetNeedsCommitToMainThread(); + } + + void SetupTree() override { + LayerTreeHostScrollTest::SetupTree(); + + gfx::Size scroll_layer_bounds(200, 200); + layer_tree_host()->outer_viewport_scroll_layer()->SetBounds( + scroll_layer_bounds); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); + } + + void WillBeginMainFrame() override { + num_will_begin_main_frames_++; + Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + switch (num_will_begin_main_frames_) { + case 1: + // This will not be aborted because of the initial prop changes. + EXPECT_EQ(0, num_impl_scrolls_); + EXPECT_EQ(0, layer_tree_host()->source_frame_number()); + EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->scroll_offset()); + break; + case 2: + // This commit will not be aborted because of the scroll change. + EXPECT_EQ(1, num_impl_scrolls_); + EXPECT_EQ(1, layer_tree_host()->source_frame_number()); + EXPECT_VECTOR_EQ( + gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_), + root_scroll_layer->scroll_offset()); + root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta( + root_scroll_layer->scroll_offset(), second_main_scroll_)); + break; + case 3: { + // This commit will be aborted. + EXPECT_EQ(2, num_impl_scrolls_); + // The source frame number still increases even with the abort. + EXPECT_EQ(2, layer_tree_host()->source_frame_number()); + gfx::Vector2dF delta = + impl_scroll_ + impl_scroll_ + second_main_scroll_; + EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta), + root_scroll_layer->scroll_offset()); + break; + } + case 4: { + // This commit will also be aborted. + EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, layer_tree_host()->source_frame_number()); + gfx::Vector2dF delta = + impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; + EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta), + root_scroll_layer->scroll_offset()); + break; + } + } + } + + void DidBeginMainFrame() override { num_did_begin_main_frames_++; } + + void WillCommit() override { num_will_commits_++; } + + void DidCommit() override { num_did_commits_++; } + + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { + switch (num_impl_commits_) { + case 1: + // Redraw so that we keep scrolling. + impl->SetNeedsRedraw(); + // Block activation until third commit is aborted. + impl->BlockNotifyReadyToActivateForTesting(true); + break; + } + num_impl_commits_++; + } + + void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* impl, + CommitEarlyOutReason reason) override { + switch (num_aborted_commits_) { + case 0: + EXPECT_EQ(2, num_impl_commits_); + // Unblock activation when third commit is aborted. + impl->BlockNotifyReadyToActivateForTesting(false); + break; + case 1: + EXPECT_EQ(2, num_impl_commits_); + // Redraw to end the test. + impl->SetNeedsRedraw(); + break; + } + num_aborted_commits_++; + } + + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { + LayerImpl* root_scroll_layer = impl->OuterViewportScrollLayer(); + switch (impl->active_tree()->source_frame_number()) { + case 0: { + switch (num_impl_commits_) { + case 1: { + // First draw + EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer)); + root_scroll_layer->ScrollBy(impl_scroll_); + EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer)); + EXPECT_VECTOR_EQ( + initial_scroll_, + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + impl->SetNeedsCommit(); + break; + } + case 2: { + // Second draw but no new active tree because activation is blocked. + EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer)); + root_scroll_layer->ScrollBy(impl_scroll_); + EXPECT_VECTOR_EQ(impl_scroll_ + impl_scroll_, + ScrollDelta(root_scroll_layer)); + EXPECT_VECTOR_EQ( + initial_scroll_, + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + // Ask for another commit (which will abort). + impl->SetNeedsCommit(); + break; + } + default: + NOTREACHED(); + } + break; + } + case 1: { + EXPECT_EQ(2, num_impl_commits_); + // All scroll deltas so far should be consumed. + EXPECT_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer)); + switch (num_aborted_commits_) { + case 1: { + root_scroll_layer->ScrollBy(impl_scroll_); + EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer)); + gfx::Vector2dF prev_delta = + impl_scroll_ + impl_scroll_ + second_main_scroll_; + EXPECT_VECTOR_EQ( + gfx::ScrollOffsetWithDelta(initial_scroll_, prev_delta), + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + // Ask for another commit (which will abort). + impl->SetNeedsCommit(); + break; + } + case 2: { + gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ + + second_main_scroll_; + EXPECT_VECTOR_EQ( + gfx::ScrollOffsetWithDelta(initial_scroll_, delta), + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + // End test after second aborted commit (fourth commit request). + EndTest(); + break; + } + } + break; + } + } + num_draws_++; + } + + 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_++; + } + + void AfterTest() override { + EXPECT_EQ(3, num_impl_scrolls_); + // Verify that the embedder sees aborted commits as real commits. + EXPECT_EQ(4, num_will_begin_main_frames_); + EXPECT_EQ(4, num_did_begin_main_frames_); + EXPECT_EQ(4, num_will_commits_); + EXPECT_EQ(4, num_did_commits_); + // ...but the compositor thread only sees two real ones. + EXPECT_EQ(2, num_impl_commits_); + // ...and two aborted ones. + EXPECT_EQ(2, num_aborted_commits_); + // ...and four draws. + EXPECT_EQ(4, num_draws_); + } + + private: + gfx::ScrollOffset initial_scroll_; + gfx::Vector2dF impl_scroll_; + gfx::Vector2dF second_main_scroll_; + int num_will_begin_main_frames_; + int num_did_begin_main_frames_; + int num_will_commits_; + int num_did_commits_; + int num_impl_commits_; + int num_aborted_commits_; + int num_impl_scrolls_; + int num_draws_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommitMFBA); + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_serialization.cc b/chromium/cc/trees/layer_tree_host_unittest_serialization.cc index c78700e4e7d..7d989d66fa2 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_serialization.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_serialization.cc @@ -47,12 +47,10 @@ class LayerTreeHostSerializationTest : public testing::Test { void VerifyHostHasAllExpectedLayersInTree(Layer* root_layer) { LayerTreeHostCommon::CallFunctionForEveryLayer( - root_layer->layer_tree_host(), - [root_layer](Layer* layer) { + root_layer->layer_tree_host(), [root_layer](Layer* layer) { DCHECK(layer->layer_tree_host()); EXPECT_EQ(layer, layer->layer_tree_host()->LayerById(layer->id())); - }, - CallFunctionLayerType::ALL_LAYERS); + }); } void VerifySerializationAndDeserialization() { @@ -69,8 +67,6 @@ class LayerTreeHostSerializationTest : public testing::Test { layer_tree_host_dst_->needs_meta_info_recomputation_); EXPECT_EQ(layer_tree_host_src_->source_frame_number_, layer_tree_host_dst_->source_frame_number_); - EXPECT_EQ(layer_tree_host_src_->meta_information_sequence_number_, - layer_tree_host_dst_->meta_information_sequence_number_); EXPECT_EQ(layer_tree_host_src_->root_layer()->id(), layer_tree_host_dst_->root_layer()->id()); EXPECT_EQ(layer_tree_host_dst_.get(), @@ -135,31 +131,31 @@ class LayerTreeHostSerializationTest : public testing::Test { } EXPECT_TRUE(found_hud_layer_type); } else { - EXPECT_EQ(nullptr, layer_tree_host_dst_->hud_layer_); + EXPECT_FALSE(layer_tree_host_dst_->hud_layer_); } if (layer_tree_host_src_->overscroll_elasticity_layer_) { EXPECT_EQ(layer_tree_host_src_->overscroll_elasticity_layer_->id(), layer_tree_host_dst_->overscroll_elasticity_layer_->id()); } else { - EXPECT_EQ(nullptr, layer_tree_host_dst_->overscroll_elasticity_layer_); + EXPECT_FALSE(layer_tree_host_dst_->overscroll_elasticity_layer_); } if (layer_tree_host_src_->page_scale_layer_) { EXPECT_EQ(layer_tree_host_src_->page_scale_layer_->id(), layer_tree_host_dst_->page_scale_layer_->id()); } else { - EXPECT_EQ(nullptr, layer_tree_host_dst_->page_scale_layer_); + EXPECT_FALSE(layer_tree_host_dst_->page_scale_layer_); } if (layer_tree_host_src_->inner_viewport_scroll_layer_) { EXPECT_EQ(layer_tree_host_src_->inner_viewport_scroll_layer_->id(), layer_tree_host_dst_->inner_viewport_scroll_layer_->id()); } else { - EXPECT_EQ(nullptr, layer_tree_host_dst_->inner_viewport_scroll_layer_); + EXPECT_FALSE(layer_tree_host_dst_->inner_viewport_scroll_layer_); } if (layer_tree_host_src_->outer_viewport_scroll_layer_) { EXPECT_EQ(layer_tree_host_src_->outer_viewport_scroll_layer_->id(), layer_tree_host_dst_->outer_viewport_scroll_layer_->id()); } else { - EXPECT_EQ(nullptr, layer_tree_host_dst_->outer_viewport_scroll_layer_); + EXPECT_FALSE(layer_tree_host_dst_->outer_viewport_scroll_layer_); } EXPECT_EQ(layer_tree_host_src_->selection_, layer_tree_host_dst_->selection_); @@ -174,11 +170,9 @@ class LayerTreeHostSerializationTest : public testing::Test { if (layer_tree_host_dst_->property_trees_.sequence_number) { int seq_num = layer_tree_host_dst_->property_trees_.sequence_number; LayerTreeHostCommon::CallFunctionForEveryLayer( - layer_tree_host_dst_.get(), - [seq_num](Layer* layer) { + layer_tree_host_dst_.get(), [seq_num](Layer* layer) { EXPECT_EQ(seq_num, layer->property_tree_sequence_number()); - }, - CallFunctionLayerType::ALL_LAYERS); + }); } } @@ -188,7 +182,6 @@ class LayerTreeHostSerializationTest : public testing::Test { layer_tree_host_src_->needs_meta_info_recomputation_ = !layer_tree_host_src_->needs_meta_info_recomputation_; layer_tree_host_src_->source_frame_number_ *= 3; - layer_tree_host_src_->meta_information_sequence_number_ *= 3; // Just fake setup a layer for both source and dest. scoped_refptr<Layer> root_layer_src = Layer::Create(); @@ -353,11 +346,11 @@ class LayerTreeHostSerializationTest : public testing::Test { private: TestTaskGraphRunner task_graph_runner_src_; FakeLayerTreeHostClient client_src_; - scoped_ptr<LayerTreeHost> layer_tree_host_src_; + std::unique_ptr<LayerTreeHost> layer_tree_host_src_; TestTaskGraphRunner task_graph_runner_dst_; FakeLayerTreeHostClient client_dst_; - scoped_ptr<LayerTreeHost> layer_tree_host_dst_; + std::unique_ptr<LayerTreeHost> layer_tree_host_dst_; }; TEST_F(LayerTreeHostSerializationTest, AllMembersChanged) { diff --git a/chromium/cc/trees/layer_tree_host_unittest_video.cc b/chromium/cc/trees/layer_tree_host_unittest_video.cc index 269ee8f69ef..24cbd363763 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_video.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_video.cc @@ -32,6 +32,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay video->SetBounds(gfx::Size(4, 5)); video->SetIsDrawable(true); root->AddChild(video); + video_layer_id_ = video->id(); layer_tree_host()->SetRootLayer(root); layer_tree_host()->SetDeviceScaleFactor(2.f); @@ -69,7 +70,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { VideoLayerImpl* video = static_cast<VideoLayerImpl*>( - host_impl->active_tree()->root_layer()->children()[0]); + host_impl->active_tree()->LayerById(video_layer_id_)); EXPECT_EQ(media::VIDEO_ROTATION_90, video->video_rotation()); @@ -83,6 +84,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay private: int num_draws_; + int video_layer_id_; FakeVideoFrameProvider video_frame_provider_; }; diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index aeca3f8de5f..4248cccc9a7 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -78,7 +78,6 @@ LayerTreeImpl::LayerTreeImpl( needs_full_tree_sync_(true), next_activation_forces_redraw_(false), has_ever_been_drawn_(false), - render_surface_layer_list_id_(0), have_scroll_event_handlers_(false), event_listener_properties_(), top_controls_shrink_blink_size_(false), @@ -106,35 +105,17 @@ void LayerTreeImpl::Shutdown() { void LayerTreeImpl::ReleaseResources() { if (root_layer_) { LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->ReleaseResources(); }, - CallFunctionLayerType::ALL_LAYERS); + this, [](LayerImpl* layer) { layer->ReleaseResources(); }); } } void LayerTreeImpl::RecreateResources() { if (root_layer_) { LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->RecreateResources(); }, - CallFunctionLayerType::ALL_LAYERS); + this, [](LayerImpl* layer) { layer->RecreateResources(); }); } } -void LayerTreeImpl::GatherFrameTimingRequestIds( - std::vector<int64_t>* request_ids) { - if (!root_layer_) - return; - - // TODO(vmpstr): Early out if there are no requests on any of the layers. For - // that, we need to inform LayerTreeImpl whenever there are requests when we - // get them. - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, - [request_ids](LayerImpl* layer) { - layer->GatherFrameTimingRequestIds(request_ids); - }, - CallFunctionLayerType::ALL_LAYERS); -} - bool LayerTreeImpl::IsViewportLayerId(int id) const { if (id == inner_viewport_scroll_layer_id_ || id == outer_viewport_scroll_layer_id_) @@ -275,7 +256,7 @@ void LayerTreeImpl::UpdateScrollbars(int scroll_layer_id, int clip_layer_id) { } } -void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) { +void LayerTreeImpl::SetRootLayer(std::unique_ptr<LayerImpl> layer) { if (root_layer_ && layer.get() != root_layer_) RemoveLayer(root_layer_->id()); root_layer_ = layer.get(); @@ -320,11 +301,11 @@ gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const { return offset; } -scoped_ptr<OwnedLayerImplList> LayerTreeImpl::DetachLayers() { +std::unique_ptr<OwnedLayerImplList> LayerTreeImpl::DetachLayers() { root_layer_ = nullptr; render_surface_layer_list_.clear(); set_needs_update_draw_properties(); - scoped_ptr<OwnedLayerImplList> ret = std::move(layers_); + std::unique_ptr<OwnedLayerImplList> ret = std::move(layers_); layers_.reset(new OwnedLayerImplList); return ret; } @@ -441,20 +422,30 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->has_ever_been_drawn_ = false; } -LayerListIterator LayerTreeImpl::begin() { - return LayerListIterator(root_layer_); +void LayerTreeImpl::MoveChangeTrackingToLayers() { + // We need to update the change tracking on property trees before we move it + // onto the layers. + property_trees_.UpdateChangeTracking(); + for (auto* layer : *this) { + if (layer->LayerPropertyChanged()) + layer->NoteLayerPropertyChanged(); + } } -LayerListIterator LayerTreeImpl::end() { - return LayerListIterator(nullptr); +LayerListIterator<LayerImpl> LayerTreeImpl::begin() { + return LayerListIterator<LayerImpl>(root_layer_); } -LayerListReverseIterator LayerTreeImpl::rbegin() { - return LayerListReverseIterator(root_layer_); +LayerListIterator<LayerImpl> LayerTreeImpl::end() { + return LayerListIterator<LayerImpl>(nullptr); } -LayerListReverseIterator LayerTreeImpl::rend() { - return LayerListReverseIterator(nullptr); +LayerListReverseIterator<LayerImpl> LayerTreeImpl::rbegin() { + return LayerListReverseIterator<LayerImpl>(root_layer_); +} + +LayerListReverseIterator<LayerImpl> LayerTreeImpl::rend() { + return LayerListReverseIterator<LayerImpl>(nullptr); } void LayerTreeImpl::AddToElementMap(LayerImpl* layer) { @@ -493,6 +484,10 @@ void LayerTreeImpl::RemoveFromElementMap(LayerImpl* layer) { element_layers_map_.erase(layer->element_id()); } +void LayerTreeImpl::AddToOpacityAnimationsMap(int id, float opacity) { + opacity_animations_map_[id] = opacity; +} + LayerTreeImpl::ElementLayers LayerTreeImpl::GetMutableLayers( uint64_t element_id) { auto iter = element_layers_map_.find(element_id); @@ -571,12 +566,21 @@ void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() { // frame to a newly-committed property tree. if (!root_layer()) return; - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, - [](LayerImpl* layer) { - layer->UpdatePropertyTreeForScrollingAndAnimationIfNeeded(); - }, - CallFunctionLayerType::ALL_LAYERS); + for (auto& layer_id_to_opacity : opacity_animations_map_) { + if (LayerImpl* layer = LayerById(layer_id_to_opacity.first)) { + EffectNode* node = + property_trees_.effect_tree.Node(layer->effect_tree_index()); + if (node->owner_id != layer->id() || + !node->data.is_currently_animating_opacity) + continue; + node->data.opacity = layer_id_to_opacity.second; + property_trees_.effect_tree.set_needs_update(true); + } + } + opacity_animations_map_.clear(); + LayerTreeHostCommon::CallFunctionForEveryLayer(this, [](LayerImpl* layer) { + layer->UpdatePropertyTreeForScrollingAndAnimationIfNeeded(); + }); } void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) { @@ -826,10 +830,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { "cc", "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties", "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_); bool can_render_to_separate_surface = - (layer_tree_host_impl_->GetDrawMode() != - DRAW_MODE_RESOURCELESS_SOFTWARE); - - ++render_surface_layer_list_id_; + (!is_in_resourceless_software_draw_mode()); LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( root_layer(), DrawViewportSize(), @@ -841,7 +842,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { settings().can_use_lcd_text, settings().layers_always_allowed_lcd_text, can_render_to_separate_surface, settings().layer_transforms_should_scale_layer_contents, - &render_surface_layer_list_, render_surface_layer_list_id_, + settings().verify_clip_tree_calculations, &render_surface_layer_list_, &property_trees_); LayerTreeHostCommon::CalculateDrawProperties(&inputs); if (const char* client_name = GetClientNameForMetrics()) { @@ -850,6 +851,9 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { "Compositing.%s.LayerTreeImpl.CalculateDrawPropertiesUs", client_name), timer.Elapsed().InMicroseconds()); + UMA_HISTOGRAM_COUNTS_100( + base::StringPrintf("Compositing.%s.NumRenderSurfaces", client_name), + base::saturated_cast<int>(render_surface_layer_list_.size())); } } @@ -870,7 +874,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { it != end; ++it) { occlusion_tracker.EnterLayer(it); - bool inside_replica = it->render_target()->InsideReplica(); + bool inside_replica = it->InsideReplica(); // Don't use occlusion if a layer will appear in a replica, since the // tile raster code does not know how to look for the replica and would @@ -916,7 +920,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { } unoccluded_screen_space_region_ = - occlusion_tracker.ComputeVisibleRegionInScreen(); + occlusion_tracker.ComputeVisibleRegionInScreen(this); } // It'd be ideal if this could be done earlier, but when the raster source @@ -939,14 +943,14 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { // Resourceless draw do not need tiles and should not affect existing tile // priorities. - if (layer_tree_host_impl_->GetDrawMode() != DRAW_MODE_RESOURCELESS_SOFTWARE) { + if (!is_in_resourceless_software_draw_mode()) { TRACE_EVENT_BEGIN2("cc", "LayerTreeImpl::UpdateDrawProperties::UpdateTiles", "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_); size_t layers_updated_count = 0; bool tile_priorities_updated = false; for (PictureLayerImpl* layer : picture_layers_) { - if (!layer->IsDrawnRenderSurfaceLayerListMember()) + if (!layer->is_drawn_render_surface_layer_list_member()) continue; ++layers_updated_count; tile_priorities_updated |= layer->UpdateTiles(); @@ -965,7 +969,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { } void LayerTreeImpl::BuildPropertyTreesForTesting() { - LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer_); + PropertyTreeBuilder::PreCalculateMetaInformationForTesting(root_layer_); property_trees_.transform_tree.set_source_to_parent_updates_allowed(true); PropertyTreeBuilder::BuildPropertyTrees( root_layer_, PageScaleLayer(), InnerViewportScrollLayer(), @@ -977,10 +981,6 @@ void LayerTreeImpl::BuildPropertyTreesForTesting() { property_trees_.transform_tree.set_source_to_parent_updates_allowed(false); } -void LayerTreeImpl::IncrementRenderSurfaceListIdForTesting() { - render_surface_layer_list_id_++; -} - const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const { // If this assert triggers, then the list is dirty. DCHECK(!needs_update_draw_properties_); @@ -1035,34 +1035,34 @@ bool LayerTreeImpl::LayerNeedsPushPropertiesForTesting(LayerImpl* layer) { void LayerTreeImpl::RegisterLayer(LayerImpl* layer) { DCHECK(!LayerById(layer->id())); layer_id_map_[layer->id()] = layer; - layer_tree_host_impl_->animation_host()->RegisterLayer( + layer_tree_host_impl_->animation_host()->RegisterElement( layer->id(), - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING); + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING); } void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) { DCHECK(LayerById(layer->id())); - layer_tree_host_impl_->animation_host()->UnregisterLayer( + layer_tree_host_impl_->animation_host()->UnregisterElement( layer->id(), - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING); + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING); layer_id_map_.erase(layer->id()); DCHECK_NE(root_layer_, layer); } // These manage ownership of the LayerImpl. -void LayerTreeImpl::AddLayer(scoped_ptr<LayerImpl> layer) { +void LayerTreeImpl::AddLayer(std::unique_ptr<LayerImpl> layer) { DCHECK(std::find(layers_->begin(), layers_->end(), layer) == layers_->end()); layers_->push_back(std::move(layer)); set_needs_update_draw_properties(); } -scoped_ptr<LayerImpl> LayerTreeImpl::RemoveLayer(int id) { +std::unique_ptr<LayerImpl> LayerTreeImpl::RemoveLayer(int id) { if (root_layer_ && root_layer_->id() == id) root_layer_ = nullptr; for (auto it = layers_->begin(); it != layers_->end(); ++it) { if ((*it) && (*it)->id() != id) continue; - scoped_ptr<LayerImpl> ret = std::move(*it); + std::unique_ptr<LayerImpl> ret = std::move(*it); set_needs_update_draw_properties(); layers_->erase(it); return ret; @@ -1086,8 +1086,7 @@ void LayerTreeImpl::DidBecomeActive() { if (root_layer()) { LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->DidBecomeActive(); }, - CallFunctionLayerType::ALL_LAYERS); + this, [](LayerImpl* layer) { layer->DidBecomeActive(); }); } for (const auto& swap_promise : swap_promise_list_) @@ -1220,7 +1219,7 @@ const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const { return layer_tree_host_impl_->ViewportRectForTilePriority(); } -scoped_ptr<ScrollbarAnimationController> +std::unique_ptr<ScrollbarAnimationController> LayerTreeImpl::CreateScrollbarAnimationController(int scroll_layer_id) { DCHECK(settings().scrollbar_fade_delay_ms); DCHECK(settings().scrollbar_fade_duration_ms); @@ -1341,20 +1340,21 @@ bool LayerTreeImpl::DistributeRootScrollOffset( return true; } -void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) { +void LayerTreeImpl::QueueSwapPromise( + std::unique_ptr<SwapPromise> swap_promise) { DCHECK(swap_promise); swap_promise_list_.push_back(std::move(swap_promise)); } void LayerTreeImpl::QueuePinnedSwapPromise( - scoped_ptr<SwapPromise> swap_promise) { + std::unique_ptr<SwapPromise> swap_promise) { DCHECK(IsActiveTree()); DCHECK(swap_promise); pinned_swap_promise_list_.push_back(std::move(swap_promise)); } void LayerTreeImpl::PassSwapPromises( - std::vector<scoped_ptr<SwapPromise>>* new_swap_promise) { + std::vector<std::unique_ptr<SwapPromise>>* new_swap_promise) { for (const auto& swap_promise : swap_promise_list_) swap_promise->DidNotSwap(SwapPromise::SWAP_FAILS); swap_promise_list_.clear(); @@ -1396,10 +1396,6 @@ bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const { return layer_tree_host_impl_->IsUIResourceOpaque(uid); } -bool LayerTreeImpl::OutputIsSecure() const { - return layer_tree_host_impl_->output_is_secure(); -} - void LayerTreeImpl::ProcessUIResourceRequestQueue() { for (const auto& req : ui_resource_request_queue_) { switch (req.GetType()) { @@ -1623,7 +1619,7 @@ static const gfx::Transform SurfaceScreenSpaceTransform( const LayerImpl* layer, const TransformTree& transform_tree) { DCHECK(layer->render_surface()); - return layer->IsDrawnRenderSurfaceLayerListMember() + return layer->is_drawn_render_surface_layer_list_member() ? layer->render_surface()->screen_space_transform() : transform_tree.ToScreenSpaceTransformWithoutSublayerScale( layer->render_surface()->TransformTreeIndex()); @@ -1657,9 +1653,20 @@ static bool PointIsClippedByAncestorClipNode( gfx::Rect combined_clip_in_target_space = gfx::ToEnclosingRect(clip_node->data.combined_clip_in_target_space); - if (!PointHitsRect(screen_space_point, transform_node->data.to_screen, - combined_clip_in_target_space, NULL)) + const LayerImpl* target_layer = + layer->layer_tree_impl()->LayerById(transform_node->owner_id); + DCHECK(transform_node->id == 0 || target_layer->render_surface() || + layer->layer_tree_impl()->is_in_resourceless_software_draw_mode()); + gfx::Transform surface_screen_space_transform = + transform_node->id == 0 || + (layer->layer_tree_impl() + ->is_in_resourceless_software_draw_mode()) + ? gfx::Transform() + : SurfaceScreenSpaceTransform(target_layer, transform_tree); + if (!PointHitsRect(screen_space_point, surface_screen_space_transform, + combined_clip_in_target_space, NULL)) { return true; + } } const LayerImpl* clip_node_owner = layer->layer_tree_impl()->LayerById(clip_node->owner_id); @@ -1692,8 +1699,9 @@ static bool PointHitsLayer(const LayerImpl* layer, const ClipTree& clip_tree) { gfx::Rect content_rect(layer->bounds()); if (!PointHitsRect(screen_space_point, layer->ScreenSpaceTransform(), - content_rect, distance_to_intersection)) + content_rect, distance_to_intersection)) { return false; + } // At this point, we think the point does hit the layer, but we need to walk // up the parents to ensure that the layer was not clipped in such a way @@ -1757,42 +1765,34 @@ static void FindClosestMatchingLayer(const gfx::PointF& screen_space_point, } } -static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) { - if (!layer->scrollable()) - return false; - if (layer->layer_or_descendant_is_drawn()) - return true; - - if (!layer->scroll_children()) - return false; - for (std::set<LayerImpl*>::const_iterator it = - layer->scroll_children()->begin(); - it != layer->scroll_children()->end(); ++it) { - if ((*it)->layer_or_descendant_is_drawn()) - return true; - } - return false; +static bool ScrollsOrScrollbarAnyDrawnRenderSurfaceLayerListMember( + LayerImpl* layer) { + return layer->scrolls_drawn_descendant() || + (layer->ToScrollbarLayer() && + layer->is_drawn_render_surface_layer_list_member()); } -struct FindScrollingLayerFunctor { +struct FindScrollingLayerOrScrollbarLayerFunctor { bool operator()(LayerImpl* layer) const { - return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer); + return ScrollsOrScrollbarAnyDrawnRenderSurfaceLayerListMember(layer); } }; -LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint( +LayerImpl* +LayerTreeImpl::FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( const gfx::PointF& screen_space_point) { FindClosestMatchingLayerState state; - FindClosestMatchingLayer( - screen_space_point, root_layer(), FindScrollingLayerFunctor(), - property_trees_.transform_tree, property_trees_.clip_tree, &state); + FindClosestMatchingLayer(screen_space_point, root_layer(), + FindScrollingLayerOrScrollbarLayerFunctor(), + property_trees_.transform_tree, + property_trees_.clip_tree, &state); return state.closest_match; } struct HitTestVisibleScrollableOrTouchableFunctor { bool operator()(LayerImpl* layer) const { - return layer->IsDrawnRenderSurfaceLayerListMember() || - ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) || + return layer->is_drawn_render_surface_layer_list_member() || + ScrollsOrScrollbarAnyDrawnRenderSurfaceLayerListMember(layer) || !layer->touch_event_handler_region().IsEmpty(); } }; @@ -1950,59 +1950,67 @@ VideoFrameControllerClient* LayerTreeImpl::GetVideoFrameControllerClient() return layer_tree_host_impl_; } +void LayerTreeImpl::SetFixedRasterScaleHasBlurryContent() { + layer_tree_host_impl_->set_fixed_raster_scale_has_blurry_content(); +} + +void LayerTreeImpl::SetFixedRasterScaleAttemptedToChangeScale() { + layer_tree_host_impl_->SetFixedRasterScaleAttemptedToChangeScale(); +} + void LayerTreeImpl::SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation> pending_animation) { + std::unique_ptr<PendingPageScaleAnimation> pending_animation) { pending_page_scale_animation_ = std::move(pending_animation); } -scoped_ptr<PendingPageScaleAnimation> +std::unique_ptr<PendingPageScaleAnimation> LayerTreeImpl::TakePendingPageScaleAnimation() { return std::move(pending_page_scale_animation_); } bool LayerTreeImpl::IsAnimatingFilterProperty(const LayerImpl* layer) const { - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host()->IsAnimatingFilterProperty( - layer->id(), tree_type); + layer->id(), list_type); } bool LayerTreeImpl::IsAnimatingOpacityProperty(const LayerImpl* layer) const { - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host()->IsAnimatingOpacityProperty( - layer->id(), tree_type); + layer->id(), list_type); } bool LayerTreeImpl::IsAnimatingTransformProperty(const LayerImpl* layer) const { - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host()->IsAnimatingTransformProperty( - layer->id(), tree_type); + layer->id(), list_type); } bool LayerTreeImpl::HasPotentiallyRunningFilterAnimation( const LayerImpl* layer) const { - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host() - ->HasPotentiallyRunningFilterAnimation(layer->id(), tree_type); + ->HasPotentiallyRunningFilterAnimation(layer->id(), list_type); } bool LayerTreeImpl::HasPotentiallyRunningOpacityAnimation( const LayerImpl* layer) const { - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host() - ->HasPotentiallyRunningOpacityAnimation(layer->id(), tree_type); + ->HasPotentiallyRunningOpacityAnimation(layer->id(), list_type); } bool LayerTreeImpl::HasPotentiallyRunningTransformAnimation( const LayerImpl* layer) const { - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host() - ->HasPotentiallyRunningTransformAnimation(layer->id(), tree_type); + ->HasPotentiallyRunningTransformAnimation(layer->id(), list_type); } bool LayerTreeImpl::HasAnyAnimationTargetingProperty( @@ -2012,28 +2020,12 @@ bool LayerTreeImpl::HasAnyAnimationTargetingProperty( ->HasAnyAnimationTargetingProperty(layer->id(), property); } -bool LayerTreeImpl::FilterIsAnimatingOnImplOnly(const LayerImpl* layer) const { - return layer_tree_host_impl_->animation_host()->FilterIsAnimatingOnImplOnly( - layer->id()); -} - -bool LayerTreeImpl::OpacityIsAnimatingOnImplOnly(const LayerImpl* layer) const { - return layer_tree_host_impl_->animation_host()->OpacityIsAnimatingOnImplOnly( - layer->id()); -} - bool LayerTreeImpl::ScrollOffsetIsAnimatingOnImplOnly( const LayerImpl* layer) const { return layer_tree_host_impl_->animation_host() ->ScrollOffsetIsAnimatingOnImplOnly(layer->id()); } -bool LayerTreeImpl::TransformIsAnimatingOnImplOnly( - const LayerImpl* layer) const { - return layer_tree_host_impl_->animation_host() - ->TransformIsAnimatingOnImplOnly(layer->id()); -} - bool LayerTreeImpl::AnimationsPreserveAxisAlignment( const LayerImpl* layer) const { return layer_tree_host_impl_->animation_host() @@ -2041,28 +2033,28 @@ bool LayerTreeImpl::AnimationsPreserveAxisAlignment( } bool LayerTreeImpl::HasOnlyTranslationTransforms(const LayerImpl* layer) const { - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host()->HasOnlyTranslationTransforms( - layer->id(), tree_type); + layer->id(), list_type); } bool LayerTreeImpl::MaximumTargetScale(const LayerImpl* layer, float* max_scale) const { *max_scale = 0.f; - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host()->MaximumTargetScale( - layer->id(), tree_type, max_scale); + layer->id(), list_type, max_scale); } bool LayerTreeImpl::AnimationStartScale(const LayerImpl* layer, float* start_scale) const { *start_scale = 0.f; - LayerTreeType tree_type = - IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING; + ElementListType list_type = + IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING; return layer_tree_host_impl_->animation_host()->AnimationStartScale( - layer->id(), tree_type, start_scale); + layer->id(), list_type, start_scale); } bool LayerTreeImpl::HasFilterAnimationThatInflatesBounds( @@ -2103,11 +2095,11 @@ void LayerTreeImpl::ScrollAnimationAbort(bool needs_completion) { needs_completion); } -void LayerTreeImpl::ResetAllChangeTracking(PropertyTrees::ResetFlags flag) { +void LayerTreeImpl::ResetAllChangeTracking() { layers_that_should_push_properties_.clear(); for (auto* layer : *this) layer->ResetChangeTracking(); - property_trees_.ResetAllChangeTracking(flag); + property_trees_.ResetAllChangeTracking(); } } // namespace cc diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index 8bda30b4b01..f67d934ef9e 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -12,6 +12,7 @@ #include <vector> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/values.h" #include "cc/base/synced_property.h" #include "cc/input/event_listener_properties.h" @@ -64,12 +65,12 @@ class CC_EXPORT LayerTreeImpl { // This is the number of times a fixed point has to be hit contiuously by a // layer to consider it as jittering. const int kFixedPointHitsThreshold = 3; - static scoped_ptr<LayerTreeImpl> create( + static std::unique_ptr<LayerTreeImpl> create( LayerTreeHostImpl* layer_tree_host_impl, scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, scoped_refptr<SyncedTopControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll) { - return make_scoped_ptr( + return base::WrapUnique( new LayerTreeImpl(layer_tree_host_impl, page_scale_factor, top_controls_shown_ratio, elastic_overscroll)); } @@ -105,8 +106,8 @@ class CC_EXPORT LayerTreeImpl { gfx::Rect DeviceViewport() const; gfx::Size DrawViewportSize() const; const gfx::Rect ViewportRectForTilePriority() const; - scoped_ptr<ScrollbarAnimationController> CreateScrollbarAnimationController( - int scroll_layer_id); + std::unique_ptr<ScrollbarAnimationController> + CreateScrollbarAnimationController(int scroll_layer_id); void DidAnimateScrollOffset(); bool use_gpu_rasterization() const; GpuRasterizationStatus GetGpuRasterizationStatus() const; @@ -117,6 +118,8 @@ class CC_EXPORT LayerTreeImpl { AnimationHost* animation_host() const { return layer_tree_host_impl_->animation_host(); } + void SetFixedRasterScaleHasBlurryContent(); + void SetFixedRasterScaleAttemptedToChangeScale(); // Tree specific methods exposed to layer-impl tree. // --------------------------------------------------------------------------- @@ -131,9 +134,9 @@ class CC_EXPORT LayerTreeImpl { // Other public methods // --------------------------------------------------------------------------- LayerImpl* root_layer() const { return root_layer_; } - void SetRootLayer(scoped_ptr<LayerImpl>); + void SetRootLayer(std::unique_ptr<LayerImpl>); bool IsRootLayer(const LayerImpl* layer) const; - scoped_ptr<OwnedLayerImplList> DetachLayers(); + std::unique_ptr<OwnedLayerImplList> DetachLayers(); void ClearLayers(); void SetPropertyTrees(const PropertyTrees property_trees) { @@ -141,6 +144,11 @@ class CC_EXPORT LayerTreeImpl { property_trees_.is_main_thread = false; property_trees_.is_active = IsActiveTree(); property_trees_.transform_tree.set_source_to_parent_updates_allowed(false); + // The value of some effect node properties (like is_drawn) depends on + // whether we are on the active tree or not. So, we need to update the + // effect tree. + if (IsActiveTree()) + property_trees_.effect_tree.set_needs_update(true); } PropertyTrees* property_trees() { return &property_trees_; } @@ -148,14 +156,14 @@ class CC_EXPORT LayerTreeImpl { void PushPropertiesTo(LayerTreeImpl* tree_impl); - LayerListIterator begin(); - LayerListIterator end(); - LayerListReverseIterator rbegin(); - LayerListReverseIterator rend(); + void MoveChangeTrackingToLayers(); - // TODO(thakis): Consider marking this CC_EXPORT once we understand - // http://crbug.com/575700 better. - struct ElementLayers { + LayerListIterator<LayerImpl> begin(); + LayerListIterator<LayerImpl> end(); + LayerListReverseIterator<LayerImpl> rbegin(); + LayerListReverseIterator<LayerImpl> rend(); + + struct CC_EXPORT ElementLayers { // Transform and opacity mutations apply to this layer. LayerImpl* main = nullptr; // Scroll mutations apply to this layer. @@ -164,6 +172,9 @@ class CC_EXPORT LayerTreeImpl { void AddToElementMap(LayerImpl* layer); void RemoveFromElementMap(LayerImpl* layer); + + void AddToOpacityAnimationsMap(int id, float opacity); + ElementLayers GetMutableLayers(uint64_t element_id); int source_frame_number() const { return source_frame_number_; } void set_source_frame_number(int frame_number) { @@ -267,7 +278,6 @@ class CC_EXPORT LayerTreeImpl { // text may cause invalidations, so should only be done after a commit. bool UpdateDrawProperties(bool update_lcd_text); void BuildPropertyTreesForTesting(); - void IncrementRenderSurfaceListIdForTesting(); void set_needs_update_draw_properties() { needs_update_draw_properties_ = true; @@ -276,6 +286,11 @@ class CC_EXPORT LayerTreeImpl { return needs_update_draw_properties_; } + bool is_in_resourceless_software_draw_mode() { + return (layer_tree_host_impl_->GetDrawMode() == + DRAW_MODE_RESOURCELESS_SOFTWARE); + } + void set_needs_full_tree_sync(bool needs) { needs_full_tree_sync_ = needs; } bool needs_full_tree_sync() const { return needs_full_tree_sync_; } @@ -310,8 +325,8 @@ class CC_EXPORT LayerTreeImpl { void UnregisterLayer(LayerImpl* layer); // These manage ownership of the LayerImpl. - void AddLayer(scoped_ptr<LayerImpl> layer); - scoped_ptr<LayerImpl> RemoveLayer(int id); + void AddLayer(std::unique_ptr<LayerImpl> layer); + std::unique_ptr<LayerImpl> RemoveLayer(int id); size_t NumLayers(); @@ -343,7 +358,7 @@ class CC_EXPORT LayerTreeImpl { // active tree along with the layer information. Similarly, when a // new activation overwrites layer information on the active tree, // queued swap promises are broken. - void QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise); + void QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise); // Queue a swap promise, pinned to this tree. Pinned swap promises // may only be queued on the active tree. @@ -354,10 +369,11 @@ class CC_EXPORT LayerTreeImpl { // // Pinned active tree swap promises will not be broken prematurely // on the active tree if a new tree is activated. - void QueuePinnedSwapPromise(scoped_ptr<SwapPromise> swap_promise); + void QueuePinnedSwapPromise(std::unique_ptr<SwapPromise> swap_promise); // Take the |new_swap_promise| and append it to |swap_promise_list_|. - void PassSwapPromises(std::vector<scoped_ptr<SwapPromise>>* new_swap_promise); + void PassSwapPromises( + std::vector<std::unique_ptr<SwapPromise>>* new_swap_promise); void FinishSwapPromises(CompositorFrameMetadata* metadata); void BreakSwapPromises(SwapPromise::DidNotSwapReason reason); @@ -368,8 +384,6 @@ class CC_EXPORT LayerTreeImpl { bool IsUIResourceOpaque(UIResourceId uid) const; - bool OutputIsSecure() const; - void RegisterPictureLayerImpl(PictureLayerImpl* layer); void UnregisterPictureLayerImpl(PictureLayerImpl* layer); const std::vector<PictureLayerImpl*>& picture_layers() const { @@ -393,11 +407,7 @@ class CC_EXPORT LayerTreeImpl { return surface_layers_; } - int current_render_surface_list_id() const { - return render_surface_layer_list_id_; - } - - LayerImpl* FindFirstScrollingLayerThatIsHitByPoint( + LayerImpl* FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( const gfx::PointF& screen_space_point); LayerImpl* FindLayerThatIsHitByPoint(const gfx::PointF& screen_space_point); @@ -424,10 +434,8 @@ class CC_EXPORT LayerTreeImpl { void PushTopControlsFromMainThread(float top_controls_shown_ratio); void SetPendingPageScaleAnimation( - scoped_ptr<PendingPageScaleAnimation> pending_animation); - scoped_ptr<PendingPageScaleAnimation> TakePendingPageScaleAnimation(); - - void GatherFrameTimingRequestIds(std::vector<int64_t>* request_ids); + std::unique_ptr<PendingPageScaleAnimation> pending_animation); + std::unique_ptr<PendingPageScaleAnimation> TakePendingPageScaleAnimation(); void DidUpdateScrollOffset(int layer_id, int transform_id); void DidUpdateScrollState(int layer_id); @@ -443,10 +451,7 @@ class CC_EXPORT LayerTreeImpl { bool HasAnyAnimationTargetingProperty(const LayerImpl* layer, TargetProperty::Type property) const; - bool FilterIsAnimatingOnImplOnly(const LayerImpl* layer) const; - bool OpacityIsAnimatingOnImplOnly(const LayerImpl* layer) const; bool ScrollOffsetIsAnimatingOnImplOnly(const LayerImpl* layer) const; - bool TransformIsAnimatingOnImplOnly(const LayerImpl* layer) const; bool AnimationsPreserveAxisAlignment(const LayerImpl* layer) const; bool HasOnlyTranslationTransforms(const LayerImpl* layer) const; @@ -483,7 +488,7 @@ class CC_EXPORT LayerTreeImpl { event_properties; } - void ResetAllChangeTracking(PropertyTrees::ResetFlags flag); + void ResetAllChangeTracking(); protected: explicit LayerTreeImpl( @@ -527,13 +532,15 @@ class CC_EXPORT LayerTreeImpl { scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_; - scoped_ptr<OwnedLayerImplList> layers_; + std::unique_ptr<OwnedLayerImplList> layers_; LayerImplMap layer_id_map_; // Set of layers that need to push properties. std::unordered_set<LayerImpl*> layers_that_should_push_properties_; std::unordered_map<uint64_t, ElementLayers> element_layers_map_; + std::unordered_map<int, float> opacity_animations_map_; + // Maps from clip layer ids to scroll layer ids. Note that this only includes // the subset of clip layers that act as scrolling containers. (This is // derived from LayerImpl::scroll_clip_layer_ and exists to avoid O(n) walks.) @@ -566,13 +573,11 @@ class CC_EXPORT LayerTreeImpl { bool has_ever_been_drawn_; - std::vector<scoped_ptr<SwapPromise>> swap_promise_list_; - std::vector<scoped_ptr<SwapPromise>> pinned_swap_promise_list_; + std::vector<std::unique_ptr<SwapPromise>> swap_promise_list_; + std::vector<std::unique_ptr<SwapPromise>> pinned_swap_promise_list_; UIResourceRequestQueue ui_resource_request_queue_; - int render_surface_layer_list_id_; - bool have_scroll_event_handlers_; EventListenerProperties event_listener_properties_[static_cast<size_t>( EventListenerClass::kNumClasses)]; @@ -586,7 +591,7 @@ class CC_EXPORT LayerTreeImpl { // shown). scoped_refptr<SyncedTopControls> top_controls_shown_ratio_; - scoped_ptr<PendingPageScaleAnimation> pending_page_scale_animation_; + std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_; private: DISALLOW_COPY_AND_ASSIGN(LayerTreeImpl); diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 8781d2fc702..c6afcee459f 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -26,6 +26,7 @@ class LayerTreeImplTest : public LayerTreeHostCommonTest { LayerTreeImplTest() : output_surface_(FakeOutputSurface::Create3d()) { LayerTreeSettings settings; settings.layer_transforms_should_scale_layer_contents = true; + settings.verify_clip_tree_calculations = true; host_impl_.reset(new FakeLayerTreeHostImpl(settings, &task_runner_provider_, &shared_bitmap_manager_, &task_graph_runner_)); @@ -54,12 +55,12 @@ class LayerTreeImplTest : public LayerTreeHostCommonTest { TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeImplTaskRunnerProvider task_runner_provider_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<FakeLayerTreeHostImpl> host_impl_; + std::unique_ptr<OutputSurface> output_surface_; + std::unique_ptr<FakeLayerTreeHostImpl> host_impl_; }; TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform identity_matrix; @@ -109,14 +110,15 @@ TEST_F(LayerTreeImplTest, UpdateViewportAndHitTest) { TestTaskGraphRunner task_graph_runner; FakeImplTaskRunnerProvider task_runner_provider; LayerTreeSettings settings; - scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); - scoped_ptr<FakeLayerTreeHostImpl> host_impl; + settings.verify_clip_tree_calculations = true; + std::unique_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(); + std::unique_ptr<FakeLayerTreeHostImpl> host_impl; host_impl.reset(new FakeLayerTreeHostImpl(settings, &task_runner_provider, &shared_bitmap_manager, &task_graph_runner)); host_impl->SetVisible(true); EXPECT_TRUE(host_impl->InitializeRenderer(output_surface.get())); - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl->active_tree(), 12345); gfx::Transform identity_matrix; @@ -147,9 +149,9 @@ TEST_F(LayerTreeImplTest, UpdateViewportAndHitTest) { } TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); - scoped_ptr<HeadsUpDisplayLayerImpl> hud = + std::unique_ptr<HeadsUpDisplayLayerImpl> hud = HeadsUpDisplayLayerImpl::Create(host_impl().active_tree(), 11111); gfx::Transform identity_matrix; @@ -204,7 +206,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) { } TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform uninvertible_transform; @@ -271,7 +273,7 @@ TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) { } TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform identity_matrix; @@ -320,7 +322,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) { } TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform identity_matrix; @@ -381,13 +383,14 @@ TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) { // Tests hit testing on a layer whose clip node has different transform and // target id. gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(500, 500), true, false, true); gfx::Transform translation; translation.Translate(100, 100); - scoped_ptr<LayerImpl> render_surface = + std::unique_ptr<LayerImpl> render_surface = LayerImpl::Create(host_impl().active_tree(), 2); SetLayerPropertiesForTesting(render_surface.get(), translation, gfx::Point3F(), gfx::PointF(), @@ -395,18 +398,21 @@ TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) { gfx::Transform scale_matrix; scale_matrix.Scale(2, 2); - scoped_ptr<LayerImpl> scale = LayerImpl::Create(host_impl().active_tree(), 3); + std::unique_ptr<LayerImpl> scale = + LayerImpl::Create(host_impl().active_tree(), 3); SetLayerPropertiesForTesting(scale.get(), scale_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50), true, false, false); - scoped_ptr<LayerImpl> clip = LayerImpl::Create(host_impl().active_tree(), 4); + std::unique_ptr<LayerImpl> clip = + LayerImpl::Create(host_impl().active_tree(), 4); SetLayerPropertiesForTesting(clip.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(25, 25), true, false, false); clip->SetMasksToBounds(true); - scoped_ptr<LayerImpl> test = LayerImpl::Create(host_impl().active_tree(), 5); + std::unique_ptr<LayerImpl> test = + LayerImpl::Create(host_impl().active_tree(), 5); SetLayerPropertiesForTesting(test.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, false, false); @@ -440,18 +446,19 @@ TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) { TEST_F(LayerTreeImplTest, HitTestingSiblings) { // This tests hit testing when the test point hits only one of the siblings. gfx::Transform identity_matrix; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(100, 100), true, false, true); - scoped_ptr<LayerImpl> child1 = + std::unique_ptr<LayerImpl> child1 = LayerImpl::Create(host_impl().active_tree(), 2); SetLayerPropertiesForTesting(child1.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(25, 25), true, false, false); child1->SetMasksToBounds(true); child1->SetDrawsContent(true); - scoped_ptr<LayerImpl> child2 = + std::unique_ptr<LayerImpl> child2 = LayerImpl::Create(host_impl().active_tree(), 3); SetLayerPropertiesForTesting(child2.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), gfx::Size(75, 75), true, false, @@ -478,11 +485,12 @@ TEST_F(LayerTreeImplTest, HitTestingPointOutsideMaxTextureSize) { host_impl().active_tree()->resource_provider()->max_texture_size(); gfx::Size bounds(max_texture_size + 100, max_texture_size + 100); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), bounds, true, false, true); - scoped_ptr<LayerImpl> surface = + std::unique_ptr<LayerImpl> surface = LayerImpl::Create(host_impl().active_tree(), 2); SetLayerPropertiesForTesting(surface.get(), identity_matrix, gfx::Point3F(), gfx::PointF(), bounds, true, false, true); @@ -506,7 +514,7 @@ TEST_F(LayerTreeImplTest, HitTestingPointOutsideMaxTextureSize) { } TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform identity_matrix; @@ -570,12 +578,13 @@ TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) { gfx::Transform identity_matrix; gfx::Point3F transform_origin; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin, gfx::PointF(), gfx::Size(100, 100), true, false, true); { - scoped_ptr<LayerImpl> clipping_layer = + std::unique_ptr<LayerImpl> clipping_layer = LayerImpl::Create(host_impl().active_tree(), 123); // this layer is positioned, and hit testing should correctly know where the // layer is located. @@ -586,7 +595,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) { false, false); clipping_layer->SetMasksToBounds(true); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 456); position = gfx::PointF(-50.f, -50.f); bounds = gfx::Size(300, 300); @@ -646,7 +655,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { // the root + child clips combined create a triangle. The rotated_leaf will // only be visible where it overlaps this triangle. // - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 123); LayerImpl* root_layer = root.get(); @@ -658,11 +667,11 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { position, bounds, true, false, true); root->SetMasksToBounds(true); { - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 456); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl().active_tree(), 789); - scoped_ptr<LayerImpl> rotated_leaf = + std::unique_ptr<LayerImpl> rotated_leaf = LayerImpl::Create(host_impl().active_tree(), 2468); position = gfx::PointF(10.f, 10.f); @@ -763,12 +772,13 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { gfx::Transform identity_matrix; gfx::Point3F transform_origin; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin, gfx::PointF(), gfx::Size(100, 100), true, false, true); { - scoped_ptr<LayerImpl> intermediate_layer = + std::unique_ptr<LayerImpl> intermediate_layer = LayerImpl::Create(host_impl().active_tree(), 123); // this layer is positioned, and hit testing should correctly know where the // layer is located. @@ -784,7 +794,7 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { // The child of the intermediate_layer is translated so that it does not // overlap intermediate_layer at all. If child is incorrectly clipped, we // would not be able to hit it successfully. - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 456); position = gfx::PointF(60.f, 60.f); // 70, 70 in screen space bounds = gfx::Size(20, 20); @@ -830,7 +840,8 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { } TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); LayerImpl* root_layer = root.get(); gfx::Transform identity_matrix; @@ -847,11 +858,11 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { // grand_child, (third) child1, and (back) the root layer behind all other // layers. - scoped_ptr<LayerImpl> child1 = + std::unique_ptr<LayerImpl> child1 = LayerImpl::Create(host_impl().active_tree(), 2); - scoped_ptr<LayerImpl> child2 = + std::unique_ptr<LayerImpl> child2 = LayerImpl::Create(host_impl().active_tree(), 3); - scoped_ptr<LayerImpl> grand_child1 = + std::unique_ptr<LayerImpl> grand_child1 = LayerImpl::Create(host_impl().active_tree(), 4); position = gfx::PointF(10.f, 10.f); @@ -963,11 +974,11 @@ int LayerTreeImplTest::HitTestSimpleTree(int root_id, float root_depth, float left_child_depth, float right_child_depth) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), root_id); - scoped_ptr<LayerImpl> left_child = + std::unique_ptr<LayerImpl> left_child = LayerImpl::Create(host_impl().active_tree(), left_child_id); - scoped_ptr<LayerImpl> right_child = + std::unique_ptr<LayerImpl> right_child = LayerImpl::Create(host_impl().active_tree(), right_child_id); gfx::Point3F transform_origin; @@ -1053,7 +1064,8 @@ TEST_F(LayerTreeImplTest, HitTestingSameSortingContextParentWins) { } TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); gfx::Transform identity_matrix; gfx::Point3F transform_origin; @@ -1062,7 +1074,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin, position, bounds, true, false, true); root->SetDrawsContent(true); - root->SetShouldFlattenTransform(false); + root->test_properties()->should_flatten_transform = false; root->Set3dSortingContextId(1); { // child 1 and child2 are initialized to overlap between x=50 and x=60. @@ -1071,11 +1083,11 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { // grand_child, (third) child1, and (back) the root layer behind all other // layers. - scoped_ptr<LayerImpl> child1 = + std::unique_ptr<LayerImpl> child1 = LayerImpl::Create(host_impl().active_tree(), 2); - scoped_ptr<LayerImpl> child2 = + std::unique_ptr<LayerImpl> child2 = LayerImpl::Create(host_impl().active_tree(), 3); - scoped_ptr<LayerImpl> grand_child1 = + std::unique_ptr<LayerImpl> grand_child1 = LayerImpl::Create(host_impl().active_tree(), 4); position = gfx::PointF(10.f, 10.f); @@ -1084,7 +1096,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { transform_origin, position, bounds, true, false, false); child1->SetDrawsContent(true); - child1->SetShouldFlattenTransform(false); + child1->test_properties()->should_flatten_transform = false; child1->Set3dSortingContextId(1); position = gfx::PointF(50.f, 10.f); @@ -1094,7 +1106,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { SetLayerPropertiesForTesting(child2.get(), translate_z, transform_origin, position, bounds, true, false, false); child2->SetDrawsContent(true); - child2->SetShouldFlattenTransform(false); + child2->test_properties()->should_flatten_transform = false; child2->Set3dSortingContextId(1); // Remember that grand_child is positioned with respect to its parent (i.e. @@ -1106,7 +1118,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { transform_origin, position, bounds, true, false, false); grand_child1->SetDrawsContent(true); - grand_child1->SetShouldFlattenTransform(false); + grand_child1->test_properties()->should_flatten_transform = false; child1->AddChild(std::move(grand_child1)); root->AddChild(std::move(child1)); @@ -1177,7 +1189,8 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { } TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); gfx::Transform identity_matrix; gfx::Point3F transform_origin; gfx::PointF position; @@ -1186,9 +1199,9 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { position, bounds, true, false, true); root->SetDrawsContent(true); { - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 2); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl().active_tree(), 4); position = gfx::PointF(10.f, 10.f); @@ -1207,10 +1220,11 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { grand_child->SetHasRenderSurface(true); // This should let |grand_child| "escape" |child|'s clip. - grand_child->SetClipParent(root.get()); - scoped_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>); + grand_child->test_properties()->clip_parent = root.get(); + std::unique_ptr<std::set<LayerImpl*>> clip_children( + new std::set<LayerImpl*>); clip_children->insert(grand_child.get()); - root->SetClipChildren(clip_children.release()); + root->test_properties()->clip_children.reset(clip_children.release()); child->AddChild(std::move(grand_child)); root->AddChild(std::move(child)); @@ -1228,7 +1242,8 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { } TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) { - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); gfx::Transform identity_matrix; gfx::Point3F transform_origin; gfx::PointF position; @@ -1237,11 +1252,11 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) { position, bounds, true, false, true); root->SetDrawsContent(true); { - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 2); - scoped_ptr<LayerImpl> scroll_child = + std::unique_ptr<LayerImpl> scroll_child = LayerImpl::Create(host_impl().active_tree(), 3); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl().active_tree(), 4); position = gfx::PointF(10.f, 10.f); @@ -1260,10 +1275,11 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) { // This should cause scroll child and its descendants to be affected by // |child|'s clip. - scroll_child->SetScrollParent(child.get()); - scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); + scroll_child->test_properties()->scroll_parent = child.get(); + std::unique_ptr<std::set<LayerImpl*>> scroll_children( + new std::set<LayerImpl*>); scroll_children->insert(scroll_child.get()); - child->SetScrollChildren(scroll_children.release()); + child->test_properties()->scroll_children.reset(scroll_children.release()); SetLayerPropertiesForTesting(grand_child.get(), identity_matrix, transform_origin, position, bounds, true, @@ -1293,7 +1309,8 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { // The geometry is set up similarly to the previous case, but // all layers are forced to be render surfaces now. // - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); LayerImpl* root_layer = root.get(); gfx::Transform identity_matrix; @@ -1310,11 +1327,11 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { // grand_child, (third) child1, and (back) the root layer behind all other // layers. - scoped_ptr<LayerImpl> child1 = + std::unique_ptr<LayerImpl> child1 = LayerImpl::Create(host_impl().active_tree(), 2); - scoped_ptr<LayerImpl> child2 = + std::unique_ptr<LayerImpl> child2 = LayerImpl::Create(host_impl().active_tree(), 3); - scoped_ptr<LayerImpl> grand_child1 = + std::unique_ptr<LayerImpl> grand_child1 = LayerImpl::Create(host_impl().active_tree(), 4); position = gfx::PointF(10.f, 10.f); @@ -1323,7 +1340,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { transform_origin, position, bounds, true, false, false); child1->SetDrawsContent(true); - child1->SetForceRenderSurface(true); + child1->test_properties()->force_render_surface = true; position = gfx::PointF(50.f, 10.f); bounds = gfx::Size(50, 50); @@ -1331,7 +1348,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { transform_origin, position, bounds, true, false, false); child2->SetDrawsContent(true); - child2->SetForceRenderSurface(true); + child2->test_properties()->force_render_surface = true; // Remember that grand_child is positioned with respect to its parent (i.e. // child1). In screen space, the intended position is (10, 50), with size @@ -1342,7 +1359,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { transform_origin, position, bounds, true, false, false); grand_child1->SetDrawsContent(true); - grand_child1->SetForceRenderSurface(true); + grand_child1->test_properties()->force_render_surface = true; child1->AddChild(std::move(grand_child1)); root->AddChild(std::move(child1)); @@ -1428,7 +1445,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { } TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform identity_matrix; @@ -1504,7 +1521,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForUninvertibleTransform) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform uninvertible_transform; @@ -1583,7 +1600,7 @@ TEST_F(LayerTreeImplTest, TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSinglePositionedLayer) { - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 12345); gfx::Transform identity_matrix; @@ -1651,7 +1668,8 @@ TEST_F(LayerTreeImplTest, // 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 // scaling the points accordingly. - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); gfx::Transform identity_matrix; gfx::Point3F transform_origin; @@ -1663,7 +1681,7 @@ TEST_F(LayerTreeImplTest, 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 = + std::unique_ptr<LayerImpl> test_layer = LayerImpl::Create(host_impl().active_tree(), 12345); SetLayerPropertiesForTesting(test_layer.get(), identity_matrix, transform_origin, position, bounds, true, @@ -1800,12 +1818,13 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { gfx::Transform identity_matrix; gfx::Point3F transform_origin; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin, gfx::PointF(), gfx::Size(100, 100), true, false, true); { - scoped_ptr<LayerImpl> clipping_layer = + std::unique_ptr<LayerImpl> clipping_layer = LayerImpl::Create(host_impl().active_tree(), 123); // this layer is positioned, and hit testing should correctly know where the // layer is located. @@ -1816,7 +1835,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { false, false); clipping_layer->SetMasksToBounds(true); - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 456); Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); position = gfx::PointF(-50.f, -50.f); @@ -1878,16 +1897,105 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { EXPECT_EQ(456, result_layer->id()); } +TEST_F(LayerTreeImplTest, + HitCheckingTouchHandlerRegionsForClippedLayerWithDeviceScale) { + // 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 + // scaling the points accordingly. + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); + + gfx::Transform identity_matrix; + gfx::Point3F transform_origin; + // Set the bounds of the root layer big enough to fit the child when scaled. + SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin, + gfx::PointF(), gfx::Size(100, 100), true, false, + true); + std::unique_ptr<LayerImpl> surface = + LayerImpl::Create(host_impl().active_tree(), 2); + SetLayerPropertiesForTesting(surface.get(), identity_matrix, transform_origin, + gfx::PointF(), gfx::Size(100, 100), true, false, + true); + { + std::unique_ptr<LayerImpl> clipping_layer = + LayerImpl::Create(host_impl().active_tree(), 123); + // This layer is positioned, and hit testing should correctly know where the + // layer is located. + gfx::PointF position(25.f, 20.f); + gfx::Size bounds(50, 50); + SetLayerPropertiesForTesting(clipping_layer.get(), identity_matrix, + transform_origin, position, bounds, true, + false, false); + clipping_layer->SetMasksToBounds(true); + + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl().active_tree(), 456); + Region touch_handler_region(gfx::Rect(0, 0, 300, 300)); + position = gfx::PointF(-50.f, -50.f); + bounds = gfx::Size(300, 300); + SetLayerPropertiesForTesting(child.get(), identity_matrix, transform_origin, + position, bounds, true, false, false); + child->SetDrawsContent(true); + child->SetTouchEventHandlerRegion(touch_handler_region); + clipping_layer->AddChild(std::move(child)); + surface->AddChild(std::move(clipping_layer)); + root->AddChild(std::move(surface)); + } + + float device_scale_factor = 3.f; + float page_scale_factor = 1.f; + float max_page_scale_factor = 1.f; + gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize( + root->bounds(), device_scale_factor * page_scale_factor); + host_impl().SetViewportSize(scaled_bounds_for_root); + + host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); + host_impl().active_tree()->SetRootLayer(std::move(root)); + host_impl().active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 1, + Layer::INVALID_ID); + host_impl().active_tree()->BuildPropertyTreesForTesting(); + host_impl().active_tree()->PushPageScaleFromMainThread( + page_scale_factor, page_scale_factor, max_page_scale_factor); + host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + + // Sanity check the scenario we just created. + ASSERT_EQ(2u, RenderSurfaceLayerList().size()); + + // Hit checking for a point outside the layer should return a null pointer. + // Despite the child layer being very large, it should be clipped to the root + // layer's bounds. + gfx::PointF test_point(24.f, 24.f); + test_point = + gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); + LayerImpl* 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 child layer. + test_point = gfx::PointF(25.f, 25.f); + test_point = + gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); + result_layer = + host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( + test_point); + ASSERT_TRUE(result_layer); + EXPECT_EQ(456, result_layer->id()); +} + TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { gfx::Transform identity_matrix; gfx::Point3F transform_origin; - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin, gfx::PointF(), gfx::Size(100, 100), true, false, true); { - scoped_ptr<LayerImpl> touch_layer = + std::unique_ptr<LayerImpl> touch_layer = LayerImpl::Create(host_impl().active_tree(), 123); // this layer is positioned, and hit testing should correctly know where the // layer is located. @@ -1902,7 +2010,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { } { - scoped_ptr<LayerImpl> notouch_layer = + std::unique_ptr<LayerImpl> notouch_layer = LayerImpl::Create(host_impl().active_tree(), 1234); // this layer is positioned, and hit testing should correctly know where the // layer is located. @@ -1960,7 +2068,8 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { } TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); gfx::Transform identity_matrix; gfx::Point3F transform_origin; @@ -1972,7 +2081,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { Region touch_handler_region(gfx::Rect(10, 10, 30, 30)); gfx::PointF position; gfx::Size bounds(50, 50); - scoped_ptr<LayerImpl> test_layer = + std::unique_ptr<LayerImpl> test_layer = LayerImpl::Create(host_impl().active_tree(), 12345); SetLayerPropertiesForTesting(test_layer.get(), identity_matrix, transform_origin, position, bounds, true, @@ -2009,7 +2118,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); EXPECT_FALSE(result_layer); - EXPECT_FALSE(test_layer->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_FALSE(test_layer->is_drawn_render_surface_layer_list_member()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_screen_space_transform, draw_property_utils::ScreenSpaceTransform( @@ -2031,7 +2140,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { test_point); ASSERT_TRUE(result_layer); ASSERT_EQ(test_layer, result_layer); - EXPECT_FALSE(result_layer->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_FALSE(result_layer->is_drawn_render_surface_layer_list_member()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_screen_space_transform, draw_property_utils::ScreenSpaceTransform( @@ -2041,7 +2150,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) { int root_layer_id = 12345; - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), root_layer_id); gfx::Transform identity_matrix; @@ -2120,7 +2229,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { int root_layer_id = 12345; int clip_layer_id = 1234; int clipped_layer_id = 123; - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), root_layer_id); root->SetDrawsContent(true); @@ -2133,7 +2242,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { gfx::Vector2dF clipping_offset(10, 10); { - scoped_ptr<LayerImpl> clipping_layer = + std::unique_ptr<LayerImpl> clipping_layer = LayerImpl::Create(host_impl().active_tree(), clip_layer_id); // The clipping layer should occlude the right selection bound. gfx::PointF position = gfx::PointF() + clipping_offset; @@ -2143,7 +2252,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { false, false); clipping_layer->SetMasksToBounds(true); - scoped_ptr<LayerImpl> clipped_layer = + std::unique_ptr<LayerImpl> clipped_layer = LayerImpl::Create(host_impl().active_tree(), clipped_layer_id); position = gfx::PointF(); bounds = gfx::Size(100, 100); @@ -2218,7 +2327,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { int root_layer_id = 1; int sub_layer_id = 2; - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), root_layer_id); root->SetDrawsContent(true); @@ -2231,7 +2340,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { gfx::Vector2dF sub_layer_offset(10, 0); { - scoped_ptr<LayerImpl> sub_layer = + std::unique_ptr<LayerImpl> sub_layer = LayerImpl::Create(host_impl().active_tree(), sub_layer_id); gfx::PointF position = gfx::PointF() + sub_layer_offset; gfx::Size bounds(50, 50); @@ -2304,7 +2413,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) { int child_id = 2; int grand_child_id = 3; - scoped_ptr<LayerImpl> root = + std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), root_id); gfx::Size bounds(100, 100); gfx::Transform identity_matrix; @@ -2319,12 +2428,12 @@ TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) { large_transform.RotateAboutYAxis(30); { - scoped_ptr<LayerImpl> child = + std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), child_id); SetLayerPropertiesForTesting(child.get(), large_transform, transform_origin, position, bounds, true, false, false); - scoped_ptr<LayerImpl> grand_child = + std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl().active_tree(), grand_child_id); SetLayerPropertiesForTesting(grand_child.get(), large_transform, transform_origin, position, bounds, true, @@ -2364,13 +2473,15 @@ TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) { TEST_F(LayerTreeImplTest, NumLayersTestOne) { EXPECT_EQ(0u, host_impl().active_tree()->NumLayers()); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); EXPECT_EQ(1u, host_impl().active_tree()->NumLayers()); } TEST_F(LayerTreeImplTest, NumLayersSmallTree) { EXPECT_EQ(0u, host_impl().active_tree()->NumLayers()); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); root->AddChild(LayerImpl::Create(host_impl().active_tree(), 2)); root->AddChild(LayerImpl::Create(host_impl().active_tree(), 3)); root->child_at(1)->AddChild(LayerImpl::Create(host_impl().active_tree(), 4)); @@ -2388,10 +2499,11 @@ TEST_F(LayerTreeImplTest, DeviceScaleFactorNeedsDrawPropertiesUpdate) { TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) { host_impl().active_tree()->set_event_listener_properties( EventListenerClass::kMouseWheel, EventListenerProperties::kBlocking); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); - scoped_ptr<LayerImpl> left_child = + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), 1); + std::unique_ptr<LayerImpl> left_child = LayerImpl::Create(host_impl().active_tree(), 2); - scoped_ptr<LayerImpl> right_child = + std::unique_ptr<LayerImpl> right_child = LayerImpl::Create(host_impl().active_tree(), 3); gfx::Point3F transform_origin; diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc index 5bcaf42fafb..44a934a2d8d 100644 --- a/chromium/cc/trees/layer_tree_settings.cc +++ b/chromium/cc/trees/layer_tree_settings.cc @@ -57,12 +57,14 @@ LayerTreeSettingsScrollbarAnimatorFromProto( LayerTreeSettings::LayerTreeSettings() : single_thread_proxy_scheduler(true), use_external_begin_frame_source(false), + use_output_surface_begin_frame_source(false), main_frame_before_activation_enabled(false), using_synchronous_renderer_compositor(false), can_use_lcd_text(true), use_distance_field_text(false), gpu_rasterization_enabled(false), gpu_rasterization_forced(false), + async_worker_context_enabled(false), gpu_rasterization_msaa_sample_count(0), gpu_rasterization_skewport_target_time_in_seconds(0.2f), create_low_res_tiling(false), @@ -83,9 +85,12 @@ LayerTreeSettings::LayerTreeSettings() max_untiled_layer_size(gfx::Size(512, 512)), minimum_occlusion_tracking_size(gfx::Size(160, 160)), // 3000 pixels should give sufficient area for prepainting. + // Note this value is specified with an ideal contents scale in mind. That + // is, the ideal tiling would use this value as the padding. + // TODO(vmpstr): Figure out a better number that doesn't depend on scale. tiling_interest_area_padding(3000), skewport_target_time_in_seconds(1.0f), - skewport_extrapolation_limit_in_content_pixels(2000), + skewport_extrapolation_limit_in_screen_pixels(2000), max_memory_for_prepaint_percentage(100), use_zero_copy(false), use_partial_raster(false), @@ -96,10 +101,12 @@ LayerTreeSettings::LayerTreeSettings() ignore_root_layer_flings(false), scheduled_raster_task_limit(32), use_occlusion_for_tile_prioritization(false), + verify_clip_tree_calculations(false), image_decode_tasks_enabled(false), wait_for_beginframe_interval(true), abort_commit_before_output_surface_creation(true), use_mouse_wheel_gestures(false), + use_layer_lists(false), max_staging_buffer_usage_in_bytes(32 * 1024 * 1024), memory_policy_(64 * 1024 * 1024, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, @@ -123,6 +130,7 @@ bool LayerTreeSettings::operator==(const LayerTreeSettings& other) const { use_distance_field_text == other.use_distance_field_text && gpu_rasterization_enabled == other.gpu_rasterization_enabled && gpu_rasterization_forced == other.gpu_rasterization_forced && + async_worker_context_enabled == other.async_worker_context_enabled && gpu_rasterization_msaa_sample_count == other.gpu_rasterization_msaa_sample_count && create_low_res_tiling == other.create_low_res_tiling && @@ -150,8 +158,8 @@ bool LayerTreeSettings::operator==(const LayerTreeSettings& other) const { tiling_interest_area_padding == other.tiling_interest_area_padding && skewport_target_time_in_seconds == other.skewport_target_time_in_seconds && - skewport_extrapolation_limit_in_content_pixels == - other.skewport_extrapolation_limit_in_content_pixels && + skewport_extrapolation_limit_in_screen_pixels == + other.skewport_extrapolation_limit_in_screen_pixels && max_memory_for_prepaint_percentage == other.max_memory_for_prepaint_percentage && use_zero_copy == other.use_zero_copy && @@ -162,6 +170,7 @@ bool LayerTreeSettings::operator==(const LayerTreeSettings& other) const { scheduled_raster_task_limit == other.scheduled_raster_task_limit && use_occlusion_for_tile_prioritization == other.use_occlusion_for_tile_prioritization && + verify_clip_tree_calculations == other.verify_clip_tree_calculations && image_decode_tasks_enabled == other.image_decode_tasks_enabled && wait_for_beginframe_interval == other.wait_for_beginframe_interval && use_mouse_wheel_gestures == other.use_mouse_wheel_gestures && @@ -185,6 +194,7 @@ void LayerTreeSettings::ToProtobuf(proto::LayerTreeSettings* proto) const { proto->set_use_distance_field_text(use_distance_field_text); proto->set_gpu_rasterization_enabled(gpu_rasterization_enabled); proto->set_gpu_rasterization_forced(gpu_rasterization_forced); + proto->set_async_worker_context_enabled(async_worker_context_enabled); proto->set_gpu_rasterization_msaa_sample_count( gpu_rasterization_msaa_sample_count); proto->set_create_low_res_tiling(create_low_res_tiling); @@ -210,8 +220,8 @@ void LayerTreeSettings::ToProtobuf(proto::LayerTreeSettings* proto) const { proto->mutable_minimum_occlusion_tracking_size()); proto->set_tiling_interest_area_padding(tiling_interest_area_padding); proto->set_skewport_target_time_in_seconds(skewport_target_time_in_seconds); - proto->set_skewport_extrapolation_limit_in_content_pixels( - skewport_extrapolation_limit_in_content_pixels); + proto->set_skewport_extrapolation_limit_in_screen_pixels( + skewport_extrapolation_limit_in_screen_pixels); proto->set_max_memory_for_prepaint_percentage( max_memory_for_prepaint_percentage); proto->set_use_zero_copy(use_zero_copy); @@ -246,6 +256,7 @@ void LayerTreeSettings::FromProtobuf(const proto::LayerTreeSettings& proto) { use_distance_field_text = proto.use_distance_field_text(); gpu_rasterization_enabled = proto.gpu_rasterization_enabled(); gpu_rasterization_forced = proto.gpu_rasterization_forced(); + async_worker_context_enabled = proto.async_worker_context_enabled(); gpu_rasterization_msaa_sample_count = proto.gpu_rasterization_msaa_sample_count(); create_low_res_tiling = proto.create_low_res_tiling(); @@ -271,8 +282,8 @@ void LayerTreeSettings::FromProtobuf(const proto::LayerTreeSettings& proto) { ProtoToSize(proto.minimum_occlusion_tracking_size()); tiling_interest_area_padding = proto.tiling_interest_area_padding(); skewport_target_time_in_seconds = proto.skewport_target_time_in_seconds(); - skewport_extrapolation_limit_in_content_pixels = - proto.skewport_extrapolation_limit_in_content_pixels(); + skewport_extrapolation_limit_in_screen_pixels = + proto.skewport_extrapolation_limit_in_screen_pixels(); max_memory_for_prepaint_percentage = proto.max_memory_for_prepaint_percentage(); use_zero_copy = proto.use_zero_copy(); diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index b4f56ebce0f..a72346a0f04 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -38,13 +38,17 @@ class CC_EXPORT LayerTreeSettings { RendererSettings renderer_settings; bool single_thread_proxy_scheduler; + // TODO(enne): Remove this after everything uses output surface begin frames. bool use_external_begin_frame_source; + // TODO(enne): Temporary staging for unified begin frame source work. + bool use_output_surface_begin_frame_source; bool main_frame_before_activation_enabled; bool using_synchronous_renderer_compositor; bool can_use_lcd_text; bool use_distance_field_text; bool gpu_rasterization_enabled; bool gpu_rasterization_forced; + bool async_worker_context_enabled; int gpu_rasterization_msaa_sample_count; float gpu_rasterization_skewport_target_time_in_seconds; bool create_low_res_tiling; @@ -70,9 +74,9 @@ class CC_EXPORT LayerTreeSettings { gfx::Size default_tile_size; gfx::Size max_untiled_layer_size; gfx::Size minimum_occlusion_tracking_size; - size_t tiling_interest_area_padding; + int tiling_interest_area_padding; float skewport_target_time_in_seconds; - int skewport_extrapolation_limit_in_content_pixels; + int skewport_extrapolation_limit_in_screen_pixels; size_t max_memory_for_prepaint_percentage; bool use_zero_copy; bool use_partial_raster; @@ -82,10 +86,12 @@ class CC_EXPORT LayerTreeSettings { bool ignore_root_layer_flings; size_t scheduled_raster_task_limit; bool use_occlusion_for_tile_prioritization; + bool verify_clip_tree_calculations; bool image_decode_tasks_enabled; bool wait_for_beginframe_interval; bool abort_commit_before_output_surface_creation; bool use_mouse_wheel_gestures; + bool use_layer_lists; int max_staging_buffer_usage_in_bytes; ManagedMemoryPolicy memory_policy_; diff --git a/chromium/cc/trees/layer_tree_settings_unittest.cc b/chromium/cc/trees/layer_tree_settings_unittest.cc index cf9e27972ae..f406a905988 100644 --- a/chromium/cc/trees/layer_tree_settings_unittest.cc +++ b/chromium/cc/trees/layer_tree_settings_unittest.cc @@ -70,8 +70,8 @@ TEST(LayerTreeSettingsTest, AllMembersChanged) { settings.tiling_interest_area_padding = settings.tiling_interest_area_padding * 3 + 1; settings.skewport_target_time_in_seconds = 0.53f; - settings.skewport_extrapolation_limit_in_content_pixels = - settings.skewport_extrapolation_limit_in_content_pixels * 3 + 1; + settings.skewport_extrapolation_limit_in_screen_pixels = + settings.skewport_extrapolation_limit_in_screen_pixels * 3 + 1; settings.max_memory_for_prepaint_percentage = settings.max_memory_for_prepaint_percentage * 3 + 1; settings.use_zero_copy = !settings.use_zero_copy; @@ -130,7 +130,7 @@ TEST(LayerTreeSettingsTest, ArbitraryValues) { settings.minimum_occlusion_tracking_size = gfx::Size(57, 58); settings.tiling_interest_area_padding = 59; settings.skewport_target_time_in_seconds = 0.6f; - settings.skewport_extrapolation_limit_in_content_pixels = 61; + settings.skewport_extrapolation_limit_in_screen_pixels = 61; settings.max_memory_for_prepaint_percentage = 62; settings.use_zero_copy = true; settings.use_partial_raster = true; diff --git a/chromium/cc/trees/mutator_host_client.h b/chromium/cc/trees/mutator_host_client.h index c90af7e7a8d..73c3a08d404 100644 --- a/chromium/cc/trees/mutator_host_client.h +++ b/chromium/cc/trees/mutator_host_client.h @@ -13,37 +13,49 @@ class ScrollOffset; namespace cc { class FilterOperations; -class Layer; -enum class LayerTreeType { ACTIVE, PENDING }; +using ElementId = int; + +enum class ElementListType { ACTIVE, PENDING }; + +enum class AnimationChangeType { POTENTIAL, RUNNING, BOTH }; class MutatorHostClient { public: - virtual bool IsLayerInTree(int layer_id, LayerTreeType tree_type) const = 0; + virtual bool IsElementInList(ElementId element_id, + ElementListType list_type) const = 0; + virtual void SetMutatorsNeedCommit() = 0; virtual void SetMutatorsNeedRebuildPropertyTrees() = 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, + virtual void SetElementFilterMutated(ElementId element_id, + ElementListType list_type, + const FilterOperations& filters) = 0; + virtual void SetElementOpacityMutated(ElementId element_id, + ElementListType list_type, + float opacity) = 0; + virtual void SetElementTransformMutated(ElementId element_id, + ElementListType list_type, + const gfx::Transform& transform) = 0; + virtual void SetElementScrollOffsetMutated( + ElementId element_id, + ElementListType list_type, const gfx::ScrollOffset& scroll_offset) = 0; - virtual void LayerTransformIsPotentiallyAnimatingChanged( - int layer_id, - LayerTreeType tree_type, + virtual void ElementTransformIsAnimatingChanged( + ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, bool is_animating) = 0; + virtual void ElementOpacityIsAnimatingChanged(ElementId element_id, + ElementListType list_type, + AnimationChangeType change_type, + bool is_animating) = 0; + virtual void ScrollOffsetAnimationFinished() = 0; - virtual gfx::ScrollOffset GetScrollOffsetForAnimation(int layer_id) const = 0; + virtual gfx::ScrollOffset GetScrollOffsetForAnimation( + ElementId element_id) const = 0; }; } // namespace cc diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc index a1a3ca07474..b1319b8a7a4 100644 --- a/chromium/cc/trees/occlusion_tracker.cc +++ b/chromium/cc/trees/occlusion_tracker.cc @@ -110,20 +110,21 @@ static SimpleEnclosedRegion TransformSurfaceOpaqueRegion( } void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) { - if (!stack_.empty() && stack_.back().target == new_target) + DCHECK(new_target->has_render_surface()); + if (!stack_.empty() && stack_.back().target == new_target->render_surface()) return; - const LayerImpl* old_target = NULL; + const RenderSurfaceImpl* old_target_surface = NULL; const RenderSurfaceImpl* old_occlusion_immune_ancestor = NULL; if (!stack_.empty()) { - old_target = stack_.back().target; + old_target_surface = stack_.back().target; old_occlusion_immune_ancestor = - old_target->render_surface()->nearest_occlusion_immune_ancestor(); + old_target_surface->nearest_occlusion_immune_ancestor(); } const RenderSurfaceImpl* new_occlusion_immune_ancestor = new_target->render_surface()->nearest_occlusion_immune_ancestor(); - stack_.push_back(StackObject(new_target)); + stack_.push_back(StackObject(new_target->render_surface())); // 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 @@ -156,7 +157,7 @@ void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) { 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()); + old_target_surface->screen_space_transform()); stack_[last_index].occlusion_from_outside_target = TransformSurfaceOpaqueRegion( stack_[last_index - 1].occlusion_from_outside_target, false, @@ -246,15 +247,18 @@ static void ReduceOcclusionBelowSurface( void OcclusionTracker::LeaveToRenderTarget(const LayerImpl* new_target) { DCHECK(!stack_.empty()); size_t last_index = stack_.size() - 1; + DCHECK(new_target->has_render_surface()); bool surface_will_be_at_top_after_pop = - stack_.size() > 1 && stack_[last_index - 1].target == new_target; + stack_.size() > 1 && + stack_[last_index - 1].target == new_target->render_surface(); // We merge the screen occlusion from the current RenderSurfaceImpl subtree // 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 LayerImpl* old_target = stack_[last_index].target; - const RenderSurfaceImpl* old_surface = old_target->render_surface(); + const RenderSurfaceImpl* old_surface = stack_[last_index].target; + const LayerImpl* old_target = + new_target->layer_tree_impl()->LayerById(old_surface->OwningLayerId()); SimpleEnclosedRegion old_occlusion_from_inside_target_in_new_target = TransformSurfaceOpaqueRegion( @@ -302,7 +306,7 @@ void OcclusionTracker::LeaveToRenderTarget(const LayerImpl* new_target) { stack_.pop_back(); } else { // Replace the top of the stack with the new pushed surface. - stack_.back().target = new_target; + stack_.back().target = new_target->render_surface(); stack_.back().occlusion_from_inside_target = old_occlusion_from_inside_target_in_new_target; if (!new_target->layer_tree_impl()->IsRootLayer(new_target)) { @@ -366,12 +370,11 @@ void OcclusionTracker::MarkOccludedBehindLayer(const LayerImpl* layer) { return; gfx::Rect clip_rect_in_target = ScreenSpaceClipRectInTargetSurface( - layer->render_target()->render_surface(), screen_space_clip_rect_); + layer->render_target(), screen_space_clip_rect_); if (layer->is_clipped()) { clip_rect_in_target.Intersect(layer->clip_rect()); } else { - clip_rect_in_target.Intersect( - layer->render_target()->render_surface()->content_rect()); + clip_rect_in_target.Intersect(layer->render_target()->content_rect()); } for (size_t i = 0; i < opaque_layer_region.GetRegionComplexity(); ++i) { @@ -386,9 +389,9 @@ void OcclusionTracker::MarkOccludedBehindLayer(const LayerImpl* layer) { } } -Region OcclusionTracker::ComputeVisibleRegionInScreen() const { - DCHECK(stack_.back().target->layer_tree_impl()->IsRootLayer( - stack_.back().target)); +Region OcclusionTracker::ComputeVisibleRegionInScreen( + const LayerTreeImpl* layer_tree) const { + DCHECK(layer_tree->root_layer()->render_surface() == stack_.back().target); const SimpleEnclosedRegion& occluded = stack_.back().occlusion_from_inside_target; Region visible_region(screen_space_clip_rect_); diff --git a/chromium/cc/trees/occlusion_tracker.h b/chromium/cc/trees/occlusion_tracker.h index 847de7b6390..9812ff3029a 100644 --- a/chromium/cc/trees/occlusion_tracker.h +++ b/chromium/cc/trees/occlusion_tracker.h @@ -48,7 +48,7 @@ class CC_EXPORT OcclusionTracker { void LeaveLayer(const LayerIteratorPosition& layer_iterator); // Gives the region of the screen that is not occluded by something opaque. - Region ComputeVisibleRegionInScreen() const; + Region ComputeVisibleRegionInScreen(const LayerTreeImpl* layer_tree) const; void set_minimum_tracking_size(const gfx::Size& size) { minimum_tracking_size_ = size; @@ -57,8 +57,8 @@ class CC_EXPORT OcclusionTracker { protected: struct StackObject { StackObject() : target(0) {} - explicit StackObject(const LayerImpl* target) : target(target) {} - const LayerImpl* target; + explicit StackObject(const RenderSurfaceImpl* target) : target(target) {} + const RenderSurfaceImpl* target; SimpleEnclosedRegion occlusion_from_outside_target; SimpleEnclosedRegion occlusion_from_inside_target; }; diff --git a/chromium/cc/trees/occlusion_tracker_perftest.cc b/chromium/cc/trees/occlusion_tracker_perftest.cc index ccaa75ae560..35c30e15d7e 100644 --- a/chromium/cc/trees/occlusion_tracker_perftest.cc +++ b/chromium/cc/trees/occlusion_tracker_perftest.cc @@ -6,7 +6,7 @@ #include <stddef.h> -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "cc/debug/lap_timer.h" #include "cc/layers/layer_iterator.h" @@ -46,8 +46,8 @@ class OcclusionTrackerPerfTest : public testing::Test { host_impl_->SetVisible(true); host_impl_->InitializeRenderer(output_surface_.get()); - scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(active_tree(), 1); - root_layer->SetForceRenderSurface(true); + std::unique_ptr<LayerImpl> root_layer = LayerImpl::Create(active_tree(), 1); + root_layer->test_properties()->force_render_surface = true; active_tree()->SetRootLayer(std::move(root_layer)); } @@ -73,8 +73,8 @@ class OcclusionTrackerPerfTest : public testing::Test { FakeRenderingStatsInstrumentation stats_; TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<LayerTreeHostImpl> host_impl_; + std::unique_ptr<OutputSurface> output_surface_; + std::unique_ptr<LayerTreeHostImpl> host_impl_; }; TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) { @@ -86,7 +86,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) { CreateHost(); host_impl_->SetViewportSize(viewport_rect.size()); - scoped_ptr<SolidColorLayerImpl> opaque_layer = + std::unique_ptr<SolidColorLayerImpl> opaque_layer = SolidColorLayerImpl::Create(active_tree(), 2); opaque_layer->SetBackgroundColor(SK_ColorRED); opaque_layer->SetContentsOpaque(true); @@ -154,7 +154,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_10OpaqueLayers) { host_impl_->SetViewportSize(viewport_rect.size()); for (int i = 0; i < kNumOpaqueLayers; ++i) { - scoped_ptr<SolidColorLayerImpl> opaque_layer = + std::unique_ptr<SolidColorLayerImpl> opaque_layer = SolidColorLayerImpl::Create(active_tree(), 2 + i); opaque_layer->SetBackgroundColor(SK_ColorRED); opaque_layer->SetContentsOpaque(true); diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index e32134e69e9..28bd9ecf7c1 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -6,7 +6,6 @@ #include <stddef.h> -#include "cc/animation/layer_animation_controller.h" #include "cc/base/math_util.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" @@ -101,13 +100,14 @@ class OcclusionTrackerTest : public testing::Test { 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)); + std::unique_ptr<TestContentLayerImpl> layer( + new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); SetProperties(layer_ptr, transform, position, bounds); host_->host_impl()->active_tree()->SetRootLayer(std::move(layer)); - layer_ptr->SetForceRenderSurface(true); + layer_ptr->test_properties()->force_render_surface = true; SetRootLayerOnMainThread(layer_ptr); return layer_ptr; @@ -119,7 +119,7 @@ class OcclusionTrackerTest : public testing::Test { 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); + std::unique_ptr<LayerImpl> layer = LayerImpl::Create(tree, id); LayerImpl* layer_ptr = layer.get(); SetProperties(layer_ptr, transform, position, bounds); parent->AddChild(std::move(layer)); @@ -131,7 +131,7 @@ class OcclusionTrackerTest : public testing::Test { const gfx::PointF& position, const gfx::Size& bounds) { LayerImpl* layer = CreateLayer(parent, transform, position, bounds); - layer->SetForceRenderSurface(true); + layer->test_properties()->force_render_surface = true; return layer; } @@ -142,7 +142,8 @@ class OcclusionTrackerTest : public testing::Test { bool opaque) { LayerTreeImpl* tree = host_->host_impl()->active_tree(); int id = next_layer_impl_id_++; - scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id)); + std::unique_ptr<TestContentLayerImpl> layer( + new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); SetProperties(layer_ptr, transform, position, bounds); @@ -166,7 +167,8 @@ class OcclusionTrackerTest : public testing::Test { 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)); + std::unique_ptr<TestContentLayerImpl> layer( + new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); SetProperties(layer_ptr, transform, position, bounds); SetReplica(owning_layer, std::move(layer)); @@ -176,7 +178,8 @@ class OcclusionTrackerTest : public testing::Test { 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)); + std::unique_ptr<TestContentLayerImpl> layer( + new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds); SetMask(owning_layer, std::move(layer)); @@ -190,7 +193,7 @@ class OcclusionTrackerTest : public testing::Test { bool opaque) { TestContentLayerImpl* layer = CreateDrawingLayer(parent, transform, position, bounds, opaque); - layer->SetForceRenderSurface(true); + layer->test_properties()->force_render_surface = true; return layer; } @@ -202,7 +205,7 @@ class OcclusionTrackerTest : public testing::Test { ResetLayerIterator(); } - void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} + void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} void AddCopyRequest(Layer* layer) { layer->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( @@ -211,7 +214,7 @@ class OcclusionTrackerTest : public testing::Test { } void AddCopyRequest(LayerImpl* layer) { - std::vector<scoped_ptr<CopyOutputRequest>> requests; + std::vector<std::unique_ptr<CopyOutputRequest>> requests; requests.push_back(CopyOutputRequest::CreateBitmapRequest(base::Bind( &OcclusionTrackerTest::CopyOutputCallback, base::Unretained(this)))); layer->PassCopyRequests(&requests); @@ -226,12 +229,10 @@ class OcclusionTrackerTest : public testing::Test { FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list_impl_, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list_impl_); inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); layer_iterator_ = layer_iterator_begin_ = LayerIterator::Begin(&render_surface_layer_list_impl_); @@ -297,20 +298,20 @@ class OcclusionTrackerTest : public testing::Test { layer->SetBounds(bounds); } - void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { + void SetReplica(LayerImpl* owning_layer, std::unique_ptr<LayerImpl> layer) { // We need to set parent on replica layer for property tree building. layer->SetParent(owning_layer); owning_layer->SetReplicaLayer(std::move(layer)); } - void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) { + void SetMask(LayerImpl* owning_layer, std::unique_ptr<LayerImpl> layer) { owning_layer->SetMaskLayer(std::move(layer)); } bool opaque_layers_; FakeLayerTreeHostClient client_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHost> host_; + std::unique_ptr<FakeLayerTreeHost> host_; // These hold ownership of the layers for the duration of the test. LayerImplList render_surface_layer_list_impl_; LayerIterator layer_iterator_begin_; @@ -537,7 +538,7 @@ class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest { layer1_matrix.Scale(2.0, 2.0); TestContentLayerImpl* layer1 = this->CreateDrawingLayer( parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true); - layer1->SetForceRenderSurface(true); + layer1->test_properties()->force_render_surface = true; gfx::Transform layer2_matrix; layer2_matrix.Translate(25.0, 25.0); @@ -918,17 +919,17 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest { parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - blur_layer->SetForceRenderSurface(true); + blur_layer->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(10.f)); blur_layer->SetFilters(filters); - opaque_layer->SetForceRenderSurface(true); + opaque_layer->test_properties()->force_render_surface = true; filters.Clear(); filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); opaque_layer->SetFilters(filters); - opacity_layer->SetForceRenderSurface(true); + opacity_layer->test_properties()->force_render_surface = true; filters.Clear(); filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); opacity_layer->SetFilters(filters); @@ -1185,9 +1186,9 @@ class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, transform, gfx::PointF(), gfx::Size(100, 100), true); - parent->SetShouldFlattenTransform(false); + parent->test_properties()->should_flatten_transform = false; parent->Set3dSortingContextId(1); - layer->SetShouldFlattenTransform(false); + layer->test_properties()->should_flatten_transform = false; layer->Set3dSortingContextId(1); this->CalcDrawEtc(parent); @@ -1480,7 +1481,7 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), occlusion_rect.size(), true); - occluding_layer->SetForceRenderSurface(false); + occluding_layer->test_properties()->force_render_surface = false; this->CalcDrawEtc(parent); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); @@ -1564,8 +1565,8 @@ class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice gfx::Size(50, 50), true); // Filters make the layers own surfaces. - filtered_surface1->SetForceRenderSurface(true); - filtered_surface2->SetForceRenderSurface(true); + filtered_surface1->test_properties()->force_render_surface = true; + filtered_surface2->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(1.f)); filtered_surface1->SetBackgroundFilters(filters); @@ -1641,7 +1642,7 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter gfx::Size()); // Filters make the layer own a surface. - filtered_surface->SetForceRenderSurface(true); + filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); filtered_surface->SetBackgroundFilters(filters); @@ -1708,7 +1709,7 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded gfx::Size(50, 50), true); // Filters make the layer own a surface. - filtered_surface->SetForceRenderSurface(true); + filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); filtered_surface->SetBackgroundFilters(filters); @@ -1787,7 +1788,7 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded gfx::Size(10, 10), true); // Filters make the layer own a surface. - filtered_surface->SetForceRenderSurface(true); + filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); filtered_surface->SetBackgroundFilters(filters); @@ -1862,7 +1863,7 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude gfx::Size(20, 22), true); // Blend mode makes the layer own a surface. - blend_mode_layer->SetForceRenderSurface(true); + blend_mode_layer->test_properties()->force_render_surface = true; blend_mode_layer->SetBlendMode(SkXfermode::kMultiply_Mode); this->CalcDrawEtc(parent); @@ -2072,7 +2073,7 @@ class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude // The |copy| layer is hidden but since it is being copied, it will be // drawn. - hide->SetHideLayerAndSubtree(true); + hide->test_properties()->hide_layer_and_subtree = true; this->CalcDrawEtc(root); diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index 216467641cc..17ecbbcf4a3 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -8,6 +8,8 @@ #include <vector> #include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/trace_event/trace_event_argument.h" #include "cc/base/math_util.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/input/scroll_state.h" @@ -47,6 +49,14 @@ void TreeNode<T>::FromProtobuf(const proto::TreeNode& proto) { data.FromProtobuf(proto); } +template <typename T> +void TreeNode<T>::AsValueInto(base::trace_event::TracedValue* value) const { + value->SetInteger("id", id); + value->SetInteger("parent_id", parent_id); + value->SetInteger("owner_id", owner_id); + data.AsValueInto(value); +} + template struct TreeNode<TransformNodeData>; template struct TreeNode<ClipNodeData>; template struct TreeNode<EffectNodeData>; @@ -107,7 +117,9 @@ void PropertyTree<T>::ToProtobuf(proto::PropertyTree* proto) const { } template <typename T> -void PropertyTree<T>::FromProtobuf(const proto::PropertyTree& proto) { +void PropertyTree<T>::FromProtobuf( + const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map) { // Verify that the property tree is empty. DCHECK_EQ(static_cast<int>(nodes_.size()), 1); DCHECK_EQ(back()->id, 0); @@ -117,14 +129,27 @@ void PropertyTree<T>::FromProtobuf(const proto::PropertyTree& proto) { DCHECK_GT(proto.nodes_size(), 0); nodes_.back().FromProtobuf(proto.nodes(0)); + DCHECK(!node_id_to_index_map || (*node_id_to_index_map).empty()); for (int i = 1; i < proto.nodes_size(); ++i) { nodes_.push_back(T()); nodes_.back().FromProtobuf(proto.nodes(i)); + (*node_id_to_index_map)[nodes_.back().owner_id] = nodes_.back().id; } needs_update_ = proto.needs_update(); } +template <typename T> +void PropertyTree<T>::AsValueInto(base::trace_event::TracedValue* value) const { + value->BeginArray("nodes"); + for (const auto& node : nodes_) { + value->BeginDictionary(); + node.AsValueInto(value); + value->EndDictionary(); + } + value->EndArray(); +} + template class PropertyTree<TransformNode>; template class PropertyTree<ClipNode>; template class PropertyTree<EffectNode>; @@ -136,9 +161,11 @@ TransformNodeData::TransformNodeData() source_node_id(-1), sorting_context_id(0), needs_local_transform_update(true), + node_and_ancestors_are_animated_or_invertible(true), is_invertible(true), ancestors_are_invertible(true), - is_animated(false), + has_potential_animation(false), + is_currently_animating(false), to_screen_is_potentially_animated(false), has_only_translation_animations(true), to_screen_has_scale_animation(false), @@ -174,9 +201,12 @@ bool TransformNodeData::operator==(const TransformNodeData& other) const { source_node_id == other.source_node_id && sorting_context_id == other.sorting_context_id && needs_local_transform_update == other.needs_local_transform_update && + node_and_ancestors_are_animated_or_invertible == + other.node_and_ancestors_are_animated_or_invertible && is_invertible == other.is_invertible && ancestors_are_invertible == other.ancestors_are_invertible && - is_animated == other.is_animated && + has_potential_animation == other.has_potential_animation && + is_currently_animating == other.is_currently_animating && to_screen_is_potentially_animated == other.to_screen_is_potentially_animated && has_only_translation_animations == @@ -256,10 +286,14 @@ void TransformNodeData::ToProtobuf(proto::TreeNode* proto) const { data->set_needs_local_transform_update(needs_local_transform_update); + data->set_node_and_ancestors_are_animated_or_invertible( + node_and_ancestors_are_animated_or_invertible); + data->set_is_invertible(is_invertible); data->set_ancestors_are_invertible(ancestors_are_invertible); - data->set_is_animated(is_animated); + data->set_has_potential_animation(has_potential_animation); + data->set_is_currently_animating(is_currently_animating); data->set_to_screen_is_potentially_animated( to_screen_is_potentially_animated); data->set_has_only_translation_animations(has_only_translation_animations); @@ -323,10 +357,14 @@ void TransformNodeData::FromProtobuf(const proto::TreeNode& proto) { needs_local_transform_update = data.needs_local_transform_update(); + node_and_ancestors_are_animated_or_invertible = + data.node_and_ancestors_are_animated_or_invertible(); + is_invertible = data.is_invertible(); ancestors_are_invertible = data.ancestors_are_invertible(); - is_animated = data.is_animated(); + has_potential_animation = data.has_potential_animation(); + is_currently_animating = data.is_currently_animating(); to_screen_is_potentially_animated = data.to_screen_is_potentially_animated(); has_only_translation_animations = data.has_only_translation_animations(); to_screen_has_scale_animation = data.to_screen_has_scale_animation(); @@ -365,6 +403,17 @@ void TransformNodeData::FromProtobuf(const proto::TreeNode& proto) { source_to_parent = ProtoToVector2dF(data.source_to_parent()); } +void TransformNodeData::AsValueInto( + base::trace_event::TracedValue* value) const { + MathUtil::AddToTracedValue("pre_local", pre_local, value); + MathUtil::AddToTracedValue("local", local, value); + MathUtil::AddToTracedValue("post_local", post_local, value); + value->SetInteger("target_id", target_id); + value->SetInteger("content_target_id", content_target_id); + value->SetInteger("source_node_id", source_node_id); + value->SetInteger("sorting_context_id", sorting_context_id); +} + ClipNodeData::ClipNodeData() : transform_id(-1), target_id(-1), @@ -434,20 +483,36 @@ void ClipNodeData::FromProtobuf(const proto::TreeNode& proto) { resets_clip = data.resets_clip(); } +void ClipNodeData::AsValueInto(base::trace_event::TracedValue* value) const { + MathUtil::AddToTracedValue("clip", clip, value); + value->SetInteger("transform_id", transform_id); + value->SetInteger("target_id", target_id); + value->SetBoolean("applies_local_clip", applies_local_clip); + value->SetBoolean("layer_clipping_uses_only_local_clip", + layer_clipping_uses_only_local_clip); + value->SetBoolean("target_is_clipped", target_is_clipped); + value->SetBoolean("layers_are_clipped", layers_are_clipped); + value->SetBoolean("layers_are_clipped_when_surfaces_disabled", + layers_are_clipped_when_surfaces_disabled); + value->SetBoolean("resets_clip", resets_clip); +} + EffectNodeData::EffectNodeData() : opacity(1.f), screen_space_opacity(1.f), has_render_surface(false), + render_surface(nullptr), has_copy_request(false), has_background_filters(false), - node_or_ancestor_has_background_filters(false), - to_screen_opacity_is_animated(false), hidden_by_backface_visibility(false), double_sided(false), is_drawn(true), - has_animated_opacity(false), + subtree_hidden(false), + has_potential_opacity_animation(false), + is_currently_animating_opacity(false), effect_changed(false), num_copy_requests_in_subtree(0), + has_unclipped_descendants(false), transform_id(0), clip_id(0), target_id(0) {} @@ -460,12 +525,13 @@ bool EffectNodeData::operator==(const EffectNodeData& other) const { has_render_surface == other.has_render_surface && has_copy_request == other.has_copy_request && has_background_filters == other.has_background_filters && - node_or_ancestor_has_background_filters == - other.node_or_ancestor_has_background_filters && - to_screen_opacity_is_animated == other.to_screen_opacity_is_animated && hidden_by_backface_visibility == other.hidden_by_backface_visibility && double_sided == other.double_sided && is_drawn == other.is_drawn && - has_animated_opacity == other.has_animated_opacity && + subtree_hidden == other.subtree_hidden && + has_potential_opacity_animation == + other.has_potential_opacity_animation && + is_currently_animating_opacity == + other.is_currently_animating_opacity && effect_changed == other.effect_changed && num_copy_requests_in_subtree == other.num_copy_requests_in_subtree && transform_id == other.transform_id && clip_id == other.clip_id && @@ -480,13 +546,12 @@ void EffectNodeData::ToProtobuf(proto::TreeNode* proto) const { data->set_has_render_surface(has_render_surface); data->set_has_copy_request(has_copy_request); data->set_has_background_filters(has_background_filters); - data->set_node_or_ancestor_has_background_filters( - node_or_ancestor_has_background_filters); - data->set_to_screen_opacity_is_animated(to_screen_opacity_is_animated); data->set_hidden_by_backface_visibility(hidden_by_backface_visibility); data->set_double_sided(double_sided); data->set_is_drawn(is_drawn); - data->set_has_animated_opacity(has_animated_opacity); + data->set_subtree_hidden(subtree_hidden); + data->set_has_potential_opacity_animation(has_potential_opacity_animation); + data->set_is_currently_animating_opacity(is_currently_animating_opacity); data->set_effect_changed(effect_changed); data->set_num_copy_requests_in_subtree(num_copy_requests_in_subtree); data->set_transform_id(transform_id); @@ -503,13 +568,12 @@ void EffectNodeData::FromProtobuf(const proto::TreeNode& proto) { has_render_surface = data.has_render_surface(); has_copy_request = data.has_copy_request(); has_background_filters = data.has_background_filters(); - node_or_ancestor_has_background_filters = - data.node_or_ancestor_has_background_filters(); - to_screen_opacity_is_animated = data.to_screen_opacity_is_animated(); hidden_by_backface_visibility = data.hidden_by_backface_visibility(); double_sided = data.double_sided(); is_drawn = data.is_drawn(); - has_animated_opacity = data.has_animated_opacity(); + subtree_hidden = data.subtree_hidden(); + has_potential_opacity_animation = data.has_potential_opacity_animation(); + is_currently_animating_opacity = data.is_currently_animating_opacity(); effect_changed = data.effect_changed(); num_copy_requests_in_subtree = data.num_copy_requests_in_subtree(); transform_id = data.transform_id(); @@ -517,6 +581,23 @@ void EffectNodeData::FromProtobuf(const proto::TreeNode& proto) { target_id = data.target_id(); } +void EffectNodeData::AsValueInto(base::trace_event::TracedValue* value) const { + value->SetDouble("opacity", opacity); + value->SetBoolean("has_render_surface", has_render_surface); + value->SetBoolean("has_copy_request", has_copy_request); + value->SetBoolean("has_background_filters", has_background_filters); + value->SetBoolean("double_sided", double_sided); + value->SetBoolean("is_drawn", is_drawn); + value->SetBoolean("has_potential_opacity_animation", + has_potential_opacity_animation); + value->SetBoolean("effect_changed", effect_changed); + value->SetInteger("num_copy_requests_in_subtree", + num_copy_requests_in_subtree); + value->SetInteger("transform_id", transform_id); + value->SetInteger("clip_id", clip_id); + value->SetInteger("target_id", target_id); +} + ScrollNodeData::ScrollNodeData() : scrollable(false), main_thread_scrolling_reasons( @@ -529,7 +610,8 @@ ScrollNodeData::ScrollNodeData() user_scrollable_horizontal(false), user_scrollable_vertical(false), element_id(0), - transform_id(0) {} + transform_id(0), + num_drawn_descendants(0) {} ScrollNodeData::ScrollNodeData(const ScrollNodeData& other) = default; @@ -599,6 +681,20 @@ void ScrollNodeData::FromProtobuf(const proto::TreeNode& proto) { transform_id = data.transform_id(); } +void ScrollNodeData::AsValueInto(base::trace_event::TracedValue* value) const { + value->SetBoolean("scrollable", scrollable); + MathUtil::AddToTracedValue("scroll_clip_layer_bounds", + scroll_clip_layer_bounds, value); + MathUtil::AddToTracedValue("bounds", bounds, value); + MathUtil::AddToTracedValue("offset_to_transform_parent", + offset_to_transform_parent, value); + value->SetBoolean("should_flatten", should_flatten); + value->SetBoolean("user_scrollable_horizontal", user_scrollable_horizontal); + value->SetBoolean("user_scrollable_vertical", user_scrollable_vertical); + value->SetInteger("element_id", element_id); + value->SetInteger("transform_id", transform_id); +} + void TransformTree::clear() { PropertyTree<TransformNode>::clear(); @@ -690,6 +786,7 @@ void TransformTree::UpdateTransforms(int id) { UpdateSnapping(node); UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); UpdateTransformChanged(node, parent_node, source_node); + UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); } bool TransformTree::IsDescendant(int desc_id, int source_id) const { @@ -932,7 +1029,7 @@ void TransformTree::UpdateAnimationProperties(TransformNode* node, parent_node->data.combined_starting_animation_scale; } node->data.to_screen_is_potentially_animated = - node->data.is_animated || ancestor_is_animating; + node->data.has_potential_animation || ancestor_is_animating; node->data.to_screen_has_scale_animation = !node->data.has_only_translation_animations || ancestor_is_animating_scale; @@ -1015,20 +1112,20 @@ void TransformTree::UndoSnapping(TransformNode* node) { void TransformTree::UpdateSnapping(TransformNode* node) { if (!node->data.scrolls || node->data.to_screen_is_potentially_animated || - !node->data.to_target.IsScaleOrTranslation() || + !node->data.to_screen.IsScaleOrTranslation() || !node->data.ancestors_are_invertible) { return; } - // Scroll snapping must be done in target space (the pixels we care about). - // This means we effectively snap the target space transform. If TT is the - // target space transform and TT' is TT with its translation components - // rounded, then what we're after is the scroll delta X, where TT * X = TT'. + // Scroll snapping must be done in screen space (the pixels we care about). + // This means we effectively snap the screen space transform. If ST is the + // screen space transform and ST' is ST with its translation components + // rounded, then what we're after is the scroll delta X, where ST * X = ST'. // I.e., we want a transform that will realize our scroll snap. It follows - // that X = TT^-1 * TT'. We cache TT and TT^-1 to make this more efficient. - gfx::Transform rounded = node->data.to_target; + // that X = ST^-1 * ST'. We cache ST and ST^-1 to make this more efficient. + gfx::Transform rounded = node->data.to_screen; rounded.RoundTranslationComponents(); - gfx::Transform delta = node->data.from_target; + gfx::Transform delta = node->data.from_screen; delta *= rounded; DCHECK(delta.IsApproximatelyIdentityOrTranslation(SkDoubleToMScalar(1e-4))) @@ -1038,13 +1135,13 @@ void TransformTree::UpdateSnapping(TransformNode* node) { // Now that we have our scroll delta, we must apply it to each of our // combined, to/from matrices. - node->data.to_target = rounded; + node->data.to_screen = rounded; node->data.to_parent.Translate(translation.x(), translation.y()); - node->data.from_target.matrix().postTranslate(-translation.x(), - -translation.y(), 0); - node->data.to_screen.Translate(translation.x(), translation.y()); node->data.from_screen.matrix().postTranslate(-translation.x(), -translation.y(), 0); + node->data.to_target.Translate(translation.x(), translation.y()); + node->data.from_target.matrix().postTranslate(-translation.x(), + -translation.y(), 0); node->data.scroll_snap = translation; } @@ -1062,6 +1159,29 @@ void TransformTree::UpdateTransformChanged(TransformNode* node, node->data.transform_changed = true; } +void TransformTree::UpdateNodeAndAncestorsAreAnimatedOrInvertible( + TransformNode* node, + TransformNode* parent_node) { + if (!parent_node) { + node->data.node_and_ancestors_are_animated_or_invertible = + node->data.has_potential_animation || node->data.is_invertible; + return; + } + if (!parent_node->data.node_and_ancestors_are_animated_or_invertible) { + node->data.node_and_ancestors_are_animated_or_invertible = false; + return; + } + bool is_invertible = node->data.is_invertible; + // Even when the current node's transform and the parent's screen space + // transform are invertible, the current node's screen space transform can + // become uninvertible due to floating-point arithmetic. + if (!node->data.ancestors_are_invertible && + parent_node->data.ancestors_are_invertible) + is_invertible = false; + node->data.node_and_ancestors_are_animated_or_invertible = + node->data.has_potential_animation || is_invertible; +} + void TransformTree::SetDeviceTransform(const gfx::Transform& transform, gfx::PointF root_position) { gfx::Transform root_post_local = transform; @@ -1170,11 +1290,13 @@ void TransformTree::ToProtobuf(proto::PropertyTree* proto) const { data->add_nodes_affected_by_outer_viewport_bounds_delta(i); } -void TransformTree::FromProtobuf(const proto::PropertyTree& proto) { +void TransformTree::FromProtobuf( + const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map) { DCHECK(proto.has_property_type()); DCHECK_EQ(proto.property_type(), proto::PropertyTree::Transform); - PropertyTree::FromProtobuf(proto); + PropertyTree::FromProtobuf(proto, node_id_to_index_map); const proto::TransformTreeData& data = proto.transform_tree_data(); source_to_parent_updates_allowed_ = data.source_to_parent_updates_allowed(); @@ -1197,8 +1319,12 @@ void TransformTree::FromProtobuf(const proto::PropertyTree& proto) { } } +float EffectTree::EffectiveOpacity(const EffectNode* node) const { + return node->data.subtree_hidden ? 0.f : node->data.opacity; +} + void EffectTree::UpdateOpacities(EffectNode* node, EffectNode* parent_node) { - node->data.screen_space_opacity = node->data.opacity; + node->data.screen_space_opacity = EffectiveOpacity(node); if (parent_node) node->data.screen_space_opacity *= parent_node->data.screen_space_opacity; @@ -1210,11 +1336,13 @@ void EffectTree::UpdateIsDrawn(EffectNode* node, EffectNode* parent_node) { // 1) Nodes that contribute to copy requests, whether hidden or not, must be // drawn. // 2) Nodes that have a background filter. - // 3) Nodes with animating screen space opacity are drawn if their parent is - // drawn irrespective of their opacity. + // 3) Nodes with animating screen space opacity on main thread or pending tree + // are drawn if their parent is drawn irrespective of their opacity. if (node->data.has_copy_request) node->data.is_drawn = true; - else if (node->data.opacity == 0.f && !node->data.has_animated_opacity && + else if (EffectiveOpacity(node) == 0.f && + (!node->data.has_potential_opacity_animation || + property_trees()->is_active) && !node->data.has_background_filters) node->data.is_drawn = false; else if (parent_node) @@ -1294,13 +1422,7 @@ bool EffectTree::ContributesToDrawnSurface(int id) { // copy requests. EffectNode* node = Node(id); EffectNode* parent_node = parent(node); - bool contributes_to_drawn_surface = - node->data.is_drawn && - (node->data.opacity != 0.f || node->data.has_animated_opacity || - node->data.has_background_filters); - if (parent_node && !parent_node->data.is_drawn) - contributes_to_drawn_surface = false; - return contributes_to_drawn_surface; + return node->data.is_drawn && (!parent_node || parent_node->data.is_drawn); } void EffectTree::ResetChangeTracking() { @@ -1348,11 +1470,13 @@ void ClipTree::ToProtobuf(proto::PropertyTree* proto) const { PropertyTree::ToProtobuf(proto); } -void ClipTree::FromProtobuf(const proto::PropertyTree& proto) { +void ClipTree::FromProtobuf( + const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map) { DCHECK(proto.has_property_type()); DCHECK_EQ(proto.property_type(), proto::PropertyTree::Clip); - PropertyTree::FromProtobuf(proto); + PropertyTree::FromProtobuf(proto, node_id_to_index_map); } bool EffectTree::operator==(const EffectTree& other) const { @@ -1366,11 +1490,13 @@ void EffectTree::ToProtobuf(proto::PropertyTree* proto) const { PropertyTree::ToProtobuf(proto); } -void EffectTree::FromProtobuf(const proto::PropertyTree& proto) { +void EffectTree::FromProtobuf( + const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map) { DCHECK(proto.has_property_type()); DCHECK_EQ(proto.property_type(), proto::PropertyTree::Effect); - PropertyTree::FromProtobuf(proto); + PropertyTree::FromProtobuf(proto, node_id_to_index_map); } ScrollTree::ScrollTree() @@ -1435,15 +1561,20 @@ void ScrollTree::ToProtobuf(proto::PropertyTree* proto) const { } } -void ScrollTree::FromProtobuf(const proto::PropertyTree& proto) { +void ScrollTree::FromProtobuf( + const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map) { DCHECK(proto.has_property_type()); DCHECK_EQ(proto.property_type(), proto::PropertyTree::Scroll); - PropertyTree::FromProtobuf(proto); + PropertyTree::FromProtobuf(proto, node_id_to_index_map); const proto::ScrollTreeData& data = proto.scroll_tree_data(); currently_scrolling_node_id_ = data.currently_scrolling_node_id(); + // TODO(khushalsagar): This should probably be removed if the copy constructor + // for ScrollTree copies the |layer_id_to_scroll_offset_map_| as well. + layer_id_to_scroll_offset_map_.clear(); for (int i = 0; i < data.layer_id_to_scroll_offset_map_size(); ++i) { const proto::ScrollOffsetMapEntry entry = data.layer_id_to_scroll_offset_map(i); @@ -1796,6 +1927,12 @@ bool PropertyTrees::operator==(const PropertyTrees& other) const { return transform_tree == other.transform_tree && effect_tree == other.effect_tree && clip_tree == other.clip_tree && scroll_tree == other.scroll_tree && + transform_id_to_index_map == other.transform_id_to_index_map && + effect_id_to_index_map == other.effect_id_to_index_map && + clip_id_to_index_map == other.clip_id_to_index_map && + scroll_id_to_index_map == other.scroll_id_to_index_map && + always_use_active_tree_opacity_effect_ids == + other.always_use_active_tree_opacity_effect_ids && needs_rebuild == other.needs_rebuild && changed == other.changed && full_tree_damaged == other.full_tree_damaged && is_main_thread == other.is_main_thread && @@ -1809,6 +1946,12 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) { effect_tree = from.effect_tree; clip_tree = from.clip_tree; scroll_tree = from.scroll_tree; + transform_id_to_index_map = from.transform_id_to_index_map; + effect_id_to_index_map = from.effect_id_to_index_map; + always_use_active_tree_opacity_effect_ids = + from.always_use_active_tree_opacity_effect_ids; + clip_id_to_index_map = from.clip_id_to_index_map; + scroll_id_to_index_map = from.scroll_id_to_index_map; needs_rebuild = from.needs_rebuild; changed = from.changed; full_tree_damaged = from.full_tree_damaged; @@ -1846,14 +1989,18 @@ void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const { // TODO(khushalsagar): Consider using the sequence number to decide if // property trees need to be serialized again for a commit. See crbug/555370. proto->set_sequence_number(sequence_number); + + for (auto i : always_use_active_tree_opacity_effect_ids) + proto->add_always_use_active_tree_opacity_effect_ids(i); } // static void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { - transform_tree.FromProtobuf(proto.transform_tree()); - effect_tree.FromProtobuf(proto.effect_tree()); - clip_tree.FromProtobuf(proto.clip_tree()); - scroll_tree.FromProtobuf(proto.scroll_tree()); + transform_tree.FromProtobuf(proto.transform_tree(), + &transform_id_to_index_map); + effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map); + clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map); + scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map); needs_rebuild = proto.needs_rebuild(); changed = proto.changed(); @@ -1867,6 +2014,8 @@ void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { effect_tree.SetPropertyTrees(this); clip_tree.SetPropertyTrees(this); scroll_tree.SetPropertyTrees(this); + for (auto i : proto.always_use_active_tree_opacity_effect_ids()) + always_use_active_tree_opacity_effect_ids.push_back(i); } void PropertyTrees::SetInnerViewportContainerBoundsDelta( @@ -1892,6 +2041,23 @@ void PropertyTrees::SetInnerViewportScrollBoundsDelta( inner_viewport_scroll_bounds_delta_ = bounds_delta; } +void PropertyTrees::PushOpacityIfNeeded(PropertyTrees* target_tree) { + for (int id : target_tree->always_use_active_tree_opacity_effect_ids) { + if (effect_id_to_index_map.find(id) == effect_id_to_index_map.end()) + continue; + EffectNode* source_effect_node = + effect_tree.Node(effect_id_to_index_map[id]); + EffectNode* target_effect_node = + target_tree->effect_tree.Node(target_tree->effect_id_to_index_map[id]); + float source_opacity = source_effect_node->data.opacity; + float target_opacity = target_effect_node->data.opacity; + if (source_opacity == target_opacity) + continue; + target_effect_node->data.opacity = source_opacity; + target_tree->effect_tree.set_needs_update(true); + } +} + void PropertyTrees::UpdateChangeTracking() { for (int id = 1; id < static_cast<int>(effect_tree.size()); ++id) { EffectNode* node = effect_tree.Node(id); @@ -1927,20 +2093,36 @@ void PropertyTrees::PushChangeTrackingTo(PropertyTrees* tree) { tree->full_tree_damaged = full_tree_damaged; } -void PropertyTrees::ResetAllChangeTracking(ResetFlags flag) { - switch (flag) { - case EFFECT_TREE: - effect_tree.ResetChangeTracking(); - break; - case TRANSFORM_TREE: - transform_tree.ResetChangeTracking(); - break; - case ALL_TREES: - transform_tree.ResetChangeTracking(); - effect_tree.ResetChangeTracking(); - } +void PropertyTrees::ResetAllChangeTracking() { + transform_tree.ResetChangeTracking(); + effect_tree.ResetChangeTracking(); changed = false; full_tree_damaged = false; } +std::unique_ptr<base::trace_event::TracedValue> PropertyTrees::AsTracedValue() + const { + auto value = base::WrapUnique(new base::trace_event::TracedValue); + + value->SetInteger("sequence_number", sequence_number); + + value->BeginDictionary("transform_tree"); + transform_tree.AsValueInto(value.get()); + value->EndDictionary(); + + value->BeginDictionary("effect_tree"); + effect_tree.AsValueInto(value.get()); + value->EndDictionary(); + + value->BeginDictionary("clip_tree"); + clip_tree.AsValueInto(value.get()); + value->EndDictionary(); + + value->BeginDictionary("scroll_tree"); + scroll_tree.AsValueInto(value.get()); + value->EndDictionary(); + + return value; +} + } // namespace cc diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index d22f491fd5b..2aab157ea51 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -7,6 +7,7 @@ #include <stddef.h> +#include <memory> #include <unordered_map> #include <vector> @@ -16,6 +17,12 @@ #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/transform.h" +namespace base { +namespace trace_event { +class TracedValue; +} +} + namespace cc { namespace proto { @@ -30,6 +37,7 @@ class TreeNode; } class LayerTreeImpl; +class RenderSurfaceImpl; class ScrollState; struct ScrollAndScaleSet; @@ -54,6 +62,8 @@ struct CC_EXPORT TreeNode { void ToProtobuf(proto::TreeNode* proto) const; void FromProtobuf(const proto::TreeNode& proto); + + void AsValueInto(base::trace_event::TracedValue* value) const; }; struct CC_EXPORT TransformNodeData { @@ -108,10 +118,13 @@ struct CC_EXPORT TransformNodeData { // TODO(vollick): will be moved when accelerated effects are implemented. bool needs_local_transform_update : 1; + bool node_and_ancestors_are_animated_or_invertible : 1; + bool is_invertible : 1; bool ancestors_are_invertible : 1; - bool is_animated : 1; + bool has_potential_animation : 1; + bool is_currently_animating : 1; bool to_screen_is_potentially_animated : 1; bool has_only_translation_animations : 1; bool to_screen_has_scale_animation : 1; @@ -195,6 +208,8 @@ struct CC_EXPORT TransformNodeData { void ToProtobuf(proto::TreeNode* proto) const; void FromProtobuf(const proto::TreeNode& proto); + + void AsValueInto(base::trace_event::TracedValue* value) const; }; typedef TreeNode<TransformNodeData> TransformNode; @@ -249,6 +264,7 @@ struct CC_EXPORT ClipNodeData { void ToProtobuf(proto::TreeNode* proto) const; void FromProtobuf(const proto::TreeNode& proto); + void AsValueInto(base::trace_event::TracedValue* value) const; }; typedef TreeNode<ClipNodeData> ClipNode; @@ -261,27 +277,32 @@ struct CC_EXPORT EffectNodeData { float screen_space_opacity; bool has_render_surface; + RenderSurfaceImpl* render_surface; bool has_copy_request; bool has_background_filters; - bool node_or_ancestor_has_background_filters; - bool to_screen_opacity_is_animated; bool hidden_by_backface_visibility; bool double_sided; bool is_drawn; - bool has_animated_opacity; + // TODO(jaydasika) : Delete this after implementation of + // SetHideLayerAndSubtree is cleaned up. (crbug.com/595843) + bool subtree_hidden; + bool has_potential_opacity_animation; + bool is_currently_animating_opacity; // We need to track changes to effects on the compositor to compute damage // rect. bool effect_changed; int num_copy_requests_in_subtree; + bool has_unclipped_descendants; int transform_id; int clip_id; - // For a node that creates a render surface, target_id is its own id. + // Effect node id of which this effect contributes to. int target_id; bool operator==(const EffectNodeData& other) const; void ToProtobuf(proto::TreeNode* proto) const; void FromProtobuf(const proto::TreeNode& proto); + void AsValueInto(base::trace_event::TracedValue* value) const; }; typedef TreeNode<EffectNodeData> EffectNode; @@ -304,11 +325,14 @@ struct CC_EXPORT ScrollNodeData { bool user_scrollable_vertical; int element_id; int transform_id; + // Number of drawn layers pointing to this node or any of its descendants. + int num_drawn_descendants; bool operator==(const ScrollNodeData& other) const; void ToProtobuf(proto::TreeNode* proto) const; void FromProtobuf(const proto::TreeNode& proto); + void AsValueInto(base::trace_event::TracedValue* value) const; }; typedef TreeNode<ScrollNodeData> ScrollNode; @@ -319,7 +343,7 @@ template <typename T> class CC_EXPORT PropertyTree { public: PropertyTree(); - virtual ~PropertyTree(); + ~PropertyTree(); bool operator==(const PropertyTree<T>& other) const; @@ -344,7 +368,7 @@ class CC_EXPORT PropertyTree { return size() ? &nodes_[nodes_.size() - 1] : nullptr; } - virtual void clear(); + void clear(); size_t size() const { return nodes_.size(); } void set_needs_update(bool needs_update) { needs_update_ = needs_update; } @@ -356,13 +380,16 @@ class CC_EXPORT PropertyTree { int next_available_id() const { return static_cast<int>(size()); } void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto); + void FromProtobuf(const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map); void SetPropertyTrees(PropertyTrees* property_trees) { property_trees_ = property_trees; } PropertyTrees* property_trees() const { return property_trees_; } + void AsValueInto(base::trace_event::TracedValue* value) const; + private: // Copy and assign are permitted. This is how we do tree sync. std::vector<T> nodes_; @@ -375,11 +402,11 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { public: TransformTree(); TransformTree(const TransformTree& other); - ~TransformTree() override; + ~TransformTree(); bool operator==(const TransformTree& other) const; - void clear() override; + void clear(); // 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 @@ -421,6 +448,9 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { void UpdateTransformChanged(TransformNode* node, TransformNode* parent_node, TransformNode* source_node); + void UpdateNodeAndAncestorsAreAnimatedOrInvertible( + TransformNode* node, + TransformNode* parent_node); // 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 @@ -478,7 +508,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { gfx::Transform ToScreenSpaceTransformWithoutSublayerScale(int id) const; void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto); + void FromProtobuf(const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map); private: // Returns true iff the node at |desc_id| is a descendant of the node at @@ -534,13 +565,16 @@ class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> { gfx::RectF ViewportClip(); void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto); + void FromProtobuf(const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map); }; class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { public: bool operator==(const EffectTree& other) const; + float EffectiveOpacity(const EffectNode* node) const; + void UpdateEffects(int id); void UpdateEffectChanged(EffectNode* node, EffectNode* parent_node); @@ -552,7 +586,8 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { void ResetChangeTracking(); void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto); + void FromProtobuf(const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map); private: void UpdateOpacities(EffectNode* node, EffectNode* parent_node); @@ -564,15 +599,16 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { public: ScrollTree(); ScrollTree(const ScrollTree& other); - ~ScrollTree() override; + ~ScrollTree(); ScrollTree& operator=(const ScrollTree& from); bool operator==(const ScrollTree& other) const; void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto); + void FromProtobuf(const proto::PropertyTree& proto, + std::unordered_map<int, int>* node_id_to_index_map); - void clear() override; + void clear(); typedef std::unordered_map<int, scoped_refptr<SyncedScrollOffset>> ScrollOffsetMap; @@ -636,6 +672,12 @@ class CC_EXPORT PropertyTrees final { void ToProtobuf(proto::PropertyTrees* proto) const; void FromProtobuf(const proto::PropertyTrees& proto); + std::unordered_map<int, int> transform_id_to_index_map; + std::unordered_map<int, int> effect_id_to_index_map; + std::unordered_map<int, int> clip_id_to_index_map; + std::unordered_map<int, int> scroll_id_to_index_map; + + std::vector<int> always_use_active_tree_opacity_effect_ids; TransformTree transform_tree; EffectTree effect_tree; ClipTree clip_tree; @@ -656,14 +698,14 @@ class CC_EXPORT PropertyTrees final { int sequence_number; bool is_main_thread; bool is_active; - enum ResetFlags { EFFECT_TREE, TRANSFORM_TREE, ALL_TREES }; void SetInnerViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetOuterViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetInnerViewportScrollBoundsDelta(gfx::Vector2dF bounds_delta); + void PushOpacityIfNeeded(PropertyTrees* target_tree); void UpdateChangeTracking(); void PushChangeTrackingTo(PropertyTrees* tree); - void ResetAllChangeTracking(ResetFlags flag); + void ResetAllChangeTracking(); gfx::Vector2dF inner_viewport_container_bounds_delta() const { return inner_viewport_container_bounds_delta_; @@ -677,6 +719,8 @@ class CC_EXPORT PropertyTrees final { return inner_viewport_scroll_bounds_delta_; } + std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const; + private: gfx::Vector2dF inner_viewport_container_bounds_delta_; gfx::Vector2dF outer_viewport_container_bounds_delta_; diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index 7b4300b9fab..bd824ed1266 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -26,13 +26,11 @@ namespace { static const int kInvalidPropertyTreeNodeId = -1; static const int kRootPropertyTreeNodeId = 0; +static const int kViewportClipTreeNodeId = 1; template <typename LayerType> struct DataForRecursion { - TransformTree* transform_tree; - ClipTree* clip_tree; - EffectTree* effect_tree; - ScrollTree* scroll_tree; + PropertyTrees* property_trees; LayerType* transform_tree_parent; LayerType* transform_fixed_parent; int render_target; @@ -57,7 +55,6 @@ struct DataForRecursion { gfx::Vector2dF scroll_snap; gfx::Transform compound_transform_since_render_target; bool axis_align_since_render_target; - int sequence_number; SkColor safe_opaque_background_color; }; @@ -72,10 +69,137 @@ struct DataForRecursionFromChild { } }; +static LayerPositionConstraint PositionConstraint(Layer* layer) { + return layer->position_constraint(); +} + +static LayerPositionConstraint PositionConstraint(LayerImpl* layer) { + return layer->test_properties()->position_constraint; +} + +struct PreCalculateMetaInformationRecursiveData { + size_t num_unclipped_descendants; + int num_descendants_that_draw_content; + + PreCalculateMetaInformationRecursiveData() + : num_unclipped_descendants(0), + num_descendants_that_draw_content(0) {} + + void Merge(const PreCalculateMetaInformationRecursiveData& data) { + num_unclipped_descendants += data.num_unclipped_descendants; + num_descendants_that_draw_content += data.num_descendants_that_draw_content; + } +}; + +static inline bool IsRootLayer(const Layer* layer) { + return !layer->parent(); +} + +static bool IsMetaInformationRecomputationNeeded(Layer* layer) { + return layer->layer_tree_host()->needs_meta_info_recomputation(); +} + +// Recursively walks the layer tree(if needed) to compute any information +// that is needed before doing the main recursion. +static void PreCalculateMetaInformationInternal( + Layer* layer, + PreCalculateMetaInformationRecursiveData* recursive_data) { + if (!IsMetaInformationRecomputationNeeded(layer)) { + DCHECK(IsRootLayer(layer)); + return; + } + + if (layer->clip_parent()) + recursive_data->num_unclipped_descendants++; + + 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); + recursive_data->Merge(data_for_child); + } + + if (layer->clip_children()) { + 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; + } + + layer->set_num_unclipped_descendants( + recursive_data->num_unclipped_descendants); + + if (IsRootLayer(layer)) + layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false); +} + +static void PreCalculateMetaInformationInternalForTesting( + LayerImpl* layer, + PreCalculateMetaInformationRecursiveData* recursive_data) { + if (layer->test_properties()->clip_parent) + recursive_data->num_unclipped_descendants++; + + for (size_t i = 0; i < layer->children().size(); ++i) { + LayerImpl* child_layer = layer->child_at(i); + + PreCalculateMetaInformationRecursiveData data_for_child; + PreCalculateMetaInformationInternalForTesting(child_layer, &data_for_child); + recursive_data->Merge(data_for_child); + } + + if (layer->test_properties()->clip_children) { + size_t num_clip_children = layer->test_properties()->clip_children->size(); + DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children); + recursive_data->num_unclipped_descendants -= num_clip_children; + } + + layer->test_properties()->num_unclipped_descendants = + recursive_data->num_unclipped_descendants; + // TODO(enne): this should be synced from the main thread, so is only + // for tests constructing layers on the compositor thread. + layer->test_properties()->num_descendants_that_draw_content = + recursive_data->num_descendants_that_draw_content; + + if (layer->DrawsContent()) + recursive_data->num_descendants_that_draw_content++; +} + +static Layer* ScrollParent(Layer* layer) { + return layer->scroll_parent(); +} + +static LayerImpl* ScrollParent(LayerImpl* layer) { + return layer->test_properties()->scroll_parent; +} + +static std::set<Layer*>* ScrollChildren(Layer* layer) { + return layer->scroll_children(); +} + +static std::set<LayerImpl*>* ScrollChildren(LayerImpl* layer) { + return layer->test_properties()->scroll_children.get(); +} + +static Layer* ClipParent(Layer* layer) { + return layer->clip_parent(); +} + +static LayerImpl* ClipParent(LayerImpl* layer) { + return layer->test_properties()->clip_parent; +} + +static size_t NumUnclippedDescendants(Layer* layer) { + return layer->num_unclipped_descendants(); +} + +static size_t NumUnclippedDescendants(LayerImpl* layer) { + return layer->test_properties()->num_unclipped_descendants; +} + template <typename LayerType> static LayerType* GetTransformParent(const DataForRecursion<LayerType>& data, LayerType* layer) { - return layer->position_constraint().is_fixed_position() + return PositionConstraint(layer).is_fixed_position() ? data.transform_fixed_parent : data.transform_tree_parent; } @@ -83,10 +207,10 @@ static LayerType* GetTransformParent(const DataForRecursion<LayerType>& data, template <typename LayerType> static ClipNode* GetClipParent(const DataForRecursion<LayerType>& data, LayerType* layer) { - const bool inherits_clip = !layer->clip_parent(); + const bool inherits_clip = !ClipParent(layer); const int id = inherits_clip ? data.clip_tree_parent - : layer->clip_parent()->clip_tree_index(); - return data.clip_tree->Node(id); + : ClipParent(layer)->clip_tree_index(); + return data.property_trees->clip_tree.Node(id); } template <typename LayerType> @@ -97,9 +221,9 @@ static bool LayerClipsSubtree(LayerType* layer) { template <typename LayerType> static int GetScrollParentId(const DataForRecursion<LayerType>& data, LayerType* layer) { - const bool inherits_scroll = !layer->scroll_parent(); + const bool inherits_scroll = !ScrollParent(layer); const int id = inherits_scroll ? data.scroll_tree_parent - : layer->scroll_parent()->scroll_tree_index(); + : ScrollParent(layer)->scroll_tree_index(); return id; } @@ -126,7 +250,7 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, // However, if the surface has unclipped descendants (layers that aren't // affected by the ancestor clip), we cannot clip the surface itself, and // must instead apply clips to the clipped descendants. - if (ancestor_clips_subtree && layer->num_unclipped_descendants() > 0) { + if (ancestor_clips_subtree && NumUnclippedDescendants(layer) > 0) { layers_are_clipped = true; } else if (!ancestor_clips_subtree) { // When there are no ancestor clips that need to be applied to a render @@ -140,7 +264,7 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, // clip at draw time since the unclipped descendants aren't affected by the // ancestor clip. data_for_children->target_is_clipped = - ancestor_clips_subtree && !layer->num_unclipped_descendants(); + ancestor_clips_subtree && !NumUnclippedDescendants(layer); } else { // Without a new render surface, layer clipping state from ancestors needs // to continue to propagate. @@ -169,7 +293,7 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, parent->data.layers_are_clipped_when_surfaces_disabled); } else { LayerType* transform_parent = data_for_children->transform_tree_parent; - if (layer->position_constraint().is_fixed_position() && + if (PositionConstraint(layer).is_fixed_position() && !created_transform_node) { transform_parent = data_for_children->transform_fixed_parent; } @@ -178,16 +302,16 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(), gfx::SizeF(layer->bounds())); node.data.transform_id = transform_parent->transform_tree_index(); - node.data.target_id = - data_for_children->effect_tree->Node(data_for_children->render_target) - ->data.transform_id; + node.data.target_id = data_for_children->property_trees->effect_tree + .Node(data_for_children->render_target) + ->data.transform_id; node.owner_id = layer->id(); if (ancestor_clips_subtree || layer_clips_subtree) { // Surfaces reset the rect used for layer clipping. At other nodes, layer // clipping state from ancestors must continue to get propagated. node.data.layer_clipping_uses_only_local_clip = - (created_render_surface && layer->num_unclipped_descendants() == 0) || + (created_render_surface && NumUnclippedDescendants(layer) == 0) || !ancestor_clips_subtree; } else { // Otherwise, we're either unclipped, or exist only in order to apply our @@ -203,7 +327,9 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, layers_are_clipped_when_surfaces_disabled; data_for_children->clip_tree_parent = - data_for_children->clip_tree->Insert(node, parent_id); + data_for_children->property_trees->clip_tree.Insert(node, parent_id); + data_for_children->property_trees->clip_id_to_index_map[layer->id()] = + data_for_children->clip_tree_parent; } layer->SetClipTreeIndex(data_for_children->clip_tree_parent); @@ -220,6 +346,30 @@ static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { : layer->Is3dSorted(); } +static inline gfx::Point3F TransformOrigin(Layer* layer) { + return layer->transform_origin(); +} + +static inline gfx::Point3F TransformOrigin(LayerImpl* layer) { + return layer->test_properties()->transform_origin; +} + +static inline bool IsContainerForFixedPositionLayers(Layer* layer) { + return layer->IsContainerForFixedPositionLayers(); +} + +static inline bool IsContainerForFixedPositionLayers(LayerImpl* layer) { + return layer->test_properties()->is_container_for_fixed_position_layers; +} + +static inline bool ShouldFlattenTransform(Layer* layer) { + return layer->should_flatten_transform(); +} + +static inline bool ShouldFlattenTransform(LayerImpl* layer) { + return layer->test_properties()->should_flatten_transform; +} + template <typename LayerType> bool AddTransformNodeIfNeeded( const DataForRecursion<LayerType>& data_from_ancestor, @@ -231,7 +381,7 @@ bool AddTransformNodeIfNeeded( const bool is_overscroll_elasticity_layer = layer == data_from_ancestor.overscroll_elasticity_layer; const bool is_scrollable = layer->scrollable(); - const bool is_fixed = layer->position_constraint().is_fixed_position(); + const bool is_fixed = PositionConstraint(layer).is_fixed_position(); const bool has_significant_transform = !layer->transform().IsIdentityOr2DTranslation(); @@ -252,9 +402,9 @@ bool AddTransformNodeIfNeeded( // a scroll child's render target is different from the scroll parent's render // target. const bool scroll_child_has_different_target = - layer->scroll_parent() && + ScrollParent(layer) && layer->parent()->effect_tree_index() != - layer->scroll_parent()->effect_tree_index(); + ScrollParent(layer)->effect_tree_index(); const bool is_at_boundary_of_3d_rendering_context = IsAtBoundaryOf3dRenderingContext(layer); @@ -276,7 +426,7 @@ bool AddTransformNodeIfNeeded( gfx::Vector2dF source_offset; if (transform_parent) { - if (layer->scroll_parent()) { + if (ScrollParent(layer)) { LayerType* source = layer->parent(); source_offset += source->offset_to_transform_parent(); source_index = source->transform_tree_index(); @@ -291,7 +441,7 @@ bool AddTransformNodeIfNeeded( } } - if (layer->IsContainerForFixedPositionLayers() || is_root) { + if (IsContainerForFixedPositionLayers(layer) || 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 = @@ -306,17 +456,17 @@ bool AddTransformNodeIfNeeded( } data_for_children->transform_tree_parent = layer; - if (layer->IsContainerForFixedPositionLayers() || is_fixed) + if (IsContainerForFixedPositionLayers(layer) || is_fixed) data_for_children->scroll_snap = gfx::Vector2dF(); if (!requires_node) { - data_for_children->should_flatten |= layer->should_flatten_transform(); + data_for_children->should_flatten |= ShouldFlattenTransform(layer); gfx::Vector2dF local_offset = layer->position().OffsetFromOrigin() + layer->transform().To2dTranslation(); gfx::Vector2dF source_to_parent; if (source_index != parent_index) { gfx::Transform to_parent; - data_from_ancestor.transform_tree->ComputeTransform( + data_from_ancestor.property_trees->transform_tree.ComputeTransform( source_index, parent_index, &to_parent); source_to_parent = to_parent.To2dTranslation(); } @@ -330,10 +480,14 @@ bool AddTransformNodeIfNeeded( return false; } - data_for_children->transform_tree->Insert(TransformNode(), parent_index); + data_for_children->property_trees->transform_tree.Insert(TransformNode(), + parent_index); - TransformNode* node = data_for_children->transform_tree->back(); + TransformNode* node = + data_for_children->property_trees->transform_tree.back(); layer->SetTransformTreeIndex(node->id); + data_for_children->property_trees->transform_id_to_index_map[layer->id()] = + node->id; if (layer->mask_layer()) layer->mask_layer()->SetTransformTreeIndex(node->id); @@ -349,18 +503,18 @@ bool AddTransformNodeIfNeeded( // Surfaces inherently flatten transforms. data_for_children->should_flatten = - layer->should_flatten_transform() || has_surface; - DCHECK_GT(data_from_ancestor.effect_tree->size(), 0u); - - node->data.target_id = - data_for_children->effect_tree->Node(data_from_ancestor.render_target) - ->data.transform_id; - node->data.content_target_id = - data_for_children->effect_tree->Node(data_for_children->render_target) - ->data.transform_id; + ShouldFlattenTransform(layer) || has_surface; + DCHECK_GT(data_from_ancestor.property_trees->effect_tree.size(), 0u); + + node->data.target_id = data_for_children->property_trees->effect_tree + .Node(data_from_ancestor.render_target) + ->data.transform_id; + node->data.content_target_id = data_for_children->property_trees->effect_tree + .Node(data_for_children->render_target) + ->data.transform_id; DCHECK_NE(node->data.target_id, kInvalidPropertyTreeNodeId); - node->data.is_animated = has_potentially_animated_transform; + node->data.has_potential_animation = has_potentially_animated_transform; if (has_potentially_animated_transform) { float maximum_animation_target_scale = 0.f; if (layer->MaximumTargetScale(&maximum_animation_target_scale)) { @@ -380,11 +534,11 @@ bool AddTransformNodeIfNeeded( float post_local_scale_factor = 1.0f; if (is_root) post_local_scale_factor = - data_for_children->transform_tree->device_scale_factor(); + data_for_children->property_trees->transform_tree.device_scale_factor(); if (is_page_scale_layer) { post_local_scale_factor *= data_from_ancestor.page_scale_factor; - data_for_children->transform_tree->set_page_scale_factor( + data_for_children->property_trees->transform_tree.set_page_scale_factor( data_from_ancestor.page_scale_factor); } @@ -394,53 +548,53 @@ bool AddTransformNodeIfNeeded( node->data.source_node_id = source_index; node->data.post_local_scale_factor = post_local_scale_factor; if (is_root) { - data_for_children->transform_tree->SetDeviceTransform( + data_for_children->property_trees->transform_tree.SetDeviceTransform( *data_from_ancestor.device_transform, layer->position()); - data_for_children->transform_tree->SetDeviceTransformScaleFactor( - *data_from_ancestor.device_transform); + data_for_children->property_trees->transform_tree + .SetDeviceTransformScaleFactor(*data_from_ancestor.device_transform); } else { node->data.source_offset = source_offset; node->data.update_post_local_transform(layer->position(), - layer->transform_origin()); + TransformOrigin(layer)); } if (is_overscroll_elasticity_layer) { DCHECK(!is_scrollable); node->data.scroll_offset = gfx::ScrollOffset(data_from_ancestor.elastic_overscroll); - } else if (!layer->scroll_parent()) { + } else if (!ScrollParent(layer)) { 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(); + PositionConstraint(layer).is_fixed_to_right_edge(); node->data.affected_by_inner_viewport_bounds_delta_y = - layer->position_constraint().is_fixed_to_bottom_edge(); + PositionConstraint(layer).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); + data_for_children->property_trees->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(); + PositionConstraint(layer).is_fixed_to_right_edge(); node->data.affected_by_outer_viewport_bounds_delta_y = - layer->position_constraint().is_fixed_to_bottom_edge(); + PositionConstraint(layer).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); + data_for_children->property_trees->transform_tree + .AddNodeAffectedByOuterViewportBoundsDelta(node->id); } } } node->data.local = layer->transform(); - node->data.update_pre_local_transform(layer->transform_origin()); + node->data.update_pre_local_transform(TransformOrigin(layer)); node->data.needs_local_transform_update = true; - data_from_ancestor.transform_tree->UpdateTransforms(node->id); + data_from_ancestor.property_trees->transform_tree.UpdateTransforms(node->id); layer->set_offset_to_transform_parent(gfx::Vector2dF()); @@ -454,15 +608,31 @@ bool AddTransformNodeIfNeeded( return true; } -bool IsAnimatingOpacity(Layer* layer) { +static inline bool HasPotentialOpacityAnimation(Layer* layer) { return layer->HasPotentiallyRunningOpacityAnimation() || layer->OpacityCanAnimateOnImplThread(); } -bool IsAnimatingOpacity(LayerImpl* layer) { +static inline bool HasPotentialOpacityAnimation(LayerImpl* layer) { return layer->HasPotentiallyRunningOpacityAnimation(); } +static inline bool DoubleSided(Layer* layer) { + return layer->double_sided(); +} + +static inline bool DoubleSided(LayerImpl* layer) { + return layer->test_properties()->double_sided; +} + +static inline bool ForceRenderSurface(Layer* layer) { + return layer->force_render_surface_for_testing(); +} + +static inline bool ForceRenderSurface(LayerImpl* layer) { + return layer->test_properties()->force_render_surface; +} + template <typename LayerType> static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) { return layer->Is3dSorted() && layer->parent() && @@ -470,6 +640,47 @@ static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) { (layer->parent()->sorting_context_id() == layer->sorting_context_id()); } +static inline bool IsRootForIsolatedGroup(Layer* layer) { + return layer->is_root_for_isolated_group(); +} + +static inline bool IsRootForIsolatedGroup(LayerImpl* layer) { + return false; +} + +static inline int NumDescendantsThatDrawContent(Layer* layer) { + return layer->NumDescendantsThatDrawContent(); +} + +static inline int NumDescendantsThatDrawContent(LayerImpl* layer) { + return layer->test_properties()->num_descendants_that_draw_content; +} + +static inline float EffectiveOpacity(Layer* layer) { + return layer->EffectiveOpacity(); +} + +static inline float EffectiveOpacity(LayerImpl* layer) { + return layer->test_properties()->hide_layer_and_subtree ? 0.f + : layer->opacity(); +} + +static inline bool HideLayerAndSubtree(Layer* layer) { + return layer->hide_layer_and_subtree(); +} + +static inline bool HideLayerAndSubtree(LayerImpl* layer) { + return layer->test_properties()->hide_layer_and_subtree; +} + +static inline bool AlwaysUseActiveTreeOpacity(Layer* layer) { + return layer->AlwaysUseActiveTreeOpacity(); +} + +static inline bool AlwaysUseActiveTreeOpacity(LayerImpl* layer) { + return false; +} + template <typename LayerType> bool ShouldCreateRenderSurface(LayerType* layer, gfx::Transform current_transform, @@ -503,14 +714,12 @@ bool ShouldCreateRenderSurface(LayerType* layer, return true; } - int num_descendants_that_draw_content = - layer->NumDescendantsThatDrawContent(); + int num_descendants_that_draw_content = NumDescendantsThatDrawContent(layer); // If the layer flattens its subtree, but it is treated as a 3D object by its // parent (i.e. parent participates in a 3D rendering context). if (LayerIsInExisting3DRenderingContext(layer) && - layer->should_flatten_transform() && - num_descendants_that_draw_content > 0) { + ShouldFlattenTransform(layer) && num_descendants_that_draw_content > 0) { TRACE_EVENT_INSTANT0( "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface flattening", TRACE_EVENT_SCOPE_THREAD); @@ -547,7 +756,7 @@ bool ShouldCreateRenderSurface(LayerType* layer, num_descendants_that_draw_content > 0 && (layer->DrawsContent() || num_descendants_that_draw_content > 1); - if (layer->EffectiveOpacity() != 1.f && layer->should_flatten_transform() && + if (EffectiveOpacity(layer) != 1.f && ShouldFlattenTransform(layer) && at_least_two_layers_in_subtree_draw_content) { TRACE_EVENT_INSTANT0( "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface opacity", @@ -560,7 +769,7 @@ bool ShouldCreateRenderSurface(LayerType* layer, // the blending descendants might have access to the content behind this layer // (layer has transparent background or descendants overflow). // https://code.google.com/p/chromium/issues/detail?id=301738 - if (layer->is_root_for_isolated_group()) { + if (IsRootForIsolatedGroup(layer)) { TRACE_EVENT_INSTANT0( "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface isolation", TRACE_EVENT_SCOPE_THREAD); @@ -568,7 +777,7 @@ bool ShouldCreateRenderSurface(LayerType* layer, } // If we force it. - if (layer->force_render_surface()) + if (ForceRenderSurface(layer)) return true; // If we'll make a copy of the layer's contents. @@ -584,15 +793,17 @@ bool AddEffectNodeIfNeeded( LayerType* layer, DataForRecursion<LayerType>* data_for_children) { const bool is_root = !layer->parent(); - const bool has_transparency = layer->EffectiveOpacity() != 1.f; - const bool has_animated_opacity = IsAnimatingOpacity(layer); + const bool has_transparency = EffectiveOpacity(layer) != 1.f; + const bool has_potential_opacity_animation = + HasPotentialOpacityAnimation(layer); const bool should_create_render_surface = ShouldCreateRenderSurface( layer, data_from_ancestor.compound_transform_since_render_target, data_from_ancestor.axis_align_since_render_target); data_for_children->axis_align_since_render_target &= layer->AnimationsPreserveAxisAlignment(); - bool requires_node = is_root || has_transparency || has_animated_opacity || + bool requires_node = is_root || has_transparency || + has_potential_opacity_animation || should_create_render_surface; int parent_id = data_from_ancestor.effect_tree_parent; @@ -607,12 +818,19 @@ bool AddEffectNodeIfNeeded( EffectNode node; node.owner_id = layer->id(); - node.data.opacity = layer->EffectiveOpacity(); + if (AlwaysUseActiveTreeOpacity(layer)) { + data_for_children->property_trees->always_use_active_tree_opacity_effect_ids + .push_back(node.owner_id); + } + + node.data.opacity = layer->opacity(); node.data.has_render_surface = should_create_render_surface; node.data.has_copy_request = layer->HasCopyRequest(); node.data.has_background_filters = !layer->background_filters().IsEmpty(); - node.data.has_animated_opacity = has_animated_opacity; - node.data.double_sided = layer->double_sided(); + node.data.has_potential_opacity_animation = has_potential_opacity_animation; + node.data.double_sided = DoubleSided(layer); + node.data.subtree_hidden = HideLayerAndSubtree(layer); + node.data.is_currently_animating_opacity = layer->OpacityIsAnimating(); if (!is_root) { // The effect node's transform id is used only when we create a render @@ -623,33 +841,24 @@ bool AddEffectNodeIfNeeded( // next available id from the transform tree as this effect node's // transform id. node.data.transform_id = - data_from_ancestor.transform_tree->next_available_id(); + data_from_ancestor.property_trees->transform_tree.next_available_id(); + node.data.has_unclipped_descendants = + (NumUnclippedDescendants(layer) != 0); } node.data.clip_id = data_from_ancestor.clip_tree_parent; - EffectNode* parent_node = data_for_children->effect_tree->Node(parent_id); - node.data.node_or_ancestor_has_background_filters = - parent_node->data.node_or_ancestor_has_background_filters || - node.data.has_background_filters; - node.data.to_screen_opacity_is_animated = - parent_node->data.to_screen_opacity_is_animated || has_animated_opacity; } else { // Root render surface acts the unbounded and untransformed to draw content // into. Transform node created from root layer (includes device scale // factor) and clip node created from root layer (include viewports) applies // to root render surface's content, but not root render surface itself. node.data.transform_id = kRootPropertyTreeNodeId; - node.data.clip_id = kRootPropertyTreeNodeId; - node.data.node_or_ancestor_has_background_filters = - node.data.has_background_filters; - node.data.to_screen_opacity_is_animated = has_animated_opacity; - } - node.data.target_id = - should_create_render_surface - ? data_from_ancestor.effect_tree->next_available_id() - : data_for_children->render_target; + node.data.clip_id = kViewportClipTreeNodeId; + } data_for_children->effect_tree_parent = - data_for_children->effect_tree->Insert(node, parent_id); + data_for_children->property_trees->effect_tree.Insert(node, parent_id); layer->SetEffectTreeIndex(data_for_children->effect_tree_parent); + data_for_children->property_trees->effect_id_to_index_map[layer->id()] = + data_for_children->effect_tree_parent; if (should_create_render_surface) { data_for_children->compound_transform_since_render_target = gfx::Transform(); @@ -700,8 +909,8 @@ void AddScrollNodeIfNeeded( DCHECK(layer->scroll_clip_layer()->transform_tree_index() != kInvalidPropertyTreeNodeId); node.data.max_scroll_offset_affected_by_page_scale = - !data_from_ancestor.transform_tree - ->Node(layer->scroll_clip_layer()->transform_tree_index()) + !data_from_ancestor.property_trees->transform_tree + .Node(layer->scroll_clip_layer()->transform_tree_index()) ->data.in_subtree_of_page_scale_layer && data_from_ancestor.in_subtree_of_page_scale_layer; } @@ -723,14 +932,16 @@ void AddScrollNodeIfNeeded( data_for_children->transform_tree_parent->transform_tree_index(); data_for_children->scroll_tree_parent = - data_for_children->scroll_tree->Insert(node, parent_id); + data_for_children->property_trees->scroll_tree.Insert(node, parent_id); data_for_children->main_thread_scrolling_reasons = node.data.main_thread_scrolling_reasons; data_for_children->scroll_tree_parent_created_by_uninheritable_criteria = scroll_node_uninheritable_criteria; + data_for_children->property_trees->scroll_id_to_index_map[layer->id()] = + data_for_children->scroll_tree_parent; if (node.data.scrollable) { - data_for_children->scroll_tree->SetBaseScrollOffset( + data_for_children->property_trees->scroll_tree.SetBaseScrollOffset( layer->id(), layer->CurrentScrollOffset()); } } @@ -763,7 +974,7 @@ void SetBackfaceVisibilityTransform(LayerType* layer, layer->SetUseLocalTransformForBackfaceVisibility(use_local_transform); // A double-sided layer's backface can been shown when its visibile. - if (layer->double_sided()) + if (DoubleSided(layer)) layer->SetShouldCheckBackfaceVisibility(false); // The backface of a layer that uses local transform for backface visibility // is not visible when it does not create a transform node as its local @@ -802,10 +1013,11 @@ void BuildPropertyTreesInternal( LayerType* layer, const DataForRecursion<LayerType>& data_from_parent, DataForRecursionFromChild<LayerType>* data_to_parent) { - layer->set_property_tree_sequence_number(data_from_parent.sequence_number); + layer->set_property_tree_sequence_number( + data_from_parent.property_trees->sequence_number); if (layer->mask_layer()) layer->mask_layer()->set_property_tree_sequence_number( - data_from_parent.sequence_number); + data_from_parent.property_trees->sequence_number); DataForRecursion<LayerType> data_for_children(data_from_parent); @@ -831,7 +1043,7 @@ void BuildPropertyTreesInternal( for (size_t i = 0; i < layer->children().size(); ++i) { SetLayerPropertyChangedForChild(layer, layer->child_at(i)); - if (!layer->child_at(i)->scroll_parent()) { + if (!ScrollParent(layer->child_at(i))) { DataForRecursionFromChild<LayerType> data_from_child; BuildPropertyTreesInternal(layer->child_at(i), data_for_children, &data_from_child); @@ -839,14 +1051,14 @@ void BuildPropertyTreesInternal( } 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))); + DCHECK(ScrollChildren(ScrollParent(layer->child_at(i))) + ->count(layer->child_at(i))); } } - if (layer->scroll_children()) { - for (LayerType* scroll_child : *layer->scroll_children()) { - DCHECK_EQ(scroll_child->scroll_parent(), layer); + if (ScrollChildren(layer)) { + for (LayerType* scroll_child : *ScrollChildren(layer)) { + DCHECK_EQ(ScrollParent(scroll_child), layer); DataForRecursionFromChild<LayerType> data_from_child; DCHECK(scroll_child->parent()); data_for_children.effect_tree_parent = @@ -869,15 +1081,45 @@ void BuildPropertyTreesInternal( if (layer->HasCopyRequest()) data_to_parent->num_copy_requests_in_subtree++; - if (data_for_children.effect_tree->Node(data_for_children.effect_tree_parent) + if (data_for_children.property_trees->effect_tree + .Node(data_for_children.effect_tree_parent) ->owner_id == layer->id()) - data_for_children.effect_tree->Node(data_for_children.effect_tree_parent) + data_for_children.property_trees->effect_tree + .Node(data_for_children.effect_tree_parent) ->data.num_copy_requests_in_subtree = data_to_parent->num_copy_requests_in_subtree; } } // namespace +void CC_EXPORT +PropertyTreeBuilder::PreCalculateMetaInformation(Layer* root_layer) { + PreCalculateMetaInformationRecursiveData recursive_data; + PreCalculateMetaInformationInternal(root_layer, &recursive_data); +} + +void CC_EXPORT PropertyTreeBuilder::PreCalculateMetaInformationForTesting( + LayerImpl* root_layer) { + PreCalculateMetaInformationRecursiveData recursive_data; + PreCalculateMetaInformationInternalForTesting(root_layer, &recursive_data); +} + +Layer* PropertyTreeBuilder::FindFirstScrollableLayer(Layer* layer) { + if (!layer) + return nullptr; + + if (layer->scrollable()) + return layer; + + for (size_t i = 0; i < layer->children().size(); ++i) { + Layer* found = FindFirstScrollableLayer(layer->children()[i].get()); + if (found) + return found; + } + + return nullptr; +} + template <typename LayerType> void BuildPropertyTreesTopLevelInternal( LayerType* root_layer, @@ -907,10 +1149,7 @@ void BuildPropertyTreesTopLevelInternal( property_trees->sequence_number++; DataForRecursion<LayerType> data_for_recursion; - data_for_recursion.transform_tree = &property_trees->transform_tree; - data_for_recursion.clip_tree = &property_trees->clip_tree; - data_for_recursion.effect_tree = &property_trees->effect_tree; - data_for_recursion.scroll_tree = &property_trees->scroll_tree; + data_for_recursion.property_trees = property_trees; data_for_recursion.transform_tree_parent = nullptr; data_for_recursion.transform_fixed_parent = nullptr; data_for_recursion.render_target = kRootPropertyTreeNodeId; @@ -935,16 +1174,21 @@ void BuildPropertyTreesTopLevelInternal( true; data_for_recursion.device_transform = &device_transform; - data_for_recursion.transform_tree->clear(); - data_for_recursion.clip_tree->clear(); - data_for_recursion.effect_tree->clear(); - data_for_recursion.scroll_tree->clear(); + data_for_recursion.property_trees->transform_tree.clear(); + data_for_recursion.property_trees->clip_tree.clear(); + data_for_recursion.property_trees->effect_tree.clear(); + data_for_recursion.property_trees->scroll_tree.clear(); data_for_recursion.compound_transform_since_render_target = gfx::Transform(); data_for_recursion.axis_align_since_render_target = true; - data_for_recursion.sequence_number = property_trees->sequence_number; - data_for_recursion.transform_tree->set_device_scale_factor( + data_for_recursion.property_trees->transform_tree.set_device_scale_factor( device_scale_factor); data_for_recursion.safe_opaque_background_color = color; + data_for_recursion.property_trees->transform_id_to_index_map.clear(); + data_for_recursion.property_trees->effect_id_to_index_map.clear(); + data_for_recursion.property_trees->clip_id_to_index_map.clear(); + data_for_recursion.property_trees->scroll_id_to_index_map.clear(); + data_for_recursion.property_trees->always_use_active_tree_opacity_effect_ids + .clear(); ClipNode root_clip; root_clip.data.resets_clip = true; @@ -952,7 +1196,8 @@ void BuildPropertyTreesTopLevelInternal( root_clip.data.clip = gfx::RectF(viewport); root_clip.data.transform_id = kRootPropertyTreeNodeId; data_for_recursion.clip_tree_parent = - data_for_recursion.clip_tree->Insert(root_clip, kRootPropertyTreeNodeId); + data_for_recursion.property_trees->clip_tree.Insert( + root_clip, kRootPropertyTreeNodeId); DataForRecursionFromChild<LayerType> data_from_child; BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); @@ -967,6 +1212,27 @@ void BuildPropertyTreesTopLevelInternal( property_trees->scroll_tree.set_needs_update(false); } +#if DCHECK_IS_ON() +static void CheckScrollAndClipPointersForLayer(Layer* layer) { + if (!layer) + return; + + if (layer->scroll_children()) { + for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); + it != layer->scroll_children()->end(); ++it) { + DCHECK_EQ((*it)->scroll_parent(), layer); + } + } + + if (layer->clip_children()) { + for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); + it != layer->clip_children()->end(); ++it) { + DCHECK_EQ((*it)->clip_parent(), layer); + } + } +} +#endif + void PropertyTreeBuilder::BuildPropertyTrees( Layer* root_layer, const Layer* page_scale_layer, @@ -989,6 +1255,10 @@ void PropertyTreeBuilder::BuildPropertyTrees( outer_viewport_scroll_layer, overscroll_elasticity_layer, elastic_overscroll, page_scale_factor, device_scale_factor, viewport, device_transform, property_trees, color); +#if DCHECK_IS_ON() + for (auto* layer : *root_layer->layer_tree_host()) + CheckScrollAndClipPointersForLayer(layer); +#endif } void PropertyTreeBuilder::BuildPropertyTrees( diff --git a/chromium/cc/trees/property_tree_builder.h b/chromium/cc/trees/property_tree_builder.h index 49a91751234..be6829e21d1 100644 --- a/chromium/cc/trees/property_tree_builder.h +++ b/chromium/cc/trees/property_tree_builder.h @@ -16,6 +16,12 @@ class LayerTreeHost; class PropertyTreeBuilder { public: + static Layer* FindFirstScrollableLayer(Layer* root_layer); + + static void CC_EXPORT PreCalculateMetaInformation(Layer* root_layer); + static void CC_EXPORT + PreCalculateMetaInformationForTesting(LayerImpl* root_layer); + static void CC_EXPORT BuildPropertyTrees(Layer* root_layer, const Layer* page_scale_layer, diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc index 6cc1cf148e6..12054d80c15 100644 --- a/chromium/cc/trees/property_tree_unittest.cc +++ b/chromium/cc/trees/property_tree_unittest.cc @@ -29,7 +29,7 @@ TEST(PropertyTreeSerializationTest, TransformNodeDataSerialization) { original.needs_local_transform_update = false; original.is_invertible = false; original.ancestors_are_invertible = false; - original.is_animated = false; + original.has_potential_animation = false; original.to_screen_is_potentially_animated = false; original.has_only_translation_animations = false; original.to_screen_has_scale_animation = false; @@ -79,13 +79,16 @@ TEST(PropertyTreeSerializationTest, TransformNodeSerialization) { TEST(PropertyTreeSerializationTest, TransformTreeSerialization) { TransformTree original; TransformNode& root = *original.Node(0); + root.owner_id = 1; root.data.target_id = 3; root.data.content_target_id = 4; TransformNode second; + second.owner_id = 2; second.data.local.Translate3d(2.f, 2.f, 0.f); second.data.source_node_id = 0; second.data.target_id = 0; TransformNode third; + third.owner_id = 3; third.data.scrolls = true; third.data.source_node_id = 1; third.data.target_id = 0; @@ -106,8 +109,12 @@ TEST(PropertyTreeSerializationTest, TransformTreeSerialization) { proto::PropertyTree proto; original.ToProtobuf(&proto); TransformTree result; - result.FromProtobuf(proto); + std::unordered_map<int, int> transform_id_to_index_map; + result.FromProtobuf(proto, &transform_id_to_index_map); + EXPECT_EQ(transform_id_to_index_map[1], 0); + EXPECT_EQ(transform_id_to_index_map[2], 1); + EXPECT_EQ(transform_id_to_index_map[3], 2); EXPECT_EQ(original, result); } @@ -150,12 +157,15 @@ TEST(PropertyTreeSerializationTest, ClipNodeSerialization) { TEST(PropertyTreeSerializationTest, ClipTreeSerialization) { ClipTree original; ClipNode& root = *original.Node(0); + root.owner_id = 1; root.data.transform_id = 2; root.data.target_id = 1; ClipNode second; + second.owner_id = 2; second.data.transform_id = 4; second.data.applies_local_clip = true; ClipNode third; + third.owner_id = 3; third.data.target_id = 3; third.data.target_is_clipped = false; @@ -166,8 +176,12 @@ TEST(PropertyTreeSerializationTest, ClipTreeSerialization) { proto::PropertyTree proto; original.ToProtobuf(&proto); ClipTree result; - result.FromProtobuf(proto); + std::unordered_map<int, int> clip_id_to_index_map; + result.FromProtobuf(proto, &clip_id_to_index_map); + EXPECT_EQ(clip_id_to_index_map[1], 0); + EXPECT_EQ(clip_id_to_index_map[2], 1); + EXPECT_EQ(clip_id_to_index_map[3], 2); EXPECT_EQ(original, result); } @@ -204,12 +218,15 @@ TEST(PropertyTreeSerializationTest, EffectNodeSerialization) { TEST(PropertyTreeSerializationTest, EffectTreeSerialization) { EffectTree original; EffectNode& root = *original.Node(0); + root.owner_id = 5; root.data.transform_id = 2; root.data.clip_id = 1; EffectNode second; + second.owner_id = 6; second.data.transform_id = 4; second.data.opacity = true; EffectNode third; + third.owner_id = 7; third.data.clip_id = 3; third.data.has_render_surface = false; @@ -220,8 +237,12 @@ TEST(PropertyTreeSerializationTest, EffectTreeSerialization) { proto::PropertyTree proto; original.ToProtobuf(&proto); EffectTree result; - result.FromProtobuf(proto); + std::unordered_map<int, int> effect_id_to_index_map; + result.FromProtobuf(proto, &effect_id_to_index_map); + EXPECT_EQ(effect_id_to_index_map[5], 0); + EXPECT_EQ(effect_id_to_index_map[6], 1); + EXPECT_EQ(effect_id_to_index_map[7], 2); EXPECT_EQ(original, result); } @@ -264,9 +285,11 @@ TEST(PropertyTreeSerializationTest, ScrollTreeSerialization) { property_trees.is_main_thread = true; ScrollTree& original = property_trees.scroll_tree; ScrollNode second; + second.owner_id = 10; second.data.scrollable = true; second.data.bounds = gfx::Size(15, 15); ScrollNode third; + third.owner_id = 20; third.data.contains_non_fast_scrollable_region = true; original.Insert(second, 0); @@ -278,21 +301,64 @@ TEST(PropertyTreeSerializationTest, ScrollTreeSerialization) { proto::PropertyTree proto; original.ToProtobuf(&proto); ScrollTree result; - result.FromProtobuf(proto); + std::unordered_map<int, int> scroll_id_to_index_map; + result.FromProtobuf(proto, &scroll_id_to_index_map); + + EXPECT_EQ(original, result); + EXPECT_EQ(scroll_id_to_index_map[10], 1); + EXPECT_EQ(scroll_id_to_index_map[20], 2); + + original.clear(); + original.set_currently_scrolling_node(0); + original.SetScrollOffset(2, gfx::ScrollOffset(1, 2)); + + proto::PropertyTree proto2; + original.ToProtobuf(&proto2); + result = ScrollTree(); + scroll_id_to_index_map.clear(); + result.FromProtobuf(proto2, &scroll_id_to_index_map); EXPECT_EQ(original, result); } TEST(PropertyTreeSerializationTest, PropertyTrees) { PropertyTrees original; - original.transform_tree.Insert(TransformNode(), 0); - original.transform_tree.Insert(TransformNode(), 1); - original.clip_tree.Insert(ClipNode(), 0); - original.clip_tree.Insert(ClipNode(), 1); - original.effect_tree.Insert(EffectNode(), 0); - original.effect_tree.Insert(EffectNode(), 1); - original.scroll_tree.Insert(ScrollNode(), 0); - original.scroll_tree.Insert(ScrollNode(), 1); + TransformNode transform_node1 = TransformNode(); + transform_node1.owner_id = 10; + original.transform_tree.Insert(transform_node1, 0); + TransformNode transform_node2 = TransformNode(); + transform_node2.owner_id = 20; + original.transform_tree.Insert(transform_node2, 1); + original.transform_id_to_index_map[10] = 1; + original.transform_id_to_index_map[20] = 2; + + ClipNode clip_node1 = ClipNode(); + clip_node1.owner_id = 10; + original.clip_tree.Insert(clip_node1, 0); + ClipNode clip_node2 = ClipNode(); + clip_node2.owner_id = 22; + original.clip_tree.Insert(clip_node2, 1); + original.clip_id_to_index_map[10] = 1; + original.clip_id_to_index_map[22] = 2; + + EffectNode effect_node1 = EffectNode(); + effect_node1.owner_id = 11; + original.effect_tree.Insert(effect_node1, 0); + EffectNode effect_node2 = EffectNode(); + effect_node2.owner_id = 23; + original.effect_tree.Insert(effect_node2, 1); + original.effect_id_to_index_map[11] = 1; + original.effect_id_to_index_map[23] = 2; + + ScrollNode scroll_node1 = ScrollNode(); + scroll_node1.owner_id = 10; + original.scroll_tree.Insert(scroll_node1, 0); + ScrollNode scroll_node2 = ScrollNode(); + scroll_node2.owner_id = 20; + original.scroll_tree.Insert(scroll_node2, 1); + original.scroll_id_to_index_map[10] = 1; + original.scroll_id_to_index_map[20] = 2; + original.needs_rebuild = false; original.non_root_surfaces_enabled = false; original.sequence_number = 3; @@ -324,7 +390,8 @@ class PropertyTreeTest : public testing::Test { TransformTree new_tree; proto::PropertyTree proto; transform_tree.ToProtobuf(&proto); - new_tree.FromProtobuf(proto); + std::unordered_map<int, int> transform_id_to_index_map; + new_tree.FromProtobuf(proto, &transform_id_to_index_map); new_tree.SetPropertyTrees(transform_tree.property_trees()); @@ -339,7 +406,8 @@ class PropertyTreeTest : public testing::Test { EffectTree new_tree; proto::PropertyTree proto; effect_tree.ToProtobuf(&proto); - new_tree.FromProtobuf(proto); + std::unordered_map<int, int> effect_id_to_index_map; + new_tree.FromProtobuf(proto, &effect_id_to_index_map); EXPECT_EQ(effect_tree, new_tree); return new_tree; diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h index 27144aa36bc..a8f3e99ca56 100644 --- a/chromium/cc/trees/proxy.h +++ b/chromium/cc/trees/proxy.h @@ -5,11 +5,11 @@ #ifndef CC_TREES_PROXY_H_ #define CC_TREES_PROXY_H_ +#include <memory> #include <string> #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "base/values.h" @@ -69,22 +69,15 @@ class CC_EXPORT Proxy { // Must be called before using the proxy. virtual void Start( - scoped_ptr<BeginFrameSource> external_begin_frame_source) = 0; + std::unique_ptr<BeginFrameSource> external_begin_frame_source) = 0; virtual void Stop() = 0; // Must be called before deleting the proxy. virtual bool SupportsImplScrolling() const = 0; - virtual void SetChildrenNeedBeginFrames(bool children_need_begin_frames) = 0; - - virtual void SetAuthoritativeVSyncInterval( - const base::TimeDelta& interval) = 0; - virtual void UpdateTopControlsState(TopControlsState constraints, TopControlsState current, bool animate) = 0; - virtual void SetOutputIsSecure(bool output_is_secure) = 0; - // Testing hooks virtual bool MainFrameWillHappenForTesting() = 0; }; diff --git a/chromium/cc/trees/proxy_common.cc b/chromium/cc/trees/proxy_common.cc index c96af7b4acd..3e614aadd41 100644 --- a/chromium/cc/trees/proxy_common.cc +++ b/chromium/cc/trees/proxy_common.cc @@ -9,8 +9,7 @@ namespace cc { -BeginMainFrameAndCommitState::BeginMainFrameAndCommitState() - : memory_allocation_limit_bytes(0), evicted_ui_resources(false) {} +BeginMainFrameAndCommitState::BeginMainFrameAndCommitState() {} BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {} @@ -21,6 +20,10 @@ void BeginMainFrameAndCommitState::ToProtobuf( scroll_info->ToProtobuf(proto->mutable_scroll_info()); proto->set_memory_allocation_limit_bytes(memory_allocation_limit_bytes); proto->set_evicted_ui_resources(evicted_ui_resources); + proto->set_has_fixed_raster_scale_blurry_content( + has_fixed_raster_scale_blurry_content); + proto->set_has_fixed_raster_scale_potential_performance_regression( + has_fixed_raster_scale_potential_performance_regression); } void BeginMainFrameAndCommitState::FromProtobuf( @@ -31,6 +34,10 @@ void BeginMainFrameAndCommitState::FromProtobuf( scroll_info->FromProtobuf(proto.scroll_info()); memory_allocation_limit_bytes = proto.memory_allocation_limit_bytes(); evicted_ui_resources = proto.evicted_ui_resources(); + has_fixed_raster_scale_blurry_content = + proto.has_fixed_raster_scale_blurry_content(); + has_fixed_raster_scale_potential_performance_regression = + proto.has_fixed_raster_scale_potential_performance_regression(); } } // namespace cc diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h index 046f1056ea9..e35d3122e4f 100644 --- a/chromium/cc/trees/proxy_common.h +++ b/chromium/cc/trees/proxy_common.h @@ -7,6 +7,7 @@ #include <stddef.h> +#include "base/callback_forward.h" #include "cc/base/cc_export.h" #include "cc/output/begin_frame_args.h" #include "cc/trees/layer_tree_host_common.h" @@ -19,15 +20,20 @@ class BeginMainFrameAndCommitState; class LayerTreeHost; +using BeginFrameCallbackList = std::vector<base::Closure>; + struct CC_EXPORT BeginMainFrameAndCommitState { BeginMainFrameAndCommitState(); ~BeginMainFrameAndCommitState(); - unsigned int begin_frame_id; + unsigned int begin_frame_id = 0; BeginFrameArgs begin_frame_args; - scoped_ptr<ScrollAndScaleSet> scroll_info; - size_t memory_allocation_limit_bytes; - bool evicted_ui_resources; + std::unique_ptr<BeginFrameCallbackList> begin_frame_callbacks; + std::unique_ptr<ScrollAndScaleSet> scroll_info; + size_t memory_allocation_limit_bytes = 0; + bool evicted_ui_resources = false; + bool has_fixed_raster_scale_blurry_content = false; + bool has_fixed_raster_scale_potential_performance_regression = false; void ToProtobuf(proto::BeginMainFrameAndCommitState* proto) const; void FromProtobuf(const proto::BeginMainFrameAndCommitState& proto); diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index a994e85579a..a2427061546 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -8,6 +8,7 @@ #include <string> #include "base/auto_reset.h" +#include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "base/trace_event/trace_event_synthetic_delay.h" @@ -34,23 +35,25 @@ unsigned int nextBeginFrameId = 0; } // namespace -scoped_ptr<ProxyImpl> ProxyImpl::Create( +std::unique_ptr<ProxyImpl> ProxyImpl::Create( ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { - return make_scoped_ptr(new ProxyImpl(channel_impl, layer_tree_host, - task_runner_provider, - std::move(external_begin_frame_source))); + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { + return base::WrapUnique( + new ProxyImpl(channel_impl, layer_tree_host, task_runner_provider, + std::move(external_begin_frame_source))); } -ProxyImpl::ProxyImpl(ChannelImpl* channel_impl, - LayerTreeHost* layer_tree_host, - TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source) +ProxyImpl::ProxyImpl( + ChannelImpl* channel_impl, + LayerTreeHost* layer_tree_host, + TaskRunnerProvider* task_runner_provider, + std::unique_ptr<BeginFrameSource> external_begin_frame_source) : layer_tree_host_id_(layer_tree_host->id()), - next_commit_waits_for_activation_(false), + commit_completion_waits_for_activation_(false), commit_completion_event_(nullptr), + activation_completion_event_(nullptr), next_frame_is_newly_committed_frame_(false), inside_draw_(false), input_throttled_until_commit_(false), @@ -73,7 +76,7 @@ ProxyImpl::ProxyImpl(ChannelImpl* channel_impl, SchedulerSettings scheduler_settings( layer_tree_host->settings().ToSchedulerSettings()); - scoped_ptr<CompositorTimingHistory> compositor_timing_history( + std::unique_ptr<CompositorTimingHistory> compositor_timing_history( new CompositorTimingHistory( scheduler_settings.using_synchronous_renderer_compositor, CompositorTimingHistory::RENDERER_UMA, @@ -182,11 +185,9 @@ void ProxyImpl::BeginMainFrameAbortedOnImpl( CommitEarlyOutReasonToString(reason)); DCHECK(IsImplThread()); DCHECK(scheduler_->CommitPending()); - DCHECK(!layer_tree_host_impl_->pending_tree()); if (CommitEarlyOutHandledCommit(reason)) { SetInputThrottledUntilCommitOnImpl(false); - last_processed_begin_main_frame_args_ = last_begin_main_frame_args_; } layer_tree_host_impl_->BeginMainFrameAborted(reason); scheduler_->NotifyBeginMainFrameStarted(main_thread_start_time); @@ -241,6 +242,16 @@ void ProxyImpl::MainFrameWillHappenOnImplForTesting( completion->Signal(); } +void ProxyImpl::BlockNotifyReadyToActivateForTesting(bool block) { + DCHECK(IsImplThread()); + layer_tree_host_impl_->BlockNotifyReadyToActivateForTesting(block); +} + +CompletionEvent* ProxyImpl::ActivationCompletionEventForTesting() { + DCHECK(IsImplThread()); + return activation_completion_event_; +} + void ProxyImpl::StartCommitOnImpl(CompletionEvent* completion, LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, @@ -251,13 +262,6 @@ void ProxyImpl::StartCommitOnImpl(CompletionEvent* completion, DCHECK(scheduler_); DCHECK(scheduler_->CommitPending()); - if (hold_commit_for_activation) { - // This commit may be aborted. Store the value for - // hold_commit_for_activation so that whenever the next commit is started, - // the main thread will be unblocked only after pending tree activation. - next_commit_waits_for_activation_ = hold_commit_for_activation; - } - if (!layer_tree_host_impl_) { TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoLayerTree", TRACE_EVENT_SCOPE_THREAD); @@ -268,7 +272,10 @@ void ProxyImpl::StartCommitOnImpl(CompletionEvent* completion, // Ideally, we should inform to impl thread when BeginMainFrame is started. // But, we can avoid a PostTask in here. scheduler_->NotifyBeginMainFrameStarted(main_thread_start_time); + commit_completion_event_ = completion; + commit_completion_waits_for_activation_ = hold_commit_for_activation; + DCHECK(!blocked_main_commit().layer_tree_host); blocked_main_commit().layer_tree_host = layer_tree_host; scheduler_->NotifyReadyToCommit(); @@ -294,13 +301,19 @@ void ProxyImpl::CommitVSyncParameters(base::TimeTicks timebase, if (!synthetic_begin_frame_source_) return; - if (interval == base::TimeDelta()) { + if (interval.is_zero()) { // TODO(brianderson): We should not be receiving 0 intervals. interval = BeginFrameArgs::DefaultInterval(); } synthetic_begin_frame_source_->OnUpdateVSyncParameters(timebase, interval); } +void ProxyImpl::SetBeginFrameSource(BeginFrameSource* source) { + // TODO(enne): this overrides any preexisting begin frame source. Those + // other sources will eventually be removed and this will be the only path. + scheduler_->SetBeginFrameSource(source); +} + void ProxyImpl::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { DCHECK(IsImplThread()); scheduler_->SetEstimatedParentDrawTime(draw_time); @@ -375,7 +388,7 @@ void ProxyImpl::SetVideoNeedsBeginFrames(bool needs_begin_frames) { } void ProxyImpl::PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEvents> events) { + std::unique_ptr<AnimationEvents> events) { TRACE_EVENT0("cc", "ProxyImpl::PostAnimationEventsToMainThreadOnImplThread"); DCHECK(IsImplThread()); channel_impl_->SetAnimationEvents(std::move(events)); @@ -440,16 +453,12 @@ void ProxyImpl::DidActivateSyncTree() { TRACE_EVENT0("cc", "ProxyImpl::DidActivateSyncTreeOnImplThread"); DCHECK(IsImplThread()); - if (next_commit_waits_for_activation_) { + if (activation_completion_event_) { TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD); - DCHECK(commit_completion_event_); - commit_completion_event_->Signal(); - commit_completion_event_ = nullptr; - next_commit_waits_for_activation_ = false; + activation_completion_event_->Signal(); + activation_completion_event_ = nullptr; } - - last_processed_begin_main_frame_args_ = last_begin_main_frame_args_; } void ProxyImpl::WillPrepareTiles() { @@ -472,26 +481,9 @@ void ProxyImpl::OnDrawForOutputSurface(bool resourceless_software_draw) { scheduler_->OnDrawForOutputSurface(resourceless_software_draw); } -void ProxyImpl::PostFrameTimingEventsOnImplThread( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) { - DCHECK(IsImplThread()); - channel_impl_->PostFrameTimingEventsOnMain(std::move(composite_events), - std::move(main_frame_events)); -} - void ProxyImpl::WillBeginImplFrame(const BeginFrameArgs& args) { DCHECK(IsImplThread()); layer_tree_host_impl_->WillBeginImplFrame(args); - if (last_processed_begin_main_frame_args_.IsValid()) { - // Last processed begin main frame args records the frame args that we sent - // to the main thread for the last frame that we've processed. If that is - // set, that means the current frame is one past the frame in which we've - // finished the processing. - layer_tree_host_impl_->RecordMainFrameTiming( - last_processed_begin_main_frame_args_, args); - last_processed_begin_main_frame_args_ = BeginFrameArgs(); - } } void ProxyImpl::DidFinishImplFrame() { @@ -504,20 +496,24 @@ void ProxyImpl::ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) { unsigned int begin_frame_id = nextBeginFrameId++; benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task( benchmark_instrumentation::kSendBeginFrame, begin_frame_id); - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state( + std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state( new BeginMainFrameAndCommitState); begin_main_frame_state->begin_frame_id = begin_frame_id; begin_main_frame_state->begin_frame_args = args; + begin_main_frame_state->begin_frame_callbacks = + layer_tree_host_impl_->ProcessLayerTreeMutations(); begin_main_frame_state->scroll_info = layer_tree_host_impl_->ProcessScrollDeltas(); begin_main_frame_state->memory_allocation_limit_bytes = layer_tree_host_impl_->memory_allocation_limit_bytes(); begin_main_frame_state->evicted_ui_resources = layer_tree_host_impl_->EvictedUIResourcesExist(); - // TODO(vmpstr): This needs to be fixed if - // main_frame_before_activation_enabled is set, since we might run this code - // twice before recording a duration. crbug.com/469824 - last_begin_main_frame_args_ = begin_main_frame_state->begin_frame_args; + begin_main_frame_state->has_fixed_raster_scale_blurry_content = + layer_tree_host_impl_->has_fixed_raster_scale_blurry_content(); + begin_main_frame_state + ->has_fixed_raster_scale_potential_performance_regression = + layer_tree_host_impl_ + ->HasFixedRasterScalePotentialPerformanceRegression(); channel_impl_->BeginMainFrame(std::move(begin_main_frame_state)); devtools_instrumentation::DidRequestMainThreadFrame(layer_tree_host_id_); } @@ -558,15 +554,17 @@ void ProxyImpl::ScheduledActionCommit() { // blocked for a commit. blocked_main_commit().layer_tree_host = nullptr; - if (next_commit_waits_for_activation_) { - // For some layer types in impl-side painting, the commit is held until - // the sync tree is activated. It's also possible that the - // sync tree has already activated if there was no work to be done. + if (commit_completion_waits_for_activation_) { + // For some layer types in impl-side painting, the commit is held until the + // sync tree is activated. It's also possible that the sync tree has + // already activated if there was no work to be done. TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD); + commit_completion_waits_for_activation_ = false; + activation_completion_event_ = commit_completion_event_; } else { commit_completion_event_->Signal(); - commit_completion_event_ = nullptr; } + commit_completion_event_ = nullptr; scheduler_->DidCommit(); @@ -604,10 +602,6 @@ void ProxyImpl::ScheduledActionInvalidateOutputSurface() { layer_tree_host_impl_->output_surface()->Invalidate(); } -void ProxyImpl::SendBeginFramesToChildren(const BeginFrameArgs& args) { - NOTREACHED() << "Only used by SingleThreadProxy"; -} - void ProxyImpl::SendBeginMainFrameNotExpectedSoon() { DCHECK(IsImplThread()); channel_impl_->BeginMainFrameNotExpectedSoon(); diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h index a335d8abe1a..d6583cde4d1 100644 --- a/chromium/cc/trees/proxy_impl.h +++ b/chromium/cc/trees/proxy_impl.h @@ -5,8 +5,9 @@ #ifndef CC_TREES_PROXY_IMPL_H_ #define CC_TREES_PROXY_IMPL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/completion_event.h" #include "cc/base/delayed_unique_notifier.h" #include "cc/input/top_controls_state.h" @@ -22,11 +23,11 @@ namespace cc { class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), public NON_EXPORTED_BASE(SchedulerClient) { public: - static scoped_ptr<ProxyImpl> Create( + static std::unique_ptr<ProxyImpl> Create( ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<BeginFrameSource> external_begin_frame_source); ~ProxyImpl() override; @@ -47,20 +48,22 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), virtual void SetVisibleOnImpl(bool visible); virtual void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion); virtual void FinishGLOnImpl(CompletionEvent* completion); - virtual void MainFrameWillHappenOnImplForTesting( - CompletionEvent* completion, - bool* main_frame_will_happen); virtual void StartCommitOnImpl(CompletionEvent* completion, LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, bool hold_commit_for_activation); + void MainFrameWillHappenOnImplForTesting(CompletionEvent* completion, + bool* main_frame_will_happen); + void BlockNotifyReadyToActivateForTesting(bool block); + CompletionEvent* ActivationCompletionEventForTesting(); + protected: // protected for testing. ProxyImpl(ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<BeginFrameSource> external_begin_frame_source); private: // The members of this struct should be accessed on the impl thread only when @@ -78,6 +81,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void DidLoseOutputSurfaceOnImplThread() override; void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) override; + void SetBeginFrameSource(BeginFrameSource* source) override; void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override; void DidSwapBuffersOnImplThread() override; void DidSwapBuffersCompleteOnImplThread() override; @@ -94,7 +98,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void SetNeedsCommitOnImplThread() override; void SetVideoNeedsBeginFrames(bool needs_begin_frames) override; void PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEvents> events) override; + std::unique_ptr<AnimationEvents> events) override; bool IsInsideDraw() override; void RenewTreePriority() override; void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -104,11 +108,6 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void DidPrepareTiles() override; void DidCompletePageScaleAnimationOnImplThread() override; void OnDrawForOutputSurface(bool resourceless_software_draw) 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; @@ -121,7 +120,6 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void ScheduledActionBeginOutputSurfaceCreation() override; void ScheduledActionPrepareTiles() override; void ScheduledActionInvalidateOutputSurface() override; - void SendBeginFramesToChildren(const BeginFrameArgs& args) override; void SendBeginMainFrameNotExpectedSoon() override; DrawResult DrawAndSwapInternal(bool forced_draw); @@ -131,15 +129,17 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), const int layer_tree_host_id_; - scoped_ptr<Scheduler> scheduler_; + std::unique_ptr<Scheduler> scheduler_; // Set when the main thread is waiting on a pending tree activation. - bool next_commit_waits_for_activation_; + bool commit_completion_waits_for_activation_; - // Set when the main thread is waiting on a commit to complete or on a - // pending tree activation. + // Set when the main thread is waiting on a commit to complete. CompletionEvent* commit_completion_event_; + // Set when the main thread is waiting for activation to complete. + CompletionEvent* activation_completion_event_; + // Set when the next draw should post DidCommitAndDrawFrame to the main // thread. bool next_frame_is_newly_committed_frame_; @@ -151,17 +151,13 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), DelayedUniqueNotifier smoothness_priority_expiration_notifier_; - scoped_ptr<BeginFrameSource> external_begin_frame_source_; - scoped_ptr<BeginFrameSource> unthrottled_begin_frame_source_; - scoped_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source_; + std::unique_ptr<BeginFrameSource> external_begin_frame_source_; + std::unique_ptr<BeginFrameSource> unthrottled_begin_frame_source_; + std::unique_ptr<SyntheticBeginFrameSource> synthetic_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_; - - scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl_; + std::unique_ptr<LayerTreeHostImpl> layer_tree_host_impl_; ChannelImpl* channel_impl_; diff --git a/chromium/cc/trees/proxy_impl_unittest.cc b/chromium/cc/trees/proxy_impl_unittest.cc index 1be6acd0694..9ff15f13f5e 100644 --- a/chromium/cc/trees/proxy_impl_unittest.cc +++ b/chromium/cc/trees/proxy_impl_unittest.cc @@ -45,8 +45,8 @@ class ProxyImplTest : public testing::Test, public TestHooks { FakeLayerTreeHostClient host_client_; FakeChannelImpl channel_impl_; TaskRunnerProvider* task_runner_provider_; - scoped_ptr<ProxyImplForTest> proxy_impl_; - scoped_ptr<FakeLayerTreeHost> layer_tree_host_; + std::unique_ptr<ProxyImplForTest> proxy_impl_; + std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; // This is a regression test. See crbug/568120. diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index c5821f373e7..fff11b497dd 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -23,21 +23,21 @@ namespace cc { -scoped_ptr<ProxyMain> ProxyMain::CreateThreaded( +std::unique_ptr<ProxyMain> ProxyMain::CreateThreaded( LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider) { - scoped_ptr<ProxyMain> proxy_main( + std::unique_ptr<ProxyMain> proxy_main( new ProxyMain(layer_tree_host, task_runner_provider)); proxy_main->SetChannel( ThreadedChannel::Create(proxy_main.get(), task_runner_provider)); return proxy_main; } -scoped_ptr<ProxyMain> ProxyMain::CreateRemote( +std::unique_ptr<ProxyMain> ProxyMain::CreateRemote( RemoteProtoChannel* remote_proto_channel, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider) { - scoped_ptr<ProxyMain> proxy_main( + std::unique_ptr<ProxyMain> proxy_main( new ProxyMain(layer_tree_host, task_runner_provider)); proxy_main->SetChannel(RemoteChannelMain::Create( remote_proto_channel, proxy_main.get(), task_runner_provider)); @@ -66,7 +66,7 @@ ProxyMain::~ProxyMain() { DCHECK(!started_); } -void ProxyMain::SetChannel(scoped_ptr<ChannelMain> channel_main) { +void ProxyMain::SetChannel(std::unique_ptr<ChannelMain> channel_main) { DCHECK(!channel_main_); channel_main_ = std::move(channel_main); } @@ -93,7 +93,7 @@ void ProxyMain::DidCommitAndDrawFrame() { layer_tree_host_->DidCommitAndDrawFrame(); } -void ProxyMain::SetAnimationEvents(scoped_ptr<AnimationEvents> events) { +void ProxyMain::SetAnimationEvents(std::unique_ptr<AnimationEvents> events) { TRACE_EVENT0("cc", "ProxyMain::SetAnimationEvents"); DCHECK(IsMainThread()); layer_tree_host_->SetAnimationEvents(std::move(events)); @@ -129,16 +129,8 @@ void ProxyMain::DidCompletePageScaleAnimation() { layer_tree_host_->DidCompletePageScaleAnimation(); } -void ProxyMain::PostFrameTimingEventsOnMain( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) { - DCHECK(IsMainThread()); - layer_tree_host_->RecordFrameTimingEvents(std::move(composite_events), - std::move(main_frame_events)); -} - void ProxyMain::BeginMainFrame( - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { + std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task( benchmark_instrumentation::kDoBeginFrame, begin_main_frame_state->begin_frame_id); @@ -187,8 +179,17 @@ void ProxyMain::BeginMainFrame( layer_tree_host_->ApplyScrollAndScale( begin_main_frame_state->scroll_info.get()); + if (begin_main_frame_state->begin_frame_callbacks) { + for (auto& callback : *begin_main_frame_state->begin_frame_callbacks) + callback.Run(); + } + layer_tree_host_->WillBeginMainFrame(); + layer_tree_host_->ReportFixedRasterScaleUseCounters( + begin_main_frame_state->has_fixed_raster_scale_blurry_content, + begin_main_frame_state + ->has_fixed_raster_scale_potential_performance_regression); layer_tree_host_->BeginMainFrame(begin_main_frame_state->begin_frame_args); layer_tree_host_->AnimateLayers( begin_main_frame_state->begin_frame_args.frame_time); @@ -382,7 +383,7 @@ void ProxyMain::MainThreadHasStoppedFlinging() { } void ProxyMain::Start( - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { DCHECK(IsMainThread()); DCHECK(layer_tree_host_->IsThreaded() || layer_tree_host_->IsRemoteServer()); DCHECK(channel_main_); @@ -424,14 +425,6 @@ bool ProxyMain::MainFrameWillHappenForTesting() { return main_frame_will_happen; } -void ProxyMain::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { - NOTREACHED() << "Only used by SingleThreadProxy"; -} - -void ProxyMain::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) { - NOTREACHED() << "Only used by SingleProxyMain"; -} - void ProxyMain::ReleaseOutputSurface() { DCHECK(IsMainThread()); DCHECK(layer_tree_host_->output_surface_lost()); @@ -449,10 +442,6 @@ void ProxyMain::UpdateTopControlsState(TopControlsState constraints, channel_main_->UpdateTopControlsStateOnImpl(constraints, current, animate); } -void ProxyMain::SetOutputIsSecure(bool output_is_secure) { - NOTREACHED() << "Only used by SingleProxyMain"; -} - bool ProxyMain::SendCommitRequestToImplThreadIfNeeded( CommitPipelineStage required_stage) { DCHECK(IsMainThread()); diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h index 1b627dda42c..ab465610805 100644 --- a/chromium/cc/trees/proxy_main.h +++ b/chromium/cc/trees/proxy_main.h @@ -7,7 +7,6 @@ #include "base/macros.h" #include "cc/base/cc_export.h" -#include "cc/debug/frame_timing_tracker.h" #include "cc/input/top_controls_state.h" #include "cc/output/output_surface.h" #include "cc/output/renderer_capabilities.h" @@ -28,11 +27,11 @@ class LayerTreeHost; // The class is created and lives on the main thread. class CC_EXPORT ProxyMain : public Proxy { public: - static scoped_ptr<ProxyMain> CreateThreaded( + static std::unique_ptr<ProxyMain> CreateThreaded( LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider); - static scoped_ptr<ProxyMain> CreateRemote( + static std::unique_ptr<ProxyMain> CreateRemote( RemoteProtoChannel* remote_proto_channel, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider); @@ -55,18 +54,15 @@ class CC_EXPORT ProxyMain : public Proxy { const RendererCapabilities& capabilities); virtual void BeginMainFrameNotExpectedSoon(); virtual void DidCommitAndDrawFrame(); - virtual void SetAnimationEvents(scoped_ptr<AnimationEvents> events); + virtual void SetAnimationEvents(std::unique_ptr<AnimationEvents> events); virtual void DidLoseOutputSurface(); virtual void RequestNewOutputSurface(); virtual void DidInitializeOutputSurface( bool success, const RendererCapabilities& capabilities); virtual void DidCompletePageScaleAnimation(); - virtual void PostFrameTimingEventsOnMain( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events); virtual void BeginMainFrame( - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state); + std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state); ChannelMain* channel_main() const { return channel_main_.get(); } CommitPipelineStage max_requested_pipeline_stage() const { @@ -103,20 +99,18 @@ class CC_EXPORT ProxyMain : public Proxy { bool CommitRequested() const override; bool BeginMainFrameRequested() const override; void MainThreadHasStoppedFlinging() override; - void Start(scoped_ptr<BeginFrameSource> external_begin_frame_source) override; + void Start( + std::unique_ptr<BeginFrameSource> external_begin_frame_source) override; void Stop() override; bool SupportsImplScrolling() const override; bool MainFrameWillHappenForTesting() override; - void SetChildrenNeedBeginFrames(bool children_need_begin_frames) override; - void SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) override; void ReleaseOutputSurface() override; void UpdateTopControlsState(TopControlsState constraints, TopControlsState current, bool animate) override; - void SetOutputIsSecure(bool output_is_secure) override; // This sets the channel used by ProxyMain to communicate with ProxyImpl. - void SetChannel(scoped_ptr<ChannelMain> channel_main); + void SetChannel(std::unique_ptr<ChannelMain> channel_main); // Returns |true| if the request was actually sent, |false| if one was // already outstanding. @@ -150,7 +144,7 @@ class CC_EXPORT ProxyMain : public Proxy { RendererCapabilities renderer_capabilities_; - scoped_ptr<ChannelMain> channel_main_; + std::unique_ptr<ChannelMain> channel_main_; DISALLOW_COPY_AND_ASSIGN(ProxyMain); }; diff --git a/chromium/cc/trees/remote_channel_impl.cc b/chromium/cc/trees/remote_channel_impl.cc index 58fdca78574..3f58422464f 100644 --- a/chromium/cc/trees/remote_channel_impl.cc +++ b/chromium/cc/trees/remote_channel_impl.cc @@ -5,6 +5,7 @@ #include "cc/trees/remote_channel_impl.h" #include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "cc/animation/animation_events.h" #include "cc/proto/compositor_message.pb.h" @@ -16,11 +17,11 @@ namespace cc { -scoped_ptr<RemoteChannelImpl> RemoteChannelImpl::Create( +std::unique_ptr<RemoteChannelImpl> RemoteChannelImpl::Create( LayerTreeHost* layer_tree_host, RemoteProtoChannel* remote_proto_channel, TaskRunnerProvider* task_runner_provider) { - return make_scoped_ptr(new RemoteChannelImpl( + return base::WrapUnique(new RemoteChannelImpl( layer_tree_host, remote_proto_channel, task_runner_provider)); } @@ -43,11 +44,11 @@ RemoteChannelImpl::~RemoteChannelImpl() { main().remote_proto_channel->SetProtoReceiver(nullptr); } -scoped_ptr<ProxyImpl> RemoteChannelImpl::CreateProxyImpl( +std::unique_ptr<ProxyImpl> RemoteChannelImpl::CreateProxyImpl( ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { DCHECK(task_runner_provider_->IsImplThread()); DCHECK(!external_begin_frame_source); return ProxyImpl::Create(channel_impl, layer_tree_host, task_runner_provider, @@ -55,7 +56,7 @@ scoped_ptr<ProxyImpl> RemoteChannelImpl::CreateProxyImpl( } void RemoteChannelImpl::OnProtoReceived( - scoped_ptr<proto::CompositorMessage> proto) { + std::unique_ptr<proto::CompositorMessage> proto) { DCHECK(task_runner_provider_->IsMainThread()); DCHECK(main().started); DCHECK(proto->has_to_impl()); @@ -116,6 +117,7 @@ void RemoteChannelImpl::HandleProto( main().layer_tree_host->FromProtobufForCommit( start_commit_message.layer_tree_host()); + { DebugScopedSetMainThreadBlocked main_thread_blocked( task_runner_provider_); @@ -253,7 +255,7 @@ bool RemoteChannelImpl::BeginMainFrameRequested() const { } void RemoteChannelImpl::Start( - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { DCHECK(task_runner_provider_->IsMainThread()); DCHECK(!main().started); DCHECK(!external_begin_frame_source); @@ -299,26 +301,12 @@ bool RemoteChannelImpl::SupportsImplScrolling() const { return true; } -void RemoteChannelImpl::SetChildrenNeedBeginFrames( - bool children_need_begin_frames) { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -void RemoteChannelImpl::SetAuthoritativeVSyncInterval( - const base::TimeDelta& interval) { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - void RemoteChannelImpl::UpdateTopControlsState(TopControlsState constraints, TopControlsState current, bool animate) { NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; } -void RemoteChannelImpl::SetOutputIsSecure(bool output_is_secure) { - NOTREACHED() << "Only used by SingleProxyMain"; -} - bool RemoteChannelImpl::MainFrameWillHappenForTesting() { DCHECK(task_runner_provider_->IsMainThread()); bool main_frame_will_happen; @@ -334,7 +322,12 @@ bool RemoteChannelImpl::MainFrameWillHappenForTesting() { return main_frame_will_happen; } -void RemoteChannelImpl::DidCompleteSwapBuffers() {} +void RemoteChannelImpl::DidCompleteSwapBuffers() { + DCHECK(task_runner_provider_->IsImplThread()); + MainThreadTaskRunner()->PostTask( + FROM_HERE, base::Bind(&RemoteChannelImpl::DidCompleteSwapBuffersOnMain, + impl().remote_channel_weak_ptr)); +} void RemoteChannelImpl::SetRendererCapabilitiesMainCopy( const RendererCapabilities& capabilities) {} @@ -343,7 +336,8 @@ void RemoteChannelImpl::BeginMainFrameNotExpectedSoon() {} void RemoteChannelImpl::DidCommitAndDrawFrame() {} -void RemoteChannelImpl::SetAnimationEvents(scoped_ptr<AnimationEvents> queue) {} +void RemoteChannelImpl::SetAnimationEvents( + std::unique_ptr<AnimationEvents> queue) {} void RemoteChannelImpl::DidLoseOutputSurface() { DCHECK(task_runner_provider_->IsImplThread()); @@ -374,13 +368,9 @@ void RemoteChannelImpl::DidInitializeOutputSurface( void RemoteChannelImpl::DidCompletePageScaleAnimation() {} -void RemoteChannelImpl::PostFrameTimingEventsOnMain( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {} - void RemoteChannelImpl::BeginMainFrame( - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { - scoped_ptr<proto::CompositorMessage> proto; + std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { + std::unique_ptr<proto::CompositorMessage> proto; proto.reset(new proto::CompositorMessage); proto::CompositorMessageToMain* to_main_proto = proto->mutable_to_main(); @@ -395,7 +385,7 @@ void RemoteChannelImpl::BeginMainFrame( } void RemoteChannelImpl::SendMessageProto( - scoped_ptr<proto::CompositorMessage> proto) { + std::unique_ptr<proto::CompositorMessage> proto) { DCHECK(task_runner_provider_->IsImplThread()); MainThreadTaskRunner()->PostTask( @@ -404,6 +394,11 @@ void RemoteChannelImpl::SendMessageProto( impl().remote_channel_weak_ptr, base::Passed(&proto))); } +void RemoteChannelImpl::DidCompleteSwapBuffersOnMain() { + DCHECK(task_runner_provider_->IsMainThread()); + main().layer_tree_host->DidCompleteSwapBuffers(); +} + void RemoteChannelImpl::DidLoseOutputSurfaceOnMain() { DCHECK(task_runner_provider_->IsMainThread()); @@ -447,7 +442,7 @@ void RemoteChannelImpl::DidInitializeOutputSurfaceOnMain( } void RemoteChannelImpl::SendMessageProtoOnMain( - scoped_ptr<proto::CompositorMessage> proto) { + std::unique_ptr<proto::CompositorMessage> proto) { DCHECK(task_runner_provider_->IsMainThread()); VLOG(1) << "Sending BeginMainFrame request to the engine."; @@ -470,7 +465,7 @@ void RemoteChannelImpl::InitializeImplOnImpl(CompletionEvent* completion, impl().proxy_impl = CreateProxyImpl(this, layer_tree_host, task_runner_provider_, nullptr); - impl().proxy_impl_weak_factory = make_scoped_ptr( + impl().proxy_impl_weak_factory = base::WrapUnique( new base::WeakPtrFactory<ProxyImpl>(impl().proxy_impl.get())); proxy_impl_weak_ptr_ = impl().proxy_impl_weak_factory->GetWeakPtr(); completion->Signal(); diff --git a/chromium/cc/trees/remote_channel_impl.h b/chromium/cc/trees/remote_channel_impl.h index acd44aa43bb..8c12b68d818 100644 --- a/chromium/cc/trees/remote_channel_impl.h +++ b/chromium/cc/trees/remote_channel_impl.h @@ -78,7 +78,7 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl, public RemoteProtoChannel::ProtoReceiver, public Proxy { public: - static scoped_ptr<RemoteChannelImpl> Create( + static std::unique_ptr<RemoteChannelImpl> Create( LayerTreeHost* layer_tree_host, RemoteProtoChannel* remote_proto_channel, TaskRunnerProvider* task_runner_provider); @@ -91,11 +91,11 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl, TaskRunnerProvider* task_runner_provider); // virtual for testing. - virtual scoped_ptr<ProxyImpl> CreateProxyImpl( + virtual std::unique_ptr<ProxyImpl> CreateProxyImpl( ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<BeginFrameSource> external_begin_frame_source); private: struct MainThreadOnly { @@ -123,8 +123,8 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl, }; struct CompositorThreadOnly { - scoped_ptr<ProxyImpl> proxy_impl; - scoped_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory; + std::unique_ptr<ProxyImpl> proxy_impl; + std::unique_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory; base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr; CompositorThreadOnly( @@ -134,7 +134,8 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl, // called on main thread. // RemoteProtoChannel::ProtoReceiver implementation. - void OnProtoReceived(scoped_ptr<proto::CompositorMessage> proto) override; + void OnProtoReceived( + std::unique_ptr<proto::CompositorMessage> proto) override; // Proxy implementation void FinishAllRendering() override; @@ -154,15 +155,13 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl, void MainThreadHasStoppedFlinging() override; bool CommitRequested() const override; bool BeginMainFrameRequested() const override; - void Start(scoped_ptr<BeginFrameSource> external_begin_frame_source) override; + void Start( + std::unique_ptr<BeginFrameSource> external_begin_frame_source) override; void Stop() override; bool SupportsImplScrolling() const override; - void SetChildrenNeedBeginFrames(bool children_need_begin_frames) override; - void SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) override; void UpdateTopControlsState(TopControlsState constraints, TopControlsState current, bool animate) override; - void SetOutputIsSecure(bool output_is_secure) override; bool MainFrameWillHappenForTesting() override; // Called on impl thread. @@ -172,30 +171,27 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl, const RendererCapabilities& capabilities) override; void BeginMainFrameNotExpectedSoon() override; void DidCommitAndDrawFrame() override; - void SetAnimationEvents(scoped_ptr<AnimationEvents> queue) override; + void SetAnimationEvents(std::unique_ptr<AnimationEvents> queue) override; void DidLoseOutputSurface() override; void RequestNewOutputSurface() override; void DidInitializeOutputSurface( bool success, const RendererCapabilities& capabilities) override; void DidCompletePageScaleAnimation() override; - void PostFrameTimingEventsOnMain( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) - override; - void BeginMainFrame( - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) override; + void BeginMainFrame(std::unique_ptr<BeginMainFrameAndCommitState> + begin_main_frame_state) override; - void SendMessageProto(scoped_ptr<proto::CompositorMessage> proto); + void SendMessageProto(std::unique_ptr<proto::CompositorMessage> proto); // called on main thread. void HandleProto(const proto::CompositorMessageToImpl& proto); + void DidCompleteSwapBuffersOnMain(); void DidLoseOutputSurfaceOnMain(); void RequestNewOutputSurfaceOnMain(); void DidInitializeOutputSurfaceOnMain( bool success, const RendererCapabilities& capabilities); - void SendMessageProtoOnMain(scoped_ptr<proto::CompositorMessage> proto); + void SendMessageProtoOnMain(std::unique_ptr<proto::CompositorMessage> proto); void PostSetNeedsRedrawToImpl(const gfx::Rect& damaged_rect); void InitializeImplOnImpl(CompletionEvent* completion, diff --git a/chromium/cc/trees/remote_channel_main.cc b/chromium/cc/trees/remote_channel_main.cc index a5e9483a67e..a231bcbe061 100644 --- a/chromium/cc/trees/remote_channel_main.cc +++ b/chromium/cc/trees/remote_channel_main.cc @@ -4,7 +4,9 @@ #include "cc/trees/remote_channel_main.h" -#include "base/memory/scoped_ptr.h" +#include <memory> + +#include "base/memory/ptr_util.h" #include "cc/proto/base_conversions.h" #include "cc/proto/compositor_message.pb.h" #include "cc/proto/compositor_message_to_impl.pb.h" @@ -15,12 +17,12 @@ namespace cc { -scoped_ptr<RemoteChannelMain> RemoteChannelMain::Create( +std::unique_ptr<RemoteChannelMain> RemoteChannelMain::Create( RemoteProtoChannel* remote_proto_channel, ProxyMain* proxy_main, TaskRunnerProvider* task_runner_provider) { - return make_scoped_ptr(new RemoteChannelMain(remote_proto_channel, proxy_main, - task_runner_provider)); + return base::WrapUnique(new RemoteChannelMain( + remote_proto_channel, proxy_main, task_runner_provider)); } RemoteChannelMain::RemoteChannelMain(RemoteProtoChannel* remote_proto_channel, @@ -31,6 +33,7 @@ RemoteChannelMain::RemoteChannelMain(RemoteProtoChannel* remote_proto_channel, task_runner_provider_(task_runner_provider), initialized_(false), weak_factory_(this) { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::RemoteChannelMain"); DCHECK(remote_proto_channel_); DCHECK(proxy_main_); DCHECK(task_runner_provider_); @@ -39,6 +42,7 @@ RemoteChannelMain::RemoteChannelMain(RemoteProtoChannel* remote_proto_channel, } RemoteChannelMain::~RemoteChannelMain() { + TRACE_EVENT0("cc.remote", "~RemoteChannelMain::RemoteChannelMain"); DCHECK(task_runner_provider_->IsMainThread()); DCHECK(!initialized_); @@ -46,7 +50,8 @@ RemoteChannelMain::~RemoteChannelMain() { } void RemoteChannelMain::OnProtoReceived( - scoped_ptr<proto::CompositorMessage> proto) { + std::unique_ptr<proto::CompositorMessage> proto) { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::OnProtoReceived"); DCHECK(task_runner_provider_->IsMainThread()); DCHECK(proto->has_to_main()); @@ -75,6 +80,8 @@ void RemoteChannelMain::MainThreadHasStoppedFlingingOnImpl() { void RemoteChannelMain::SetInputThrottledUntilCommitOnImpl(bool is_throttled) {} void RemoteChannelMain::SetDeferCommitsOnImpl(bool defer_commits) { + TRACE_EVENT1("cc.remote", "RemoteChannelMain::SetDeferCommitsOnImpl", + "defer_commits", defer_commits); proto::CompositorMessage proto; proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); to_impl_proto->set_message_type( @@ -111,6 +118,7 @@ void RemoteChannelMain::MainFrameWillHappenOnImplForTesting( } void RemoteChannelMain::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::SetNeedsRedrawOnImpl"); proto::CompositorMessage proto; proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); to_impl_proto->set_message_type( @@ -129,6 +137,7 @@ void RemoteChannelMain::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) { } void RemoteChannelMain::SetNeedsCommitOnImpl() { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::SetNeedsCommitOnImpl"); proto::CompositorMessage proto; proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); to_impl_proto->set_message_type( @@ -141,6 +150,8 @@ void RemoteChannelMain::SetNeedsCommitOnImpl() { void RemoteChannelMain::BeginMainFrameAbortedOnImpl( CommitEarlyOutReason reason, base::TimeTicks main_thread_start_time) { + TRACE_EVENT1("cc.remote", "RemoteChannelMain::BeginMainFrameAbortedOnImpl", + "reason", CommitEarlyOutReasonToString(reason)); proto::CompositorMessage proto; proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); to_impl_proto->set_message_type( @@ -160,6 +171,7 @@ void RemoteChannelMain::StartCommitOnImpl( LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, bool hold_commit_for_activation) { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::StartCommitOnImpl"); proto::CompositorMessage proto; proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); to_impl_proto->set_message_type(proto::CompositorMessageToImpl::START_COMMIT); @@ -191,7 +203,8 @@ void RemoteChannelMain::StartCommitOnImpl( void RemoteChannelMain::SynchronouslyInitializeImpl( LayerTreeHost* layer_tree_host, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::SynchronouslyInitializeImpl"); DCHECK(!initialized_); proto::CompositorMessage proto; @@ -210,6 +223,7 @@ void RemoteChannelMain::SynchronouslyInitializeImpl( } void RemoteChannelMain::SynchronouslyCloseImpl() { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::SynchronouslyCloseImpl"); DCHECK(initialized_); proto::CompositorMessage proto; proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); @@ -222,11 +236,13 @@ void RemoteChannelMain::SynchronouslyCloseImpl() { void RemoteChannelMain::SendMessageProto( const proto::CompositorMessage& proto) { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::SendMessageProto"); remote_proto_channel_->SendCompositorProto(proto); } void RemoteChannelMain::HandleProto( const proto::CompositorMessageToMain& proto) { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::HandleProto"); DCHECK(proto.has_message_type()); switch (proto.message_type()) { @@ -234,10 +250,11 @@ void RemoteChannelMain::HandleProto( NOTIMPLEMENTED() << "Ignoring message proto of unknown type"; break; case proto::CompositorMessageToMain::BEGIN_MAIN_FRAME: { + TRACE_EVENT0("cc.remote", "RemoteChannelMain::BeginMainFrame"); VLOG(1) << "Received BeginMainFrame request from client."; const proto::BeginMainFrame& begin_main_frame_message = proto.begin_main_frame_message(); - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state; + std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state; begin_main_frame_state.reset(new BeginMainFrameAndCommitState); begin_main_frame_state->FromProtobuf( begin_main_frame_message.begin_main_frame_state()); diff --git a/chromium/cc/trees/remote_channel_main.h b/chromium/cc/trees/remote_channel_main.h index 7b2b9c7485d..1848f5c589c 100644 --- a/chromium/cc/trees/remote_channel_main.h +++ b/chromium/cc/trees/remote_channel_main.h @@ -22,7 +22,7 @@ class CompositorMessageToMain; class CC_EXPORT RemoteChannelMain : public ChannelMain, public RemoteProtoChannel::ProtoReceiver { public: - static scoped_ptr<RemoteChannelMain> Create( + static std::unique_ptr<RemoteChannelMain> Create( RemoteProtoChannel* remote_proto_channel, ProxyMain* proxy_main, TaskRunnerProvider* task_runner_provider); @@ -54,11 +54,12 @@ class CC_EXPORT RemoteChannelMain : public ChannelMain, bool hold_commit_for_activation) override; void SynchronouslyInitializeImpl( LayerTreeHost* layer_tree_host, - scoped_ptr<BeginFrameSource> external_begin_frame_source) override; + std::unique_ptr<BeginFrameSource> external_begin_frame_source) override; void SynchronouslyCloseImpl() override; // RemoteProtoChannel::ProtoReceiver implementation - void OnProtoReceived(scoped_ptr<proto::CompositorMessage> proto) override; + void OnProtoReceived( + std::unique_ptr<proto::CompositorMessage> proto) override; protected: RemoteChannelMain(RemoteProtoChannel* remote_proto_channel, diff --git a/chromium/cc/trees/remote_channel_unittest.cc b/chromium/cc/trees/remote_channel_unittest.cc index e33f5802f5f..e7a0ef0e91c 100644 --- a/chromium/cc/trees/remote_channel_unittest.cc +++ b/chromium/cc/trees/remote_channel_unittest.cc @@ -9,7 +9,8 @@ namespace cc { class RemoteChannelTest : public LayerTreeTest { protected: - RemoteChannelTest() : calls_received_(0) {} + RemoteChannelTest() + : calls_received_(0), calls_received_on_both_server_and_client_(0) {} ~RemoteChannelTest() override {} @@ -21,6 +22,11 @@ class RemoteChannelTest : public LayerTreeTest { int calls_received_; + // Since LayerTreeHost on engine and client share a common LayerTreeHostClient + // for unit tests, there are some functions called twice. This variable keep + // tracks of those function calls. + int calls_received_on_both_server_and_client_; + private: DISALLOW_COPY_AND_ASSIGN(RemoteChannelTest); }; @@ -140,8 +146,8 @@ class RemoteChannelTestCommit : public RemoteChannelTest { void DidCommitAndDrawFrame() override { EXPECT_EQ(3, calls_received_++); } void DidCompleteSwapBuffers() override { - EXPECT_EQ(4, calls_received_++); - EndTest(); + if (++calls_received_on_both_server_and_client_ == 2) + EndTest(); } void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { @@ -150,27 +156,12 @@ class RemoteChannelTestCommit : public RemoteChannelTest { EXPECT_EQ(viewport_size_, host_impl->device_viewport_size()); } - void ScheduledActionSendBeginMainFrame() override { - last_args_sent_ = GetProxyImplForTest()->last_begin_frame_args(); - } - - void BeginMainFrame(const BeginFrameArgs& args) override { - last_args_received_ = args; - } - void AfterTest() override { - EXPECT_EQ(5, calls_received_); - - // Ensure that we serialized and deserialized the - // BeginMainFrameAndCommitState. While the last_args_received_ will be set - // on the impl thread, it is safe to read it here since the impl thread has - // been destroyed now. - EXPECT_EQ(last_args_sent_, last_args_received_); + EXPECT_EQ(4, calls_received_); + EXPECT_EQ(2, calls_received_on_both_server_and_client_); } const gfx::Size viewport_size_ = gfx::Size(5, 3); - BeginFrameArgs last_args_sent_; - BeginFrameArgs last_args_received_; }; REMOTE_DIRECT_RENDERER_TEST_F(RemoteChannelTestCommit); diff --git a/chromium/cc/trees/remote_proto_channel.h b/chromium/cc/trees/remote_proto_channel.h index 76141a90894..8f7ad099a13 100644 --- a/chromium/cc/trees/remote_proto_channel.h +++ b/chromium/cc/trees/remote_proto_channel.h @@ -5,7 +5,8 @@ #ifndef CC_TREES_REMOTE_PROTO_CHANNEL_H_ #define CC_TREES_REMOTE_PROTO_CHANNEL_H_ -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "cc/base/cc_export.h" namespace cc { @@ -25,7 +26,7 @@ class CC_EXPORT RemoteProtoChannel { // TODO(khushalsagar): This should probably include a closure that returns // the status of processing this proto. See crbug/576974 virtual void OnProtoReceived( - scoped_ptr<proto::CompositorMessage> proto) = 0; + std::unique_ptr<proto::CompositorMessage> proto) = 0; protected: virtual ~ProtoReceiver() {} diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index 32fc307a0cf..201a0fa1323 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -5,6 +5,7 @@ #include "cc/trees/single_thread_proxy.h" #include "base/auto_reset.h" +#include "base/memory/ptr_util.h" #include "base/profiler/scoped_tracker.h" #include "base/trace_event/trace_event.h" #include "cc/animation/animation_events.h" @@ -24,11 +25,11 @@ namespace cc { -scoped_ptr<Proxy> SingleThreadProxy::Create( +std::unique_ptr<Proxy> SingleThreadProxy::Create( LayerTreeHost* layer_tree_host, LayerTreeHostSingleThreadClient* client, TaskRunnerProvider* task_runner_provider) { - return make_scoped_ptr( + return base::WrapUnique( new SingleThreadProxy(layer_tree_host, client, task_runner_provider)); } @@ -56,7 +57,7 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, } void SingleThreadProxy::Start( - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { DebugScopedSetImplThread impl(task_runner_provider_); external_begin_frame_source_ = std::move(external_begin_frame_source); @@ -66,24 +67,27 @@ void SingleThreadProxy::Start( layer_tree_host_->settings().ToSchedulerSettings()); scheduler_settings.commit_to_active_tree = CommitToActiveTree(); - scoped_ptr<CompositorTimingHistory> compositor_timing_history( + std::unique_ptr<CompositorTimingHistory> compositor_timing_history( new CompositorTimingHistory( scheduler_settings.using_synchronous_renderer_compositor, CompositorTimingHistory::BROWSER_UMA, layer_tree_host_->rendering_stats_instrumentation())); - BeginFrameSource* frame_source = external_begin_frame_source_.get(); - if (!scheduler_settings.throttle_frame_production) { - // Unthrottled source takes precedence over external sources. - unthrottled_begin_frame_source_.reset(new BackToBackBeginFrameSource( - task_runner_provider_->MainThreadTaskRunner())); - frame_source = unthrottled_begin_frame_source_.get(); - } - if (!frame_source) { - synthetic_begin_frame_source_.reset(new SyntheticBeginFrameSource( - task_runner_provider_->MainThreadTaskRunner(), - BeginFrameArgs::DefaultInterval())); - frame_source = synthetic_begin_frame_source_.get(); + BeginFrameSource* frame_source = nullptr; + if (!layer_tree_host_->settings().use_output_surface_begin_frame_source) { + frame_source = external_begin_frame_source_.get(); + if (!scheduler_settings.throttle_frame_production) { + // Unthrottled source takes precedence over external sources. + unthrottled_begin_frame_source_.reset(new BackToBackBeginFrameSource( + task_runner_provider_->MainThreadTaskRunner())); + frame_source = unthrottled_begin_frame_source_.get(); + } + if (!frame_source) { + synthetic_begin_frame_source_.reset(new SyntheticBeginFrameSource( + task_runner_provider_->MainThreadTaskRunner(), + BeginFrameArgs::DefaultInterval())); + frame_source = synthetic_begin_frame_source_.get(); + } } scheduler_on_impl_thread_ = @@ -214,6 +218,11 @@ void SingleThreadProxy::DoCommit() { devtools_instrumentation::ScopedCommitTrace commit_task( layer_tree_host_->id()); + layer_tree_host_->ReportFixedRasterScaleUseCounters( + layer_tree_host_impl_->has_fixed_raster_scale_blurry_content(), + layer_tree_host_impl_ + ->HasFixedRasterScalePotentialPerformanceRegression()); + // Commit immediately. { // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 @@ -250,7 +259,7 @@ void SingleThreadProxy::DoCommit() { #if DCHECK_IS_ON() // In the single-threaded case, the scale and scroll deltas should never be // touched on the impl layer tree. - scoped_ptr<ScrollAndScaleSet> scroll_info = + std::unique_ptr<ScrollAndScaleSet> scroll_info = layer_tree_host_impl_->ProcessScrollDeltas(); DCHECK(!scroll_info->scrolls.size()); DCHECK_EQ(1.f, scroll_info->page_scale_delta); @@ -423,7 +432,7 @@ void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) { } void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEvents> events) { + std::unique_ptr<AnimationEvents> events) { TRACE_EVENT0( "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); DCHECK(task_runner_provider_->IsImplThread()); @@ -477,19 +486,25 @@ void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) { - if (authoritative_vsync_interval_ != base::TimeDelta()) { - interval = authoritative_vsync_interval_; - } else if (interval == base::TimeDelta()) { + if (interval.is_zero()) { // TODO(brianderson): We should not be receiving 0 intervals. interval = BeginFrameArgs::DefaultInterval(); } - last_vsync_timebase_ = timebase; - if (synthetic_begin_frame_source_) synthetic_begin_frame_source_->OnUpdateVSyncParameters(timebase, interval); } +void SingleThreadProxy::SetBeginFrameSource(BeginFrameSource* source) { + DCHECK(layer_tree_host_->settings().single_thread_proxy_scheduler); + // TODO(enne): this overrides any preexisting begin frame source. Those + // other sources will eventually be removed and this will be the only path. + if (!layer_tree_host_->settings().use_output_surface_begin_frame_source) + return; + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetBeginFrameSource(source); +} + void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time); @@ -515,13 +530,6 @@ 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(std::move(composite_events), - std::move(main_frame_events)); -} - void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately"); DCHECK(task_runner_provider_->IsMainThread()); @@ -714,21 +722,6 @@ bool SingleThreadProxy::MainFrameWillHappenForTesting() { return scheduler_on_impl_thread_->MainFrameForTestingWillHappen(); } -void SingleThreadProxy::SetChildrenNeedBeginFrames( - bool children_need_begin_frames) { - scheduler_on_impl_thread_->SetChildrenNeedBeginFrames( - children_need_begin_frames); -} - -void SingleThreadProxy::SetAuthoritativeVSyncInterval( - const base::TimeDelta& interval) { - authoritative_vsync_interval_ = interval; - if (synthetic_begin_frame_source_) { - synthetic_begin_frame_source_->OnUpdateVSyncParameters(last_vsync_timebase_, - interval); - } -} - void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { DebugScopedSetImplThread impl(task_runner_provider_); #if DCHECK_IS_ON() @@ -887,10 +880,6 @@ void SingleThreadProxy::UpdateTopControlsState(TopControlsState constraints, NOTREACHED() << "Top Controls are used only in threaded mode"; } -void SingleThreadProxy::SetOutputIsSecure(bool output_is_secure) { - layer_tree_host_impl_->set_output_is_secure(output_is_secure); -} - void SingleThreadProxy::DidFinishImplFrame() { layer_tree_host_impl_->DidFinishImplFrame(); #if DCHECK_IS_ON() @@ -900,8 +889,4 @@ void SingleThreadProxy::DidFinishImplFrame() { #endif } -void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) { - layer_tree_host_->SendBeginFramesToChildren(args); -} - } // namespace cc diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index b5477f2e535..fc761213ef3 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -29,9 +29,10 @@ class CC_EXPORT SingleThreadProxy : public Proxy, NON_EXPORTED_BASE(LayerTreeHostImplClient), SchedulerClient { public: - static scoped_ptr<Proxy> Create(LayerTreeHost* layer_tree_host, - LayerTreeHostSingleThreadClient* client, - TaskRunnerProvider* task_runner_provider_); + static std::unique_ptr<Proxy> Create( + LayerTreeHost* layer_tree_host, + LayerTreeHostSingleThreadClient* client, + TaskRunnerProvider* task_runner_provider_); ~SingleThreadProxy() override; // Proxy implementation @@ -52,16 +53,14 @@ class CC_EXPORT SingleThreadProxy : public Proxy, bool CommitRequested() const override; bool BeginMainFrameRequested() const override; void MainThreadHasStoppedFlinging() override {} - void Start(scoped_ptr<BeginFrameSource> external_begin_frame_source) override; + void Start( + std::unique_ptr<BeginFrameSource> external_begin_frame_source) override; void Stop() override; bool SupportsImplScrolling() const override; bool MainFrameWillHappenForTesting() override; - void SetChildrenNeedBeginFrames(bool children_need_begin_frames) override; - void SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) override; void UpdateTopControlsState(TopControlsState constraints, TopControlsState current, bool animate) override; - void SetOutputIsSecure(bool output_is_secure) override; // SchedulerClient implementation void WillBeginImplFrame(const BeginFrameArgs& args) override; @@ -74,7 +73,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void ScheduledActionBeginOutputSurfaceCreation() override; void ScheduledActionPrepareTiles() override; void ScheduledActionInvalidateOutputSurface() override; - void SendBeginFramesToChildren(const BeginFrameArgs& args) override; void SendBeginMainFrameNotExpectedSoon() override; // LayerTreeHostImplClient implementation @@ -82,6 +80,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void DidLoseOutputSurfaceOnImplThread() override; void CommitVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) override; + void SetBeginFrameSource(BeginFrameSource* source) override; void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override; void DidSwapBuffersOnImplThread() override; void DidSwapBuffersCompleteOnImplThread() override; @@ -95,7 +94,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void SetNeedsCommitOnImplThread() override; void SetVideoNeedsBeginFrames(bool needs_begin_frames) override; void PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEvents> events) override; + std::unique_ptr<AnimationEvents> events) override; bool IsInsideDraw() override; void RenewTreePriority() override {} void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -105,10 +104,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void DidPrepareTiles() override; void DidCompletePageScaleAnimationOnImplThread() override; void OnDrawForOutputSurface(bool resourceless_software_draw) override; - void PostFrameTimingEventsOnImplThread( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) - override; void RequestNewOutputSurface(); @@ -141,19 +136,17 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // Used on the Thread, but checked on main thread during // initialization/shutdown. - scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl_; + std::unique_ptr<LayerTreeHostImpl> layer_tree_host_impl_; RendererCapabilities renderer_capabilities_for_main_thread_; // Accessed from both threads. - scoped_ptr<BeginFrameSource> external_begin_frame_source_; - scoped_ptr<BeginFrameSource> unthrottled_begin_frame_source_; - scoped_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source_; - scoped_ptr<Scheduler> scheduler_on_impl_thread_; + std::unique_ptr<BeginFrameSource> external_begin_frame_source_; + std::unique_ptr<BeginFrameSource> unthrottled_begin_frame_source_; + std::unique_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source_; + std::unique_ptr<Scheduler> scheduler_on_impl_thread_; - base::TimeDelta authoritative_vsync_interval_; - base::TimeTicks last_vsync_timebase_; - - scoped_ptr<BlockingTaskRunner::CapturePostTasks> commit_blocking_task_runner_; + std::unique_ptr<BlockingTaskRunner::CapturePostTasks> + commit_blocking_task_runner_; bool next_frame_is_newly_committed_frame_; #if DCHECK_IS_ON() diff --git a/chromium/cc/trees/task_runner_provider.h b/chromium/cc/trees/task_runner_provider.h index cab850e52d8..12fa51dd30e 100644 --- a/chromium/cc/trees/task_runner_provider.h +++ b/chromium/cc/trees/task_runner_provider.h @@ -5,12 +5,13 @@ #ifndef CC_TREES_TASK_RUNNER_PROVIDER_H_ #define CC_TREES_TASK_RUNNER_PROVIDER_H_ +#include <memory> #include <string> #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/single_thread_task_runner.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" @@ -31,10 +32,10 @@ class BlockingTaskRunner; // Useful for assertion checks. class CC_EXPORT TaskRunnerProvider { public: - static scoped_ptr<TaskRunnerProvider> Create( + static std::unique_ptr<TaskRunnerProvider> Create( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { - return make_scoped_ptr( + return base::WrapUnique( new TaskRunnerProvider(main_task_runner, impl_task_runner)); } @@ -69,7 +70,7 @@ class CC_EXPORT TaskRunnerProvider { private: scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_; - scoped_ptr<BlockingTaskRunner> blocking_main_thread_task_runner_; + std::unique_ptr<BlockingTaskRunner> blocking_main_thread_task_runner_; #if DCHECK_IS_ON() const base::PlatformThreadId main_thread_id_; diff --git a/chromium/cc/trees/threaded_channel.cc b/chromium/cc/trees/threaded_channel.cc index 7d1d7285904..24ef3f7096c 100644 --- a/chromium/cc/trees/threaded_channel.cc +++ b/chromium/cc/trees/threaded_channel.cc @@ -5,6 +5,7 @@ #include "cc/trees/threaded_channel.h" #include "base/bind.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" #include "cc/animation/animation_events.h" @@ -12,10 +13,11 @@ namespace cc { -scoped_ptr<ThreadedChannel> ThreadedChannel::Create( +std::unique_ptr<ThreadedChannel> ThreadedChannel::Create( ProxyMain* proxy_main, TaskRunnerProvider* task_runner_provider) { - return make_scoped_ptr(new ThreadedChannel(proxy_main, task_runner_provider)); + return base::WrapUnique( + new ThreadedChannel(proxy_main, task_runner_provider)); } ThreadedChannel::ThreadedChannel(ProxyMain* proxy_main, @@ -141,7 +143,7 @@ void ThreadedChannel::StartCommitOnImpl(CompletionEvent* completion, void ThreadedChannel::SynchronouslyInitializeImpl( LayerTreeHost* layer_tree_host, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { TRACE_EVENT0("cc", "ThreadChannel::SynchronouslyInitializeImpl"); DCHECK(IsMainThread()); { @@ -214,7 +216,8 @@ void ThreadedChannel::DidCommitAndDrawFrame() { impl().proxy_main_weak_ptr)); } -void ThreadedChannel::SetAnimationEvents(scoped_ptr<AnimationEvents> events) { +void ThreadedChannel::SetAnimationEvents( + std::unique_ptr<AnimationEvents> events) { DCHECK(IsImplThread()); MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&ProxyMain::SetAnimationEvents, @@ -251,19 +254,8 @@ void ThreadedChannel::DidCompletePageScaleAnimation() { impl().proxy_main_weak_ptr)); } -void ThreadedChannel::PostFrameTimingEventsOnMain( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) { - DCHECK(IsImplThread()); - MainThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyMain::PostFrameTimingEventsOnMain, - impl().proxy_main_weak_ptr, - base::Passed(std::move(composite_events)), - base::Passed(std::move(main_frame_events)))); -} - void ThreadedChannel::BeginMainFrame( - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { + std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { DCHECK(IsImplThread()); MainThreadTaskRunner()->PostTask( FROM_HERE, @@ -271,11 +263,11 @@ void ThreadedChannel::BeginMainFrame( base::Passed(&begin_main_frame_state))); } -scoped_ptr<ProxyImpl> ThreadedChannel::CreateProxyImpl( +std::unique_ptr<ProxyImpl> ThreadedChannel::CreateProxyImpl( ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { DCHECK(IsImplThread()); return ProxyImpl::Create(channel_impl, layer_tree_host, task_runner_provider, std::move(external_begin_frame_source)); @@ -284,12 +276,12 @@ scoped_ptr<ProxyImpl> ThreadedChannel::CreateProxyImpl( void ThreadedChannel::InitializeImplOnImpl( CompletionEvent* completion, LayerTreeHost* layer_tree_host, - scoped_ptr<BeginFrameSource> external_begin_frame_source) { + std::unique_ptr<BeginFrameSource> external_begin_frame_source) { DCHECK(IsImplThread()); impl().proxy_impl = CreateProxyImpl(this, layer_tree_host, task_runner_provider_, std::move(external_begin_frame_source)); - impl().proxy_impl_weak_factory = make_scoped_ptr( + impl().proxy_impl_weak_factory = base::WrapUnique( new base::WeakPtrFactory<ProxyImpl>(impl().proxy_impl.get())); proxy_impl_weak_ptr_ = impl().proxy_impl_weak_factory->GetWeakPtr(); completion->Signal(); diff --git a/chromium/cc/trees/threaded_channel.h b/chromium/cc/trees/threaded_channel.h index 2a669d472a7..77a51d13a57 100644 --- a/chromium/cc/trees/threaded_channel.h +++ b/chromium/cc/trees/threaded_channel.h @@ -5,9 +5,10 @@ #ifndef CC_TREES_THREADED_CHANNEL_H_ #define CC_TREES_THREADED_CHANNEL_H_ +#include <memory> + #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" #include "cc/trees/channel_impl.h" @@ -76,7 +77,7 @@ class ProxyMain; class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { public: - static scoped_ptr<ThreadedChannel> Create( + static std::unique_ptr<ThreadedChannel> Create( ProxyMain* proxy_main, TaskRunnerProvider* task_runner_provider); @@ -109,7 +110,7 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { bool hold_commit_for_activation) override; void SynchronouslyInitializeImpl( LayerTreeHost* layer_tree_host, - scoped_ptr<BeginFrameSource> external_begin_frame_source) override; + std::unique_ptr<BeginFrameSource> external_begin_frame_source) override; void SynchronouslyCloseImpl() override; // ChannelImpl Implementation @@ -118,30 +119,26 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { const RendererCapabilities& capabilities) override; void BeginMainFrameNotExpectedSoon() override; void DidCommitAndDrawFrame() override; - void SetAnimationEvents(scoped_ptr<AnimationEvents> events) override; + void SetAnimationEvents(std::unique_ptr<AnimationEvents> events) override; void DidLoseOutputSurface() override; void RequestNewOutputSurface() override; void DidInitializeOutputSurface( bool success, const RendererCapabilities& capabilities) override; void DidCompletePageScaleAnimation() override; - void PostFrameTimingEventsOnMain( - scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, - scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) - override; - void BeginMainFrame( - scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) override; + void BeginMainFrame(std::unique_ptr<BeginMainFrameAndCommitState> + begin_main_frame_state) override; protected: ThreadedChannel(ProxyMain* proxy_main, TaskRunnerProvider* task_runner_provider); // Virtual for testing. - virtual scoped_ptr<ProxyImpl> CreateProxyImpl( + virtual std::unique_ptr<ProxyImpl> CreateProxyImpl( ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<BeginFrameSource> external_begin_frame_source); private: // The members of this struct should be accessed on the main thread only. @@ -158,15 +155,15 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { explicit CompositorThreadOnly(base::WeakPtr<ProxyMain> proxy_main_weak_ptr); ~CompositorThreadOnly(); - scoped_ptr<ProxyImpl> proxy_impl; + std::unique_ptr<ProxyImpl> proxy_impl; - // We use a scoped_ptr for the weak ptr factory here since the factory is + // We use a unique_ptr for the weak ptr factory here since the factory is // created after ProxyImpl is created in InitializeImplOnImpl. Since the // weak ptrs are needed only by the ThreadedChannel to safely post tasks on // ProxyImpl to be run on the impl thread, we avoid creating it in ProxyImpl // and ensure that it is destroyed before ProxyImpl during the impl-thread // tear down in CloseImplOnImpl. - scoped_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory; + std::unique_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory; // Used on the impl thread to queue calls to ProxyMain to be run on the main // thread. Since the weak pointer is invalidated after the impl-thread tear @@ -180,7 +177,7 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { void InitializeImplOnImpl( CompletionEvent* completion, LayerTreeHost* layer_tree_host, - scoped_ptr<BeginFrameSource> external_begin_frame_source); + std::unique_ptr<BeginFrameSource> external_begin_frame_source); void CloseImplOnImpl(CompletionEvent* completion); bool IsInitialized() const; diff --git a/chromium/cc/trees/threaded_channel_unittest.cc b/chromium/cc/trees/threaded_channel_unittest.cc index 81d28def59c..08d532aaa9d 100644 --- a/chromium/cc/trees/threaded_channel_unittest.cc +++ b/chromium/cc/trees/threaded_channel_unittest.cc @@ -5,6 +5,7 @@ #include "cc/trees/threaded_channel.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "cc/animation/animation_events.h" #include "cc/test/layer_tree_test.h" #include "cc/trees/single_thread_proxy.h" @@ -243,7 +244,8 @@ class ThreadedChannelTestSetAnimationEvents : public ThreadedChannelTest { void BeginChannelTest() override { PostOnImplThread(); } void StartTestOnImplThread() override { - scoped_ptr<AnimationEvents> events(make_scoped_ptr(new AnimationEvents)); + std::unique_ptr<AnimationEvents> events( + base::WrapUnique(new AnimationEvents)); GetProxyImplForTest()->PostAnimationEventsToMainThreadOnImplThread( std::move(events)); } diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc index c7e42ea0661..c726f83f8a9 100644 --- a/chromium/cc/trees/tree_synchronizer.cc +++ b/chromium/cc/trees/tree_synchronizer.cc @@ -23,7 +23,7 @@ void SynchronizeTreesInternal(LayerType* layer_root, LayerTreeImpl* tree_impl) { DCHECK(tree_impl); TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees"); - scoped_ptr<OwnedLayerImplList> old_layers(tree_impl->DetachLayers()); + std::unique_ptr<OwnedLayerImplList> old_layers(tree_impl->DetachLayers()); OwnedLayerImplMap old_layer_map; for (auto& it : *old_layers) @@ -57,26 +57,26 @@ void TreeSynchronizer::SynchronizeTrees(LayerImpl* layer_root, } template <typename LayerType> -scoped_ptr<LayerImpl> ReuseOrCreateLayerImpl(OwnedLayerImplMap* old_layers, - LayerType* layer, - LayerTreeImpl* tree_impl) { +std::unique_ptr<LayerImpl> ReuseOrCreateLayerImpl(OwnedLayerImplMap* old_layers, + LayerType* layer, + LayerTreeImpl* tree_impl) { if (!layer) return nullptr; - scoped_ptr<LayerImpl> layer_impl = std::move((*old_layers)[layer->id()]); + std::unique_ptr<LayerImpl> layer_impl = std::move((*old_layers)[layer->id()]); if (!layer_impl) layer_impl = layer->CreateLayerImpl(tree_impl); return layer_impl; } template <typename LayerType> -scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( +std::unique_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( OwnedLayerImplMap* old_layers, LayerType* layer, LayerTreeImpl* tree_impl) { if (!layer) return nullptr; - scoped_ptr<LayerImpl> layer_impl( + std::unique_ptr<LayerImpl> layer_impl( ReuseOrCreateLayerImpl(old_layers, layer, tree_impl)); layer_impl->children().clear(); @@ -85,7 +85,7 @@ scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( old_layers, layer->child_at(i), tree_impl)); } - scoped_ptr<LayerImpl> mask_layer = SynchronizeTreesRecursiveInternal( + std::unique_ptr<LayerImpl> mask_layer = SynchronizeTreesRecursiveInternal( old_layers, layer->mask_layer(), tree_impl); if (layer_impl->mask_layer() && mask_layer && layer_impl->mask_layer() == mask_layer.get()) { @@ -96,7 +96,7 @@ scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( layer_impl->SetMaskLayer(std::move(mask_layer)); } - scoped_ptr<LayerImpl> replica_layer = SynchronizeTreesRecursiveInternal( + std::unique_ptr<LayerImpl> replica_layer = SynchronizeTreesRecursiveInternal( old_layers, layer->replica_layer(), tree_impl); if (layer_impl->replica_layer() && replica_layer && layer_impl->replica_layer() == replica_layer.get()) { @@ -124,63 +124,6 @@ void SynchronizeTreesRecursive(OwnedLayerImplMap* old_layers, SynchronizeTreesRecursiveInternal(old_layers, old_root, tree_impl)); } -#if DCHECK_IS_ON() -static void CheckScrollAndClipPointersForLayer(Layer* layer, - LayerImpl* layer_impl) { - DCHECK_EQ(!!layer, !!layer_impl); - if (!layer) - return; - - // Having a scroll parent on the impl thread implies having one the main - // thread, too. The main thread may have a scroll parent that is not in the - // tree because it's been removed but not deleted. In this case, the layer - // impl will have no scroll parent. Same argument applies for clip parents and - // scroll/clip children. - DCHECK(!layer_impl->scroll_parent() || !!layer->scroll_parent()); - DCHECK(!layer_impl->clip_parent() || !!layer->clip_parent()); - DCHECK(!layer_impl->scroll_children() || !!layer->scroll_children()); - DCHECK(!layer_impl->clip_children() || !!layer->clip_children()); - - if (layer_impl->scroll_parent()) - DCHECK_EQ(layer->scroll_parent()->id(), layer_impl->scroll_parent()->id()); - - if (layer_impl->clip_parent()) - DCHECK_EQ(layer->clip_parent()->id(), layer_impl->clip_parent()->id()); - - if (layer_impl->scroll_children()) { - for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); - it != layer->scroll_children()->end(); ++it) { - DCHECK_EQ((*it)->scroll_parent(), layer); - } - for (std::set<LayerImpl*>::iterator it = - layer_impl->scroll_children()->begin(); - it != layer_impl->scroll_children()->end(); ++it) { - DCHECK_EQ((*it)->scroll_parent(), layer_impl); - } - } - - if (layer_impl->clip_children()) { - for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); - it != layer->clip_children()->end(); ++it) { - DCHECK_EQ((*it)->clip_parent(), layer); - } - for (std::set<LayerImpl*>::iterator it = - layer_impl->clip_children()->begin(); - it != layer_impl->clip_children()->end(); ++it) { - DCHECK_EQ((*it)->clip_parent(), layer_impl); - } - } -} - -static void CheckScrollAndClipPointers(LayerTreeHost* host, - LayerTreeImpl* host_impl) { - for (auto* layer_impl : *host_impl) { - Layer* layer = host->LayerById(layer_impl->id()); - CheckScrollAndClipPointersForLayer(layer, layer_impl); - } -} -#endif - template <typename LayerType> static void PushLayerPropertiesInternal( std::unordered_set<LayerType*> layers_that_should_push_properties, @@ -202,11 +145,6 @@ void TreeSynchronizer::PushLayerProperties(LayerTreeHost* host_tree, LayerTreeImpl* impl_tree) { PushLayerPropertiesInternal(host_tree->LayersThatShouldPushProperties(), impl_tree); - -#if DCHECK_IS_ON() - if (host_tree->root_layer() && impl_tree->root_layer()) - CheckScrollAndClipPointers(host_tree, impl_tree); -#endif } } // namespace cc diff --git a/chromium/cc/trees/tree_synchronizer.h b/chromium/cc/trees/tree_synchronizer.h index 260bd7b455d..be2e7439e77 100644 --- a/chromium/cc/trees/tree_synchronizer.h +++ b/chromium/cc/trees/tree_synchronizer.h @@ -5,8 +5,9 @@ #ifndef CC_TREES_TREE_SYNCHRONIZER_H_ #define CC_TREES_TREE_SYNCHRONIZER_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" namespace cc { diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index f625ccab799..b9c1dce0cc4 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -11,8 +11,8 @@ #include <vector> #include "base/format_macros.h" +#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" -#include "cc/animation/layer_animation_controller.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" #include "cc/test/animation_test_common.h" @@ -31,9 +31,9 @@ namespace { class MockLayerImpl : public LayerImpl { public: - static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl, - int layer_id) { - return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id)); + static std::unique_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl, + int layer_id) { + return base::WrapUnique(new MockLayerImpl(tree_impl, layer_id)); } ~MockLayerImpl() override { if (layer_impl_destruction_list_) @@ -58,7 +58,8 @@ class MockLayer : public Layer { return make_scoped_refptr(new MockLayer(layer_impl_destruction_list)); } - scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { + std::unique_ptr<LayerImpl> CreateLayerImpl( + LayerTreeImpl* tree_impl) override { return MockLayerImpl::Create(tree_impl, layer_id_); } @@ -108,52 +109,18 @@ void ExpectTreesAreIdentical(Layer* layer, ASSERT_EQ(layer_children.size(), layer_impl_children.size()); - const std::set<Layer*>* layer_scroll_children = layer->scroll_children(); - const std::set<LayerImpl*>* layer_impl_scroll_children = - layer_impl->scroll_children(); - - ASSERT_EQ(!!layer_scroll_children, !!layer_impl_scroll_children); - - if (layer_scroll_children) { - ASSERT_EQ(layer_scroll_children->size(), - layer_impl_scroll_children->size()); - } - const Layer* layer_scroll_parent = layer->scroll_parent(); - const LayerImpl* layer_impl_scroll_parent = layer_impl->scroll_parent(); - - ASSERT_EQ(!!layer_scroll_parent, !!layer_impl_scroll_parent); if (layer_scroll_parent) { - ASSERT_EQ(layer_scroll_parent->id(), layer_impl_scroll_parent->id()); ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) != layer_scroll_parent->scroll_children()->end()); - ASSERT_TRUE(layer_impl_scroll_parent->scroll_children()->find(layer_impl) != - layer_impl_scroll_parent->scroll_children()->end()); } - const std::set<Layer*>* layer_clip_children = layer->clip_children(); - const std::set<LayerImpl*>* layer_impl_clip_children = - layer_impl->clip_children(); - - ASSERT_EQ(!!layer_clip_children, !!layer_impl_clip_children); - - if (layer_clip_children) - ASSERT_EQ(layer_clip_children->size(), layer_impl_clip_children->size()); - const Layer* layer_clip_parent = layer->clip_parent(); - const LayerImpl* layer_impl_clip_parent = layer_impl->clip_parent(); - - ASSERT_EQ(!!layer_clip_parent, !!layer_impl_clip_parent); if (layer_clip_parent) { - const std::set<LayerImpl*>* clip_children_impl = - layer_impl_clip_parent->clip_children(); const std::set<Layer*>* clip_children = layer_clip_parent->clip_children(); - ASSERT_EQ(layer_clip_parent->id(), layer_impl_clip_parent->id()); ASSERT_TRUE(clip_children->find(layer) != clip_children->end()); - ASSERT_TRUE(clip_children_impl->find(layer_impl) != - clip_children_impl->end()); } for (size_t i = 0; i < layer_children.size(); ++i) { @@ -172,7 +139,7 @@ class TreeSynchronizerTest : public testing::Test { protected: FakeLayerTreeHostClient client_; TestTaskGraphRunner task_graph_runner_; - scoped_ptr<FakeLayerTreeHost> host_; + std::unique_ptr<FakeLayerTreeHost> host_; bool is_equal(ScrollTree::ScrollOffsetMap map, ScrollTree::ScrollOffsetMap other) { @@ -287,8 +254,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), host_->active_tree()); - host_->active_tree()->ResetAllChangeTracking( - PropertyTrees::ResetFlags::ALL_TREES); + host_->active_tree()->ResetAllChangeTracking(); // re-insert the layer and sync again. child2->RemoveFromParent(); @@ -529,140 +495,6 @@ TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) { host_->active_tree()->ClearLayers(); } -TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) { - LayerTreeSettings settings; - FakeImplTaskRunnerProvider task_runner_provider; - FakeRenderingStatsInstrumentation stats_instrumentation; - FakeLayerTreeHostImplClient impl_client; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( - settings, &impl_client, &task_runner_provider, &stats_instrumentation, - &shared_bitmap_manager, nullptr, &task_graph_runner, 0); - - scoped_refptr<Layer> layer_tree_root = Layer::Create(); - scoped_refptr<Layer> scroll_parent = Layer::Create(); - layer_tree_root->AddChild(scroll_parent); - layer_tree_root->AddChild(Layer::Create()); - layer_tree_root->AddChild(Layer::Create()); - - host_->SetRootLayer(layer_tree_root); - - // First child is the second and third child's scroll parent. - layer_tree_root->children()[1]->SetScrollParent(scroll_parent.get()); - layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get()); - - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - host_impl->active_tree()); - LayerImpl* layer_impl_tree_root = host_impl->active_tree()->root_layer(); - TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), - host_impl->active_tree()); - { - SCOPED_TRACE("case one"); - ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, - host_impl->active_tree()); - } - - // Remove the first scroll child. - layer_tree_root->children()[1]->RemoveFromParent(); - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - host_impl->active_tree()); - TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), - host_impl->active_tree()); - { - SCOPED_TRACE("case two"); - ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, - host_impl->active_tree()); - } - - // Add an additional scroll layer. - scoped_refptr<Layer> additional_scroll_child = Layer::Create(); - layer_tree_root->AddChild(additional_scroll_child); - additional_scroll_child->SetScrollParent(scroll_parent.get()); - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - host_impl->active_tree()); - TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), - host_impl->active_tree()); - { - SCOPED_TRACE("case three"); - ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, - host_impl->active_tree()); - } -} - -TEST_F(TreeSynchronizerTest, SynchronizeClipParent) { - LayerTreeSettings settings; - FakeImplTaskRunnerProvider task_runner_provider; - FakeRenderingStatsInstrumentation stats_instrumentation; - FakeLayerTreeHostImplClient impl_client; - TestSharedBitmapManager shared_bitmap_manager; - TestTaskGraphRunner task_graph_runner; - scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( - settings, &impl_client, &task_runner_provider, &stats_instrumentation, - &shared_bitmap_manager, nullptr, &task_graph_runner, 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(); - layer_tree_root->AddChild(clip_parent); - clip_parent->AddChild(intervening); - intervening->AddChild(clip_child1); - intervening->AddChild(clip_child2); - - host_->SetRootLayer(layer_tree_root); - - // First child is the second and third child's scroll parent. - clip_child1->SetClipParent(clip_parent.get()); - clip_child2->SetClipParent(clip_parent.get()); - - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - host_impl->active_tree()); - LayerImpl* layer_impl_tree_root = host_impl->active_tree()->root_layer(); - TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), - host_impl->active_tree()); - ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, - host_impl->active_tree()); - - // Remove the first clip child. - clip_child1->RemoveFromParent(); - clip_child1 = NULL; - - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - host_impl->active_tree()); - TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), - host_impl->active_tree()); - ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, - host_impl->active_tree()); - - // Add an additional clip child. - scoped_refptr<Layer> additional_clip_child = Layer::Create(); - intervening->AddChild(additional_clip_child); - additional_clip_child->SetClipParent(clip_parent.get()); - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - host_impl->active_tree()); - TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), - host_impl->active_tree()); - ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, - host_impl->active_tree()); - - // Remove the nearest clipping ancestor. - clip_parent->RemoveFromParent(); - clip_parent = NULL; - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - host_impl->active_tree()); - TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), - host_impl->active_tree()); - ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, - host_impl->active_tree()); - - // The clip children should have been unhooked. - EXPECT_EQ(2u, intervening->children().size()); - EXPECT_FALSE(clip_child2->clip_parent()); - EXPECT_FALSE(additional_clip_child->clip_parent()); -} - TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) { LayerTreeSettings settings; FakeLayerTreeHostImplClient client; @@ -773,7 +605,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { gfx::ScrollOffset(20, 30)); // Pull ScrollOffset delta for main thread, and change offset on main thread - scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); + std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); scroll_tree.CollectScrollDeltas(scroll_info.get()); host_->proxy()->SetNeedsCommit(); host_->ApplyScrollAndScale(scroll_info.get()); |