summaryrefslogtreecommitdiffstats
path: root/chromium/cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-07-31 15:50:41 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 12:35:23 +0000
commit7b2ffa587235a47d4094787d72f38102089f402a (patch)
tree30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/cc
parentd94af01c90575348c4e81a418257f254b6f8d225 (diff)
BASELINE: Update Chromium to 76.0.3809.94
Change-Id: I321c3f5f929c105aec0f98c5091ef6108822e647 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/cc')
-rw-r--r--chromium/cc/BUILD.gn5
-rw-r--r--chromium/cc/DEPS1
-rw-r--r--chromium/cc/animation/DEPS1
-rw-r--r--chromium/cc/animation/animation.cc10
-rw-r--r--chromium/cc/animation/animation.h3
-rw-r--r--chromium/cc/animation/animation_host.cc108
-rw-r--r--chromium/cc/animation/animation_host.h28
-rw-r--r--chromium/cc/animation/animation_host_unittest.cc26
-rw-r--r--chromium/cc/animation/animation_unittest.cc150
-rw-r--r--chromium/cc/animation/element_animations.cc124
-rw-r--r--chromium/cc/animation/element_animations.h30
-rw-r--r--chromium/cc/animation/element_animations_unittest.cc676
-rw-r--r--chromium/cc/animation/keyframe_effect.cc125
-rw-r--r--chromium/cc/animation/keyframe_effect.h21
-rw-r--r--chromium/cc/animation/keyframed_animation_curve_unittest.cc41
-rw-r--r--chromium/cc/animation/scroll_timeline.cc28
-rw-r--r--chromium/cc/animation/scroll_timeline.h5
-rw-r--r--chromium/cc/animation/scroll_timeline_unittest.cc41
-rw-r--r--chromium/cc/animation/single_keyframe_effect_animation.cc2
-rw-r--r--chromium/cc/animation/timing_function.cc42
-rw-r--r--chromium/cc/animation/timing_function.h29
-rw-r--r--chromium/cc/animation/worklet_animation.cc94
-rw-r--r--chromium/cc/animation/worklet_animation.h39
-rw-r--r--chromium/cc/animation/worklet_animation_unittest.cc154
-rw-r--r--chromium/cc/base/rtree.h90
-rw-r--r--chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc4
-rw-r--r--chromium/cc/debug/layer_tree_debug_state.cc5
-rw-r--r--chromium/cc/debug/layer_tree_debug_state.h1
-rw-r--r--chromium/cc/input/event_listener_properties.h4
-rw-r--r--chromium/cc/input/input_handler.cc4
-rw-r--r--chromium/cc/input/input_handler.h15
-rw-r--r--chromium/cc/input/scroll_snap_data.cc3
-rw-r--r--chromium/cc/input/scroll_snap_data.h10
-rw-r--r--chromium/cc/input/scrollbar.h5
-rw-r--r--chromium/cc/input/scrollbar_controller.cc194
-rw-r--r--chromium/cc/input/scrollbar_controller.h18
-rw-r--r--chromium/cc/input/snap_fling_controller_unittest.cc7
-rw-r--r--chromium/cc/layers/heads_up_display_layer.cc10
-rw-r--r--chromium/cc/layers/heads_up_display_layer.h5
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.cc44
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.h3
-rw-r--r--chromium/cc/layers/layer.cc30
-rw-r--r--chromium/cc/layers/layer.h25
-rw-r--r--chromium/cc/layers/layer_client.h2
-rw-r--r--chromium/cc/layers/layer_impl.cc10
-rw-r--r--chromium/cc/layers/layer_impl_test_properties.h3
-rw-r--r--chromium/cc/layers/layer_unittest.cc37
-rw-r--r--chromium/cc/layers/painted_overlay_scrollbar_layer.cc4
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer.cc6
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl.cc30
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl.h2
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc6
-rw-r--r--chromium/cc/layers/picture_layer_impl.cc4
-rw-r--r--chromium/cc/layers/picture_layer_impl_unittest.cc18
-rw-r--r--chromium/cc/layers/recording_source_unittest.cc7
-rw-r--r--chromium/cc/layers/render_surface_impl.cc8
-rw-r--r--chromium/cc/layers/render_surface_impl.h2
-rw-r--r--chromium/cc/layers/render_surface_unittest.cc2
-rw-r--r--chromium/cc/layers/scrollbar_layer_impl_base.cc18
-rw-r--r--chromium/cc/layers/scrollbar_layer_impl_base.h6
-rw-r--r--chromium/cc/layers/scrollbar_layer_unittest.cc22
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer.cc8
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer.h2
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer_impl.cc1
-rw-r--r--chromium/cc/layers/surface_layer.cc5
-rw-r--r--chromium/cc/layers/surface_layer.h7
-rw-r--r--chromium/cc/layers/surface_layer_impl.cc82
-rw-r--r--chromium/cc/layers/surface_layer_impl.h8
-rw-r--r--chromium/cc/layers/texture_layer_impl.cc12
-rw-r--r--chromium/cc/layers/texture_layer_impl_unittest.cc3
-rw-r--r--chromium/cc/layers/texture_layer_unittest.cc55
-rw-r--r--chromium/cc/layers/video_frame_provider.h4
-rw-r--r--chromium/cc/layers/video_layer.h2
-rw-r--r--chromium/cc/layers/video_layer_impl.h2
-rw-r--r--chromium/cc/layers/video_layer_impl_unittest.cc8
-rw-r--r--chromium/cc/layers/viewport.cc24
-rw-r--r--chromium/cc/layers/viewport.h8
-rw-r--r--chromium/cc/paint/discardable_image_map_unittest.cc8
-rw-r--r--chromium/cc/paint/draw_image.cc15
-rw-r--r--chromium/cc/paint/draw_image.h19
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.cc77
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.h36
-rw-r--r--chromium/cc/paint/oop_pixeltest.cc32
-rw-r--r--chromium/cc/paint/paint_op_buffer.cc36
-rw-r--r--chromium/cc/paint/paint_op_buffer_fuzzer.cc1
-rw-r--r--chromium/cc/paint/paint_op_buffer_unittest.cc122
-rw-r--r--chromium/cc/paint/paint_op_reader.cc5
-rw-r--r--chromium/cc/paint/record_paint_canvas.cc1
-rw-r--r--chromium/cc/paint/render_surface_filters.cc45
-rw-r--r--chromium/cc/paint/skia_paint_canvas.cc1
-rw-r--r--chromium/cc/paint/transfer_cache_unittest.cc4
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.cc30
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.h1
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.cc5
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.h1
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.cc4
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.h1
-rw-r--r--chromium/cc/raster/playback_image_provider.cc4
-rw-r--r--chromium/cc/raster/playback_image_provider.h2
-rw-r--r--chromium/cc/raster/playback_image_provider_unittest.cc17
-rw-r--r--chromium/cc/raster/raster_buffer_provider.cc9
-rw-r--r--chromium/cc/raster/raster_buffer_provider.h3
-rw-r--r--chromium/cc/raster/raster_source_unittest.cc10
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.cc4
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.h1
-rw-r--r--chromium/cc/resources/cross_thread_shared_bitmap.cc15
-rw-r--r--chromium/cc/resources/cross_thread_shared_bitmap.h25
-rw-r--r--chromium/cc/resources/resource_pool.cc2
-rw-r--r--chromium/cc/scheduler/compositor_frame_reporting_controller.cc4
-rw-r--r--chromium/cc/scheduler/scheduler.cc11
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.cc5
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine_unittest.cc6
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc20
-rw-r--r--chromium/cc/tiles/checker_image_tracker.cc3
-rw-r--r--chromium/cc/tiles/checker_image_tracker.h1
-rw-r--r--chromium/cc/tiles/checker_image_tracker_unittest.cc13
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.cc3
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.h1
-rw-r--r--chromium/cc/tiles/decoded_image_tracker_unittest.cc46
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc107
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.h17
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_perftest.cc44
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_unittest.cc264
-rw-r--r--chromium/cc/tiles/image_controller_unittest.cc2
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache.cc12
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache_unittest.cc24
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.cc41
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.h7
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_perftest.cc3
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_unittest.cc228
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc14
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_utils.cc16
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_utils.h10
-rw-r--r--chromium/cc/tiles/tile_draw_info.cc3
-rw-r--r--chromium/cc/tiles/tile_draw_info.h3
-rw-r--r--chromium/cc/tiles/tile_manager.cc74
-rw-r--r--chromium/cc/tiles/tile_manager.h5
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc20
-rw-r--r--chromium/cc/trees/animation_effect_timings.h25
-rw-r--r--chromium/cc/trees/debug_rect_history.cc14
-rw-r--r--chromium/cc/trees/debug_rect_history.h10
-rw-r--r--chromium/cc/trees/draw_property_utils.cc16
-rw-r--r--chromium/cc/trees/effect_node.cc73
-rw-r--r--chromium/cc/trees/effect_node.h45
-rw-r--r--chromium/cc/trees/latency_info_swap_promise.cc4
-rw-r--r--chromium/cc/trees/latency_info_swap_promise.h2
-rw-r--r--chromium/cc/trees/layer_tree_host.cc90
-rw-r--r--chromium/cc/trees/layer_tree_host.h41
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h3
-rw-r--r--chromium/cc/trees/layer_tree_host_common.cc54
-rw-r--r--chromium/cc/trees/layer_tree_host_common_unittest.cc40
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc277
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h92
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc295
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc5
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc22
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc228
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc102
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_readback.cc198
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc44
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc74
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc200
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc63
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc6
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc19
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc4
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc314
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_masks.cc20
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc120
-rw-r--r--chromium/cc/trees/layer_tree_impl.h17
-rw-r--r--chromium/cc/trees/layer_tree_impl_unittest.cc88
-rw-r--r--chromium/cc/trees/layer_tree_mutator.cc4
-rw-r--r--chromium/cc/trees/layer_tree_mutator.h5
-rw-r--r--chromium/cc/trees/layer_tree_settings.h5
-rw-r--r--chromium/cc/trees/mutator_host.h44
-rw-r--r--chromium/cc/trees/mutator_host_client.h8
-rw-r--r--chromium/cc/trees/occlusion_tracker.cc3
-rw-r--r--chromium/cc/trees/occlusion_tracker_unittest.cc25
-rw-r--r--chromium/cc/trees/paint_holding_commit_trigger.h28
-rw-r--r--chromium/cc/trees/presentation_time_callback_buffer.cc117
-rw-r--r--chromium/cc/trees/presentation_time_callback_buffer.h132
-rw-r--r--chromium/cc/trees/presentation_time_callback_buffer_unittest.cc159
-rw-r--r--chromium/cc/trees/property_tree.cc48
-rw-r--r--chromium/cc/trees/property_tree.h4
-rw-r--r--chromium/cc/trees/property_tree_builder.cc196
-rw-r--r--chromium/cc/trees/property_tree_unittest.cc13
-rw-r--r--chromium/cc/trees/proxy.h10
-rw-r--r--chromium/cc/trees/proxy_impl.cc11
-rw-r--r--chromium/cc/trees/proxy_impl.h4
-rw-r--r--chromium/cc/trees/proxy_main.cc34
-rw-r--r--chromium/cc/trees/proxy_main.h11
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc19
-rw-r--r--chromium/cc/trees/single_thread_proxy.h7
-rw-r--r--chromium/cc/trees/swap_promise.h9
-rw-r--r--chromium/cc/trees/swap_promise_manager.cc11
-rw-r--r--chromium/cc/trees/swap_promise_manager_unittest.cc4
-rw-r--r--chromium/cc/trees/target_property.h3
-rw-r--r--chromium/cc/trees/transform_node.cc6
-rw-r--r--chromium/cc/trees/transform_node.h9
-rw-r--r--chromium/cc/trees/tree_synchronizer.cc25
-rw-r--r--chromium/cc/trees/ukm_manager.cc7
-rw-r--r--chromium/cc/trees/ukm_manager.h2
-rw-r--r--chromium/cc/trees/ukm_manager_unittest.cc16
203 files changed, 4833 insertions, 2972 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn
index 0878b2fdfea..b0fde3505e6 100644
--- a/chromium/cc/BUILD.gn
+++ b/chromium/cc/BUILD.gn
@@ -269,6 +269,7 @@ cc_component("cc") {
"tiles/tiling_set_raster_queue_all.h",
"tiles/tiling_set_raster_queue_required.cc",
"tiles/tiling_set_raster_queue_required.h",
+ "trees/animation_effect_timings.h",
"trees/animation_options.h",
"trees/clip_expander.cc",
"trees/clip_expander.h",
@@ -318,6 +319,9 @@ cc_component("cc") {
"trees/occlusion.h",
"trees/occlusion_tracker.cc",
"trees/occlusion_tracker.h",
+ "trees/paint_holding_commit_trigger.h",
+ "trees/presentation_time_callback_buffer.cc",
+ "trees/presentation_time_callback_buffer.h",
"trees/property_animation_state.cc",
"trees/property_animation_state.h",
"trees/property_tree.cc",
@@ -696,6 +700,7 @@ cc_test("cc_unittests") {
"trees/layer_tree_impl_unittest.cc",
"trees/occlusion_tracker_unittest.cc",
"trees/occlusion_unittest.cc",
+ "trees/presentation_time_callback_buffer_unittest.cc",
"trees/property_tree_unittest.cc",
"trees/swap_promise_manager_unittest.cc",
"trees/tree_synchronizer_unittest.cc",
diff --git a/chromium/cc/DEPS b/chromium/cc/DEPS
index 6f352e8c510..0186be319b6 100644
--- a/chromium/cc/DEPS
+++ b/chromium/cc/DEPS
@@ -33,6 +33,7 @@ include_rules = [
"+third_party/libyuv",
"+third_party/skia/include",
"+third_party/skia/src/core/SkRemoteGlyphCache.h",
+ "+ui/events/types",
"+ui/latency",
"+ui/gfx",
"+ui/gl",
diff --git a/chromium/cc/animation/DEPS b/chromium/cc/animation/DEPS
index 80d05f0a872..bc229ac9da9 100644
--- a/chromium/cc/animation/DEPS
+++ b/chromium/cc/animation/DEPS
@@ -7,6 +7,7 @@ include_rules = [
"+cc/output/filter_operations.h",
"+cc/test",
"+cc/trees/animation_options.h",
+ "+cc/trees/animation_effect_timings.h",
"+cc/trees/element_id.h",
"+cc/trees/mutator_host.h",
"+cc/trees/mutator_host_client.h",
diff --git a/chromium/cc/animation/animation.cc b/chromium/cc/animation/animation.cc
index 3974409adfd..2e4c5eb69ac 100644
--- a/chromium/cc/animation/animation.cc
+++ b/chromium/cc/animation/animation.cc
@@ -41,16 +41,6 @@ scoped_refptr<Animation> Animation::CreateImplInstance() const {
return Animation::Create(id());
}
-ElementId Animation::element_id_of_keyframe_effect(
- KeyframeEffectId keyframe_effect_id) const {
- DCHECK(GetKeyframeEffectById(keyframe_effect_id));
- return GetKeyframeEffectById(keyframe_effect_id)->element_id();
-}
-
-bool Animation::IsElementAttached(ElementId id) const {
- return base::ContainsKey(element_to_keyframe_effect_id_map_, id);
-}
-
void Animation::SetAnimationHost(AnimationHost* animation_host) {
animation_host_ = animation_host;
}
diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h
index feb33026e2a..14a988505a9 100644
--- a/chromium/cc/animation/animation.h
+++ b/chromium/cc/animation/animation.h
@@ -47,9 +47,6 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
int id() const { return id_; }
typedef size_t KeyframeEffectId;
- ElementId element_id_of_keyframe_effect(
- KeyframeEffectId keyframe_effect_id) const;
- bool IsElementAttached(ElementId id) const;
// Parent AnimationHost. Animation can be detached from AnimationTimeline.
AnimationHost* animation_host() { return animation_host_; }
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
index cbd6d8e5ad8..ccb6a42ba3c 100644
--- a/chromium/cc/animation/animation_host.cc
+++ b/chromium/cc/animation/animation_host.cc
@@ -47,6 +47,19 @@ AnimationWorkletMutationState ToAnimationWorkletMutationState(
}
}
+bool TickAnimationsIf(AnimationHost::AnimationsList animations,
+ base::TimeTicks monotonic_time,
+ bool (*predicate)(const Animation&)) {
+ bool did_tick = false;
+ for (auto& it : animations) {
+ if (predicate(*it)) {
+ it->Tick(monotonic_time);
+ did_tick = true;
+ }
+ }
+ return did_tick;
+}
+
} // namespace
std::unique_ptr<AnimationHost> AnimationHost::CreateMainInstance() {
@@ -129,25 +142,35 @@ void AnimationHost::RemoveAnimationTimeline(
SetNeedsPushProperties();
}
+void AnimationHost::UpdateRegisteredElementIds(ElementListType changed_list) {
+ for (auto map_entry : element_to_animations_map_) {
+ if (mutator_host_client()->IsElementInPropertyTrees(map_entry.first,
+ changed_list))
+ map_entry.second->ElementIdRegistered(map_entry.first, changed_list);
+ else
+ map_entry.second->ElementIdUnregistered(map_entry.first, changed_list);
+ }
+}
+
void AnimationHost::InitClientAnimationState() {
for (auto map_entry : element_to_animations_map_)
map_entry.second->InitClientAnimationState();
}
-void AnimationHost::RegisterElement(ElementId element_id,
- ElementListType list_type) {
+void AnimationHost::RegisterElementId(ElementId element_id,
+ ElementListType list_type) {
scoped_refptr<ElementAnimations> element_animations =
GetElementAnimationsForElementId(element_id);
if (element_animations)
- element_animations->ElementRegistered(element_id, list_type);
+ element_animations->ElementIdRegistered(element_id, list_type);
}
-void AnimationHost::UnregisterElement(ElementId element_id,
- ElementListType list_type) {
+void AnimationHost::UnregisterElementId(ElementId element_id,
+ ElementListType list_type) {
scoped_refptr<ElementAnimations> element_animations =
GetElementAnimationsForElementId(element_id);
if (element_animations)
- element_animations->ElementUnregistered(element_id, list_type);
+ element_animations->ElementIdUnregistered(element_id, list_type);
}
void AnimationHost::RegisterKeyframeEffectForElement(
@@ -348,31 +371,23 @@ void AnimationHost::TickMutator(base::TimeTicks monotonic_time,
return;
}
-bool AnimationHost::ActivateAnimations() {
+bool AnimationHost::ActivateAnimations(MutatorEvents* mutator_events) {
if (!NeedsTickAnimations())
return false;
+ auto* animation_events = static_cast<AnimationEvents*>(mutator_events);
+
TRACE_EVENT0("cc", "AnimationHost::ActivateAnimations");
AnimationsList ticking_animations_copy = ticking_animations_;
- for (auto& it : ticking_animations_copy)
+ for (auto& it : ticking_animations_copy) {
it->ActivateKeyframeEffects();
+ // Finish animations which no longer affect active or pending elements.
+ it->UpdateState(false, animation_events);
+ }
return true;
}
-bool TickAnimationsIf(AnimationHost::AnimationsList animations,
- base::TimeTicks monotonic_time,
- bool (*predicate)(const Animation&)) {
- bool did_tick = false;
- for (auto& it : animations) {
- if (predicate(*it)) {
- it->Tick(monotonic_time);
- did_tick = true;
- }
- }
- return did_tick;
-}
-
bool AnimationHost::TickAnimations(base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
bool is_active_tree) {
@@ -522,6 +537,15 @@ bool AnimationHost::IsAnimatingFilterProperty(ElementId element_id,
: false;
}
+bool AnimationHost::IsAnimatingBackdropFilterProperty(
+ ElementId element_id,
+ ElementListType list_type) const {
+ auto element_animations = GetElementAnimationsForElementId(element_id);
+ return element_animations ? element_animations->IsCurrentlyAnimatingProperty(
+ TargetProperty::BACKDROP_FILTER, list_type)
+ : false;
+}
+
bool AnimationHost::IsAnimatingOpacityProperty(
ElementId element_id,
ElementListType list_type) const {
@@ -552,6 +576,16 @@ bool AnimationHost::HasPotentiallyRunningFilterAnimation(
: false;
}
+bool AnimationHost::HasPotentiallyRunningBackdropFilterAnimation(
+ ElementId element_id,
+ ElementListType list_type) const {
+ auto element_animations = GetElementAnimationsForElementId(element_id);
+ return element_animations
+ ? element_animations->IsPotentiallyAnimatingProperty(
+ TargetProperty::BACKDROP_FILTER, list_type)
+ : false;
+}
+
bool AnimationHost::HasPotentiallyRunningOpacityAnimation(
ElementId element_id,
ElementListType list_type) const {
@@ -582,15 +616,6 @@ bool AnimationHost::HasAnyAnimationTargetingProperty(
return element_animations->HasAnyAnimationTargetingProperty(property);
}
-bool AnimationHost::HasOnlyTranslationTransforms(
- 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(
ElementId element_id) const {
auto element_animations = GetElementAnimationsForElementId(element_id);
@@ -599,18 +624,17 @@ bool AnimationHost::AnimationsPreserveAxisAlignment(
: true;
}
-float AnimationHost::MaximumTargetScale(ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations ? element_animations->MaximumTargetScale(list_type)
- : kNotScaled;
-}
-
-float AnimationHost::AnimationStartScale(ElementId element_id,
- ElementListType list_type) const {
- auto element_animations = GetElementAnimationsForElementId(element_id);
- return element_animations ? element_animations->AnimationStartScale(list_type)
- : kNotScaled;
+void AnimationHost::GetAnimationScales(ElementId element_id,
+ ElementListType list_type,
+ float* maximum_scale,
+ float* starting_scale) const {
+ if (auto element_animations = GetElementAnimationsForElementId(element_id)) {
+ element_animations->GetAnimationScales(list_type, maximum_scale,
+ starting_scale);
+ return;
+ }
+ *maximum_scale = kNotScaled;
+ *starting_scale = kNotScaled;
}
bool AnimationHost::IsElementAnimating(ElementId element_id) const {
diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h
index b5bff9ac843..45fca14a5b7 100644
--- a/chromium/cc/animation/animation_host.h
+++ b/chromium/cc/animation/animation_host.h
@@ -90,12 +90,16 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
bool supports_impl_scrolling) const override;
void ClearMutators() override;
+ // Processes the current |element_to_animations_map_|, registering animations
+ // which can now be animated and unregistering those that can't based on the
+ // elements in the |changed_list|.
+ void UpdateRegisteredElementIds(ElementListType changed_list) override;
void InitClientAnimationState() override;
- void RegisterElement(ElementId element_id,
- ElementListType list_type) override;
- void UnregisterElement(ElementId element_id,
+ void RegisterElementId(ElementId element_id,
ElementListType list_type) override;
+ void UnregisterElementId(ElementId element_id,
+ ElementListType list_type) override;
void SetMutatorHostClient(MutatorHostClient* client) override;
@@ -107,7 +111,7 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
void SetScrollAnimationDurationForTesting(base::TimeDelta duration) override;
bool NeedsTickAnimations() const override;
- bool ActivateAnimations() override;
+ bool ActivateAnimations(MutatorEvents* events) override;
bool TickAnimations(base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
bool is_active_tree) override;
@@ -125,6 +129,9 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
bool IsAnimatingFilterProperty(ElementId element_id,
ElementListType list_type) const override;
+ bool IsAnimatingBackdropFilterProperty(
+ ElementId element_id,
+ ElementListType list_type) const override;
bool IsAnimatingOpacityProperty(ElementId element_id,
ElementListType list_type) const override;
bool IsAnimatingTransformProperty(ElementId element_id,
@@ -133,6 +140,9 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
bool HasPotentiallyRunningFilterAnimation(
ElementId element_id,
ElementListType list_type) const override;
+ bool HasPotentiallyRunningBackdropFilterAnimation(
+ ElementId element_id,
+ ElementListType list_type) const override;
bool HasPotentiallyRunningOpacityAnimation(
ElementId element_id,
ElementListType list_type) const override;
@@ -144,14 +154,12 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
ElementId element_id,
TargetProperty::Type property) const override;
- bool HasOnlyTranslationTransforms(ElementId element_id,
- ElementListType list_type) const override;
bool AnimationsPreserveAxisAlignment(ElementId element_id) const override;
- float MaximumTargetScale(ElementId element_id,
- ElementListType list_type) const override;
- float AnimationStartScale(ElementId element_id,
- ElementListType list_type) const override;
+ void GetAnimationScales(ElementId element_id,
+ ElementListType list_type,
+ float* maximum_scale,
+ float* starting_scale) const override;
bool IsElementAnimating(ElementId element_id) const override;
bool HasTickingKeyframeModelForTesting(ElementId element_id) const override;
diff --git a/chromium/cc/animation/animation_host_unittest.cc b/chromium/cc/animation/animation_host_unittest.cc
index f2f4bd650ed..9290174cded 100644
--- a/chromium/cc/animation/animation_host_unittest.cc
+++ b/chromium/cc/animation/animation_host_unittest.cc
@@ -32,12 +32,12 @@ class AnimationHostTest : public AnimationTimelinesTest {
~AnimationHostTest() override = default;
void AttachWorkletAnimation() {
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
+ client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
worklet_animation_ = WorkletAnimation::Create(
- worklet_animation_id_, "test_name", 1, nullptr, nullptr);
+ worklet_animation_id_, "test_name", 1, nullptr, nullptr, nullptr);
int cc_id = worklet_animation_->id();
worklet_animation_->AttachElement(element_id_);
host_->AddAnimationTimeline(timeline_);
@@ -121,8 +121,8 @@ TEST_F(AnimationHostTest, ImplOnlyTimeline) {
}
TEST_F(AnimationHostTest, ImplOnlyScrollAnimationUpdateTargetIfDetached) {
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
gfx::ScrollOffset target_offset(0., 2.);
gfx::ScrollOffset current_offset(0., 1.);
@@ -173,7 +173,7 @@ TEST_F(AnimationHostTest, FastLayerTreeMutatorUpdateTakesEffectInSameFrame) {
// Push the opacity animation to the impl thread.
host_->PushPropertiesTo(host_impl_);
- host_impl_->ActivateAnimations();
+ host_impl_->ActivateAnimations(nullptr);
// Ticking host should cause layer tree mutator to update output state which
// should take effect in the same animation frame.
@@ -207,7 +207,7 @@ TEST_F(AnimationHostTest, LayerTreeMutatorsIsMutatedWithCorrectInputState) {
start_opacity, end_opacity, true);
host_->PushPropertiesTo(host_impl_);
- host_impl_->ActivateAnimations();
+ host_impl_->ActivateAnimations(nullptr);
EXPECT_CALL(*mock_mutator, MutateRef(_));
@@ -232,7 +232,7 @@ TEST_F(AnimationHostTest, LayerTreeMutatorsIsMutatedOnlyWhenInputChanges) {
start_opacity, end_opacity, true);
host_->PushPropertiesTo(host_impl_);
- host_impl_->ActivateAnimations();
+ host_impl_->ActivateAnimations(nullptr);
EXPECT_CALL(*mock_mutator, MutateRef(_)).Times(1);
@@ -306,9 +306,9 @@ TEST_F(AnimationHostTest, LayerTreeMutatorUpdateReflectsScrollAnimations) {
int animation_id2 = 12;
WorkletAnimationId worklet_animation_id{333, 22};
- client_.RegisterElement(element_id, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id, ElementListType::PENDING);
+ client_impl_.RegisterElementId(element_id, ElementListType::ACTIVE);
host_impl_->AddAnimationTimeline(timeline_);
PropertyTrees property_trees;
@@ -340,7 +340,7 @@ TEST_F(AnimationHostTest, LayerTreeMutatorUpdateReflectsScrollAnimations) {
// Create a worklet animation that is bound to the scroll timeline.
scoped_refptr<WorkletAnimation> worklet_animation(
new WorkletAnimation(animation_id2, worklet_animation_id, "test_name", 1,
- std::move(scroll_timeline), nullptr, true));
+ std::move(scroll_timeline), nullptr, nullptr, true));
worklet_animation->AttachElement(element_id);
timeline_->AttachAnimation(worklet_animation);
diff --git a/chromium/cc/animation/animation_unittest.cc b/chromium/cc/animation/animation_unittest.cc
index 1ffadf9a9cf..9ae34304bf0 100644
--- a/chromium/cc/animation/animation_unittest.cc
+++ b/chromium/cc/animation/animation_unittest.cc
@@ -55,8 +55,9 @@ TEST_F(AnimationTest, AttachDetachLayerIfTimelineAttached) {
timeline_->AttachAnimation(animation_);
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id_));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id_));
EXPECT_TRUE(timeline_->needs_push_properties());
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
->needs_push_properties());
@@ -70,8 +71,8 @@ TEST_F(AnimationTest, AttachDetachLayerIfTimelineAttached) {
EXPECT_TRUE(animation_impl_);
EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id_));
- EXPECT_FALSE(
- animation_impl_->element_id_of_keyframe_effect(keyframe_effect_id_));
+ EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)
+ ->element_id());
EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
->needs_push_properties());
EXPECT_FALSE(timeline_->needs_push_properties());
@@ -80,8 +81,9 @@ TEST_F(AnimationTest, AttachDetachLayerIfTimelineAttached) {
EXPECT_EQ(animation_->GetKeyframeEffectById(keyframe_effect_id_),
GetKeyframeEffectForElementId(element_id_));
EXPECT_TRUE(animation_->element_animations(keyframe_effect_id_));
- EXPECT_EQ(animation_->element_id_of_keyframe_effect(keyframe_effect_id_),
- element_id_);
+ EXPECT_EQ(
+ animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
+ element_id_);
CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
host_->PushPropertiesTo(host_impl_);
@@ -89,28 +91,31 @@ TEST_F(AnimationTest, AttachDetachLayerIfTimelineAttached) {
EXPECT_EQ(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_),
GetImplKeyframeEffectForLayerId(element_id_));
EXPECT_TRUE(animation_impl_->element_animations(keyframe_effect_id_));
- EXPECT_EQ(animation_impl_->element_id_of_keyframe_effect(keyframe_effect_id_),
- element_id_);
+ EXPECT_EQ(
+ animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)->element_id(),
+ element_id_);
CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
animation_->DetachElement();
EXPECT_FALSE(GetKeyframeEffectForElementId(element_id_));
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id_));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id_));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
host_->PushPropertiesTo(host_impl_);
EXPECT_FALSE(GetImplKeyframeEffectForLayerId(element_id_));
EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id_));
- EXPECT_FALSE(
- animation_impl_->element_id_of_keyframe_effect(keyframe_effect_id_));
+ EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id_)
+ ->element_id());
CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
timeline_->DetachAnimation(animation_);
EXPECT_FALSE(animation_->animation_timeline());
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id_));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id_));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id_)->element_id());
EXPECT_TRUE(timeline_->needs_push_properties());
EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id_)
->needs_push_properties());
@@ -168,9 +173,9 @@ TEST_F(AnimationTest, AttachDetachTimelineIfLayerAttached) {
}
TEST_F(AnimationTest, PropertiesMutate) {
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
+ client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
host_->AddAnimationTimeline(timeline_);
@@ -194,6 +199,9 @@ TEST_F(AnimationTest, PropertiesMutate) {
const int transform_x = 10;
const int transform_y = 20;
+ const float start_invert = .8f;
+ const float end_invert = .6f;
+
const double duration = 1.;
AddOpacityTransitionToAnimation(animation_.get(), duration, start_opacity,
@@ -203,6 +211,8 @@ TEST_F(AnimationTest, PropertiesMutate) {
transform_y, keyframe_effect_id_);
AddAnimatedFilterToAnimation(animation_.get(), duration, start_brightness,
end_brightness, keyframe_effect_id_);
+ AddAnimatedBackdropFilterToAnimation(animation_.get(), duration, start_invert,
+ end_invert, keyframe_effect_id_);
CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
host_->PushPropertiesTo(host_impl_);
@@ -214,6 +224,8 @@ TEST_F(AnimationTest, PropertiesMutate) {
TargetProperty::TRANSFORM));
EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE,
TargetProperty::FILTER));
+ EXPECT_FALSE(client_.IsPropertyMutated(element_id_, ElementListType::ACTIVE,
+ TargetProperty::BACKDROP_FILTER));
EXPECT_FALSE(client_impl_.IsPropertyMutated(
element_id_, ElementListType::ACTIVE, TargetProperty::OPACITY));
@@ -221,16 +233,18 @@ TEST_F(AnimationTest, PropertiesMutate) {
element_id_, ElementListType::ACTIVE, TargetProperty::TRANSFORM));
EXPECT_FALSE(client_impl_.IsPropertyMutated(
element_id_, ElementListType::ACTIVE, TargetProperty::FILTER));
+ EXPECT_FALSE(client_impl_.IsPropertyMutated(
+ element_id_, ElementListType::ACTIVE, TargetProperty::BACKDROP_FILTER));
- host_impl_->ActivateAnimations();
+ host_impl_->ActivateAnimations(nullptr);
base::TimeTicks time;
time += base::TimeDelta::FromSecondsD(0.1);
- TickAnimationsTransferEvents(time, 3u);
+ TickAnimationsTransferEvents(time, 4u);
CheckKeyframeEffectAndTimelineNeedsPushProperties(false, keyframe_effect_id_);
time += base::TimeDelta::FromSecondsD(duration);
- TickAnimationsTransferEvents(time, 3u);
+ TickAnimationsTransferEvents(time, 4u);
CheckKeyframeEffectAndTimelineNeedsPushProperties(true, keyframe_effect_id_);
client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE,
@@ -239,6 +253,8 @@ TEST_F(AnimationTest, PropertiesMutate) {
transform_x, transform_y);
client_.ExpectFilterPropertyMutated(element_id_, ElementListType::ACTIVE,
end_brightness);
+ client_.ExpectBackdropFilterPropertyMutated(
+ element_id_, ElementListType::ACTIVE, end_invert);
client_impl_.ExpectOpacityPropertyMutated(
element_id_, ElementListType::ACTIVE, end_opacity);
@@ -246,6 +262,8 @@ TEST_F(AnimationTest, PropertiesMutate) {
element_id_, ElementListType::ACTIVE, transform_x, transform_y);
client_impl_.ExpectFilterPropertyMutated(element_id_, ElementListType::ACTIVE,
end_brightness);
+ client_impl_.ExpectBackdropFilterPropertyMutated(
+ element_id_, ElementListType::ACTIVE, end_invert);
client_impl_.ExpectOpacityPropertyMutated(
element_id_, ElementListType::PENDING, end_opacity);
@@ -253,15 +271,17 @@ TEST_F(AnimationTest, PropertiesMutate) {
element_id_, ElementListType::PENDING, transform_x, transform_y);
client_impl_.ExpectFilterPropertyMutated(
element_id_, ElementListType::PENDING, end_brightness);
+ client_impl_.ExpectBackdropFilterPropertyMutated(
+ element_id_, ElementListType::PENDING, end_invert);
}
TEST_F(AnimationTest, AttachTwoAnimationsToOneLayer) {
TestAnimationDelegate delegate1;
TestAnimationDelegate delegate2;
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
+ client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
scoped_refptr<Animation> animation1 = Animation::Create(100);
scoped_refptr<Animation> animation2 = Animation::Create(200);
@@ -304,7 +324,7 @@ TEST_F(AnimationTest, AttachTwoAnimationsToOneLayer) {
transform_y, keyframe_effect_id2);
host_->PushPropertiesTo(host_impl_);
- host_impl_->ActivateAnimations();
+ host_impl_->ActivateAnimations(nullptr);
EXPECT_FALSE(delegate1.started());
EXPECT_FALSE(delegate1.finished());
@@ -355,9 +375,9 @@ TEST_F(AnimationTest, AttachTwoAnimationsToOneLayer) {
}
TEST_F(AnimationTest, AddRemoveAnimationToNonAttachedAnimation) {
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
+ client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
animation_->AddKeyframeEffect(
std::make_unique<KeyframeEffect>(keyframe_effect_id_));
@@ -412,7 +432,7 @@ TEST_F(AnimationTest, AddRemoveAnimationToNonAttachedAnimation) {
EXPECT_FALSE(client_impl_.IsPropertyMutated(
element_id_, ElementListType::ACTIVE, TargetProperty::FILTER));
- host_impl_->ActivateAnimations();
+ host_impl_->ActivateAnimations(nullptr);
base::TimeTicks time;
time += base::TimeDelta::FromSecondsD(0.1);
@@ -435,7 +455,7 @@ TEST_F(AnimationTest, AddRemoveAnimationToNonAttachedAnimation) {
}
TEST_F(AnimationTest, AddRemoveAnimationCausesSetNeedsCommit) {
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
host_->AddAnimationTimeline(timeline_);
animation_->AddKeyframeEffect(
std::make_unique<KeyframeEffect>(keyframe_effect_id_));
@@ -613,8 +633,10 @@ TEST_F(AnimationTest,
timeline_->AttachAnimation(animation_);
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id1));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id2));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
EXPECT_TRUE(timeline_->needs_push_properties());
EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
->needs_push_properties());
@@ -630,14 +652,16 @@ TEST_F(AnimationTest,
animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id1);
EXPECT_TRUE(animation_->element_animations(keyframe_effect_id1));
- EXPECT_EQ(animation_->element_id_of_keyframe_effect(keyframe_effect_id1),
- element_id_);
+ EXPECT_EQ(
+ animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id(),
+ element_id_);
EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
->needs_push_properties());
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
- EXPECT_NE(animation_->element_id_of_keyframe_effect(keyframe_effect_id2),
- element_id_);
+ EXPECT_NE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id(),
+ element_id_);
EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
->needs_push_properties());
@@ -650,8 +674,9 @@ TEST_F(AnimationTest,
animation_->AttachElementForKeyframeEffect(element_id_, keyframe_effect_id2);
EXPECT_TRUE(animation_->element_animations(keyframe_effect_id2));
- EXPECT_EQ(animation_->element_id_of_keyframe_effect(keyframe_effect_id2),
- element_id_);
+ EXPECT_EQ(
+ animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id(),
+ element_id_);
EXPECT_TRUE(animation_->GetKeyframeEffectById(keyframe_effect_id2)
->needs_push_properties());
@@ -668,20 +693,24 @@ TEST_F(AnimationTest,
animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)));
EXPECT_TRUE(animation_impl_->element_animations(keyframe_effect_id1));
- EXPECT_EQ(animation_impl_->element_id_of_keyframe_effect(keyframe_effect_id1),
- element_id_);
+ EXPECT_EQ(
+ animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)->element_id(),
+ element_id_);
EXPECT_TRUE(animation_impl_->element_animations(keyframe_effect_id2));
- EXPECT_EQ(animation_impl_->element_id_of_keyframe_effect(keyframe_effect_id2),
- element_id_);
+ EXPECT_EQ(
+ animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)->element_id(),
+ element_id_);
animation_->DetachElement();
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id1));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
EXPECT_FALSE(element_animations->HasKeyframeEffectForTesting(
animation_->GetKeyframeEffectById(keyframe_effect_id1)));
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id2));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
EXPECT_FALSE(element_animations->HasKeyframeEffectForTesting(
animation_->GetKeyframeEffectById(keyframe_effect_id2)));
@@ -693,13 +722,13 @@ TEST_F(AnimationTest,
host_->PushPropertiesTo(host_impl_);
EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id1));
- EXPECT_FALSE(
- animation_impl_->element_id_of_keyframe_effect(keyframe_effect_id1));
+ EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)
+ ->element_id());
EXPECT_FALSE(element_animations_impl->HasKeyframeEffectForTesting(
animation_impl_->GetKeyframeEffectById(keyframe_effect_id1)));
EXPECT_FALSE(animation_impl_->element_animations(keyframe_effect_id2));
- EXPECT_FALSE(
- animation_impl_->element_id_of_keyframe_effect(keyframe_effect_id2));
+ EXPECT_FALSE(animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)
+ ->element_id());
EXPECT_FALSE(element_animations_impl->HasKeyframeEffectForTesting(
animation_impl_->GetKeyframeEffectById(keyframe_effect_id2)));
@@ -707,9 +736,11 @@ TEST_F(AnimationTest,
EXPECT_FALSE(animation_->animation_timeline());
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id1));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id2));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
EXPECT_TRUE(timeline_->needs_push_properties());
EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
@@ -739,8 +770,10 @@ TEST_F(AnimationTest,
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id1));
EXPECT_FALSE(animation_->element_animations(keyframe_effect_id2));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id1));
- EXPECT_FALSE(animation_->element_id_of_keyframe_effect(keyframe_effect_id2));
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id1)->element_id());
+ EXPECT_FALSE(
+ animation_->GetKeyframeEffectById(keyframe_effect_id2)->element_id());
EXPECT_TRUE(timeline_->needs_push_properties());
EXPECT_FALSE(animation_->GetKeyframeEffectById(keyframe_effect_id1)
->needs_push_properties());
@@ -823,9 +856,9 @@ TEST_F(AnimationTest,
TEST_F(AnimationTest, TickingAnimationsFromTwoKeyframeEffects) {
TestAnimationDelegate delegate1;
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
+ client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
KeyframeEffectId keyframe_effect_id1 = animation_->NextKeyframeEffectId();
@@ -865,7 +898,7 @@ TEST_F(AnimationTest, TickingAnimationsFromTwoKeyframeEffects) {
AddAnimatedTransformToAnimation(animation_.get(), duration, transform_x,
transform_y, keyframe_effect_id2);
host_->PushPropertiesTo(host_impl_);
- host_impl_->ActivateAnimations();
+ host_impl_->ActivateAnimations(nullptr);
EXPECT_FALSE(delegate1.started());
EXPECT_FALSE(delegate1.finished());
@@ -926,9 +959,18 @@ TEST_F(AnimationTest, TickingState) {
KeyframeEffect* keyframe_effect =
animation_->GetKeyframeEffectById(keyframe_effect_id);
EXPECT_FALSE(keyframe_effect->is_ticking());
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
EXPECT_TRUE(keyframe_effect->is_ticking());
- client_.UnregisterElement(element_id_, ElementListType::ACTIVE);
+
+ client_.UnregisterElementId(element_id_, ElementListType::ACTIVE);
+ // The keyframe keeps ticking until the next call to UpdateState where it can
+ // generate a finished event.
+ EXPECT_TRUE(keyframe_effect->is_ticking());
+
+ // The next call to UpdateState should remove the animation from ticking. We
+ // could also assert that the finish event was generated if we also track the
+ // state in the KeyframeModel correctly.
+ host_->UpdateAnimationState(true, nullptr);
EXPECT_FALSE(keyframe_effect->is_ticking());
}
diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc
index 797464ee5e8..12b9f0ffd16 100644
--- a/chromium/cc/animation/element_animations.cc
+++ b/chromium/cc/animation/element_animations.cc
@@ -65,11 +65,11 @@ void ElementAnimations::InitAffectedElementTypes() {
DCHECK(animation_host_);
DCHECK(animation_host_->mutator_host_client());
- if (animation_host_->mutator_host_client()->IsElementInList(
+ if (animation_host_->mutator_host_client()->IsElementInPropertyTrees(
element_id_, ElementListType::ACTIVE)) {
set_has_element_in_active_list(true);
}
- if (animation_host_->mutator_host_client()->IsElementInList(
+ if (animation_host_->mutator_host_client()->IsElementInPropertyTrees(
element_id_, ElementListType::PENDING)) {
set_has_element_in_pending_list(true);
}
@@ -80,6 +80,7 @@ TargetProperties ElementAnimations::GetPropertiesMaskForAnimationState() {
properties[TargetProperty::TRANSFORM] = true;
properties[TargetProperty::OPACITY] = true;
properties[TargetProperty::FILTER] = true;
+ properties[TargetProperty::BACKDROP_FILTER] = true;
return properties;
}
@@ -111,8 +112,8 @@ void ElementAnimations::ClearAffectedElementTypes(
RemoveKeyframeEffectsFromTicking();
}
-void ElementAnimations::ElementRegistered(ElementId element_id,
- ElementListType list_type) {
+void ElementAnimations::ElementIdRegistered(ElementId element_id,
+ ElementListType list_type) {
DCHECK_EQ(element_id_, element_id);
bool had_element_in_any_list = has_element_in_any_list();
@@ -126,16 +127,13 @@ void ElementAnimations::ElementRegistered(ElementId element_id,
UpdateKeyframeEffectsTickingState();
}
-void ElementAnimations::ElementUnregistered(ElementId element_id,
- ElementListType list_type) {
+void ElementAnimations::ElementIdUnregistered(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);
-
- if (!has_element_in_any_list())
- RemoveKeyframeEffectsFromTicking();
}
void ElementAnimations::AddKeyframeEffect(KeyframeEffect* keyframe_effect) {
@@ -212,15 +210,6 @@ void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) {
UpdateClientAnimationState();
}
-bool ElementAnimations::HasOnlyTranslationTransforms(
- ElementListType list_type) const {
- for (auto& keyframe_effect : keyframe_effects_list_) {
- if (!keyframe_effect.HasOnlyTranslationTransforms(list_type))
- return false;
- }
- return true;
-}
-
bool ElementAnimations::AnimationsPreserveAxisAlignment() const {
for (auto& keyframe_effect : keyframe_effects_list_) {
if (!keyframe_effect.AnimationsPreserveAxisAlignment())
@@ -229,40 +218,25 @@ bool ElementAnimations::AnimationsPreserveAxisAlignment() const {
return true;
}
-float ElementAnimations::AnimationStartScale(ElementListType list_type) const {
- float start_scale = kNotScaled;
-
- for (auto& keyframe_effect : keyframe_effects_list_) {
- if (keyframe_effect.HasOnlyTranslationTransforms(list_type))
- continue;
- float keyframe_effect_start_scale = kNotScaled;
- bool success = keyframe_effect.AnimationStartScale(
- list_type, &keyframe_effect_start_scale);
- if (!success)
- return kNotScaled;
- // Union: a maximum.
- start_scale = std::max(start_scale, keyframe_effect_start_scale);
- }
-
- return start_scale;
-}
-
-float ElementAnimations::MaximumTargetScale(ElementListType list_type) const {
- float max_scale = kNotScaled;
-
+void ElementAnimations::GetAnimationScales(ElementListType list_type,
+ float* maximum_scale,
+ float* starting_scale) const {
+ *maximum_scale = kNotScaled;
+ *starting_scale = kNotScaled;
for (auto& keyframe_effect : keyframe_effects_list_) {
- if (keyframe_effect.HasOnlyTranslationTransforms(list_type))
- continue;
- float keyframe_effect_max_scale = kNotScaled;
- bool success = keyframe_effect.MaximumTargetScale(
- list_type, &keyframe_effect_max_scale);
- if (!success)
- return kNotScaled;
- // Union: a maximum.
- max_scale = std::max(max_scale, keyframe_effect_max_scale);
+ float keyframe_effect_maximum_scale = kNotScaled;
+ float keyframe_effect_starting_scale = kNotScaled;
+ bool success = keyframe_effect.GetAnimationScales(
+ list_type, &keyframe_effect_maximum_scale,
+ &keyframe_effect_starting_scale);
+ if (!success) {
+ *maximum_scale = kNotScaled;
+ *starting_scale = kNotScaled;
+ return;
+ }
+ *maximum_scale = std::max(*maximum_scale, keyframe_effect_maximum_scale);
+ *starting_scale = std::max(*starting_scale, keyframe_effect_starting_scale);
}
-
- return max_scale;
}
bool ElementAnimations::ScrollOffsetAnimationWasInterrupted() const {
@@ -289,10 +263,24 @@ void ElementAnimations::NotifyClientFilterAnimated(
const FilterOperations& filters,
int target_property_id,
KeyframeModel* keyframe_model) {
- if (KeyframeModelAffectsActiveElements(keyframe_model))
- OnFilterAnimated(ElementListType::ACTIVE, filters, keyframe_model);
- if (KeyframeModelAffectsPendingElements(keyframe_model))
- OnFilterAnimated(ElementListType::PENDING, filters, keyframe_model);
+ switch (keyframe_model->target_property_id()) {
+ case TargetProperty::BACKDROP_FILTER:
+ if (KeyframeModelAffectsActiveElements(keyframe_model))
+ OnBackdropFilterAnimated(ElementListType::ACTIVE, filters,
+ keyframe_model);
+ if (KeyframeModelAffectsPendingElements(keyframe_model))
+ OnBackdropFilterAnimated(ElementListType::PENDING, filters,
+ keyframe_model);
+ break;
+ case TargetProperty::FILTER:
+ if (KeyframeModelAffectsActiveElements(keyframe_model))
+ OnFilterAnimated(ElementListType::ACTIVE, filters, keyframe_model);
+ if (KeyframeModelAffectsPendingElements(keyframe_model))
+ OnFilterAnimated(ElementListType::PENDING, filters, keyframe_model);
+ break;
+ default:
+ NOTREACHED();
+ }
}
void ElementAnimations::NotifyClientTransformOperationsAnimated(
@@ -369,8 +357,12 @@ void ElementAnimations::UpdateClientAnimationState() {
element_id_map, ElementListType::ACTIVE, diff_active, active_state_);
}
- float maximum_scale = MaximumTargetScale(ElementListType::ACTIVE);
- float starting_scale = AnimationStartScale(ElementListType::ACTIVE);
+ float maximum_scale = kNotScaled;
+ float starting_scale = kNotScaled;
+ if (transform_element_id) {
+ GetAnimationScales(ElementListType::ACTIVE, &maximum_scale,
+ &starting_scale);
+ }
if (maximum_scale != active_maximum_scale_ ||
starting_scale != active_starting_scale_) {
animation_host_->mutator_host_client()->AnimationScalesChanged(
@@ -389,8 +381,12 @@ void ElementAnimations::UpdateClientAnimationState() {
pending_state_);
}
- float maximum_scale = MaximumTargetScale(ElementListType::PENDING);
- float starting_scale = AnimationStartScale(ElementListType::PENDING);
+ float maximum_scale = kNotScaled;
+ float starting_scale = kNotScaled;
+ if (transform_element_id) {
+ GetAnimationScales(ElementListType::PENDING, &maximum_scale,
+ &starting_scale);
+ }
if (maximum_scale != pending_maximum_scale_ ||
starting_scale != pending_starting_scale_) {
animation_host_->mutator_host_client()->AnimationScalesChanged(
@@ -464,6 +460,18 @@ void ElementAnimations::OnFilterAnimated(ElementListType list_type,
target_element_id, list_type, filters);
}
+void ElementAnimations::OnBackdropFilterAnimated(
+ ElementListType list_type,
+ const FilterOperations& backdrop_filters,
+ KeyframeModel* keyframe_model) {
+ ElementId target_element_id = CalculateTargetElementId(this, keyframe_model);
+ DCHECK(target_element_id);
+ DCHECK(animation_host_);
+ DCHECK(animation_host_->mutator_host_client());
+ animation_host_->mutator_host_client()->SetElementBackdropFilterMutated(
+ target_element_id, list_type, backdrop_filters);
+}
+
void ElementAnimations::OnOpacityAnimated(ElementListType list_type,
float opacity,
KeyframeModel* keyframe_model) {
diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h
index 911106b04d8..e2a46551787 100644
--- a/chromium/cc/animation/element_animations.h
+++ b/chromium/cc/animation/element_animations.h
@@ -52,8 +52,11 @@ class CC_ANIMATION_EXPORT ElementAnimations
void ClearAffectedElementTypes(const PropertyToElementIdMap& element_id_map);
- void ElementRegistered(ElementId element_id, ElementListType list_type);
- void ElementUnregistered(ElementId element_id, ElementListType list_type);
+ // Called when |element_id| is available to animate in |list_type|.
+ void ElementIdRegistered(ElementId element_id, ElementListType list_type);
+
+ // Called when |element_id| is no longer avialable to animate in |list_type|.
+ void ElementIdUnregistered(ElementId element_id, ElementListType list_type);
void AddKeyframeEffect(KeyframeEffect* keyframe_effect);
void RemoveKeyframeEffect(KeyframeEffect* keyframe_effect);
@@ -107,19 +110,17 @@ class CC_ANIMATION_EXPORT ElementAnimations
has_element_in_pending_list_ = has_element_in_pending_list;
}
- bool HasOnlyTranslationTransforms(ElementListType list_type) const;
-
bool AnimationsPreserveAxisAlignment() const;
- // Returns the maximum of starting animation scale along any dimension at any
- // destination in active scale animations, or kNotScaled if there is no active
- // scale animation or the starting scale cannot be computed.
- float AnimationStartScale(ElementListType list_type) const;
-
- // Returns the maximum scale along any dimension at any destination in active
- // scale animations, or kNotScaled if there is no active scale animation or
- // the maximum scale cannot be computed.
- float MaximumTargetScale(ElementListType list_type) const;
+ // Gets scales transform animations. On return, |maximum_scale| is the maximum
+ // scale along any dimension at any destination in active scale animations,
+ // and |starting_scale| is the maximum of starting animation scale along any
+ // dimension at any destination in active scale animations. They are set to
+ // kNotScaled if there is no active scale animation or the scales cannot be
+ // computed.
+ void GetAnimationScales(ElementListType list_type,
+ float* maximum_scale,
+ float* starting_scale) const;
bool ScrollOffsetAnimationWasInterrupted() const;
@@ -179,6 +180,9 @@ class CC_ANIMATION_EXPORT ElementAnimations
void OnFilterAnimated(ElementListType list_type,
const FilterOperations& filters,
KeyframeModel* keyframe_model);
+ void OnBackdropFilterAnimated(ElementListType list_type,
+ const FilterOperations& backdrop_filters,
+ KeyframeModel* keyframe_model);
void OnOpacityAnimated(ElementListType list_type,
float opacity,
KeyframeModel* keyframe_model);
diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc
index ee842dc9751..f093553fe15 100644
--- a/chromium/cc/animation/element_animations_unittest.cc
+++ b/chromium/cc/animation/element_animations_unittest.cc
@@ -60,11 +60,13 @@ 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_.RegisterElement(element_id_, ElementListType::ACTIVE);
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
- EXPECT_TRUE(client_.IsElementInList(element_id_, ElementListType::ACTIVE));
- EXPECT_FALSE(client_.IsElementInList(element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(
+ client_.IsElementInPropertyTrees(element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(
+ client_.IsElementInPropertyTrees(element_id_, ElementListType::PENDING));
AttachTimelineAnimationLayer();
@@ -79,17 +81,17 @@ TEST_F(ElementAnimationsTest, AttachToLayerInActiveTree) {
EXPECT_TRUE(element_animations_impl_->has_element_in_pending_list());
// Create the layer in the impl active tree.
- client_impl_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(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_.IsElementInList(element_id_, ElementListType::ACTIVE));
- EXPECT_TRUE(
- client_impl_.IsElementInList(element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.IsElementInPropertyTrees(element_id_,
+ ElementListType::ACTIVE));
+ EXPECT_TRUE(client_impl_.IsElementInPropertyTrees(element_id_,
+ ElementListType::PENDING));
// kill layer on main thread.
- client_.UnregisterElement(element_id_, ElementListType::ACTIVE);
+ client_.UnregisterElementId(element_id_, ElementListType::ACTIVE);
EXPECT_EQ(element_animations_,
animation_->keyframe_effect()->element_animations());
EXPECT_FALSE(element_animations_->has_element_in_active_list());
@@ -103,14 +105,14 @@ TEST_F(ElementAnimationsTest, AttachToLayerInActiveTree) {
EXPECT_TRUE(element_animations_impl_->has_element_in_pending_list());
// Kill layer on impl thread in pending tree.
- client_impl_.UnregisterElement(element_id_, ElementListType::PENDING);
+ client_impl_.UnregisterElementId(element_id_, ElementListType::PENDING);
EXPECT_EQ(element_animations_impl_,
animation_impl_->keyframe_effect()->element_animations());
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_.UnregisterElement(element_id_, ElementListType::ACTIVE);
+ client_impl_.UnregisterElementId(element_id_, ElementListType::ACTIVE);
EXPECT_EQ(element_animations_impl_,
animation_impl_->keyframe_effect()->element_animations());
EXPECT_FALSE(element_animations_impl_->has_element_in_active_list());
@@ -152,15 +154,15 @@ TEST_F(ElementAnimationsTest, AttachToNotYetCreatedLayer) {
EXPECT_FALSE(element_animations_impl_->has_element_in_pending_list());
// Create layer.
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
EXPECT_TRUE(element_animations_->has_element_in_active_list());
EXPECT_FALSE(element_animations_->has_element_in_pending_list());
- client_impl_.RegisterElement(element_id_, ElementListType::PENDING);
+ client_impl_.RegisterElementId(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_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
EXPECT_TRUE(element_animations_impl_->has_element_in_active_list());
EXPECT_TRUE(element_animations_impl_->has_element_in_pending_list());
}
@@ -836,6 +838,50 @@ TEST_F(ElementAnimationsTest, FilterTransition) {
EXPECT_FALSE(animation_->keyframe_effect()->HasTickingKeyframeModel());
}
+TEST_F(ElementAnimationsTest, BackdropFilterTransition) {
+ CreateTestLayer(true, false);
+ AttachTimelineAnimationLayer();
+
+ auto events = CreateEventsForTesting();
+
+ std::unique_ptr<KeyframedFilterAnimationCurve> curve(
+ KeyframedFilterAnimationCurve::Create());
+
+ FilterOperations start_filters;
+ start_filters.Append(FilterOperation::CreateInvertFilter(0.f));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr));
+ FilterOperations end_filters;
+ end_filters.Append(FilterOperation::CreateInvertFilter(1.f));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
+ end_filters, nullptr));
+
+ std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
+ std::move(curve), 1, 0, TargetProperty::BACKDROP_FILTER));
+ animation_->AddKeyframeModel(std::move(keyframe_model));
+
+ animation_->Tick(kInitialTickTime);
+ animation_->UpdateState(true, events.get());
+ EXPECT_TRUE(animation_->keyframe_effect()->HasTickingKeyframeModel());
+ EXPECT_EQ(start_filters,
+ client_.GetBackdropFilters(element_id_, ElementListType::ACTIVE));
+
+ animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(500));
+ animation_->UpdateState(true, events.get());
+ EXPECT_EQ(
+ 1u,
+ client_.GetBackdropFilters(element_id_, ElementListType::ACTIVE).size());
+ EXPECT_EQ(
+ FilterOperation::CreateInvertFilter(0.5f),
+ client_.GetBackdropFilters(element_id_, ElementListType::ACTIVE).at(0));
+
+ animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
+ animation_->UpdateState(true, events.get());
+ EXPECT_EQ(end_filters,
+ client_.GetBackdropFilters(element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(animation_->keyframe_effect()->HasTickingKeyframeModel());
+}
+
TEST_F(ElementAnimationsTest, ScrollOffsetTransition) {
CreateTestLayer(true, false);
AttachTimelineAnimationLayer();
@@ -1764,6 +1810,8 @@ TEST_F(ElementAnimationsTest, InactiveObserverGetsTicked) {
animation_impl_->AddKeyframeModel(CreateKeyframeModel(
std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.5f, 1.f)),
id, TargetProperty::OPACITY));
+ animation_impl_->GetKeyframeModel(TargetProperty::OPACITY)
+ ->set_affects_active_elements(false);
// Without an observer, the animation shouldn't progress to the STARTING
// state.
@@ -1800,6 +1848,8 @@ TEST_F(ElementAnimationsTest, InactiveObserverGetsTicked) {
client_impl_.GetOpacity(element_id_, ElementListType::PENDING));
CreateTestImplLayer(ElementListType::ACTIVE);
+ animation_impl_->GetKeyframeModel(TargetProperty::OPACITY)
+ ->set_affects_active_elements(true);
// Now that an active observer has been added, the animation should still
// initially tick at its starting point, but should now progress to RUNNING.
@@ -2162,25 +2212,35 @@ TEST_F(ElementAnimationsTest, FinishedAndAbortedEventsForGroup) {
EXPECT_EQ(TargetProperty::OPACITY, events->events_[1].target_property);
}
-TEST_F(ElementAnimationsTest, HasOnlyTranslationTransforms) {
+TEST_F(ElementAnimationsTest, GetAnimationScalesNotScaled) {
CreateTestLayer(true, false);
AttachTimelineAnimationLayer();
CreateImplTimelineAndAnimation();
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::ACTIVE));
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::PENDING));
+ float max_scale = 999;
+ float start_scale = 999;
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
animation_impl_->AddKeyframeModel(CreateKeyframeModel(
std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
1, TargetProperty::OPACITY));
// Opacity animations aren't non-translation transforms.
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::ACTIVE));
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::PENDING));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
std::unique_ptr<KeyframedTransformAnimationCurve> curve1(
KeyframedTransformAnimationCurve::Create());
@@ -2197,58 +2257,17 @@ TEST_F(ElementAnimationsTest, HasOnlyTranslationTransforms) {
animation_impl_->AddKeyframeModel(std::move(keyframe_model));
// The only transform animation we've added is a translation.
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::ACTIVE));
- EXPECT_TRUE(animation_impl_->keyframe_effect()->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));
-
- keyframe_model =
- KeyframeModel::Create(std::move(curve2), 3, 3, TargetProperty::TRANSFORM);
- keyframe_model->set_affects_active_elements(false);
- animation_impl_->AddKeyframeModel(std::move(keyframe_model));
-
- // A scale animation is not a translation.
- EXPECT_FALSE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::PENDING));
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::ACTIVE));
-
- animation_impl_->ActivateKeyframeEffects();
- EXPECT_FALSE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::PENDING));
- EXPECT_FALSE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::ACTIVE));
-
- animation_impl_->keyframe_effect()
- ->GetKeyframeModelById(3)
- ->set_affects_pending_elements(false);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::PENDING));
- EXPECT_FALSE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::ACTIVE));
-
- animation_impl_->keyframe_effect()->GetKeyframeModelById(3)->SetRunState(
- KeyframeModel::FINISHED, TicksFromSecondsF(0.0));
-
- // Only unfinished animations should be considered by
- // HasOnlyTranslationTransforms.
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::PENDING));
- EXPECT_TRUE(animation_impl_->keyframe_effect()->HasOnlyTranslationTransforms(
- ElementListType::ACTIVE));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
}
-TEST_F(ElementAnimationsTest, AnimationStartScale) {
+TEST_F(ElementAnimationsTest, GetAnimationScales) {
CreateTestLayer(true, false);
AttachTimelineAnimationLayer();
CreateImplTimelineAndAnimation();
@@ -2256,43 +2275,51 @@ TEST_F(ElementAnimationsTest, AnimationStartScale) {
std::unique_ptr<KeyframedTransformAnimationCurve> curve1(
KeyframedTransformAnimationCurve::Create());
- TransformOperations operations1;
- operations1.AppendScale(2.0, 3.0, 4.0);
+ TransformOperations operations1a;
+ operations1a.AppendScale(2.0, 3.0, 4.0);
curve1->AddKeyframe(
- TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
- TransformOperations operations2;
+ TransformKeyframe::Create(base::TimeDelta(), operations1a, nullptr));
+ TransformOperations operations1b;
+ operations1b.AppendScale(5.0, 4.0, 3.0);
curve1->AddKeyframe(TransformKeyframe::Create(
- base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
+ base::TimeDelta::FromSecondsD(1.0), operations1b, nullptr));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve1), 1, 1, TargetProperty::TRANSFORM));
keyframe_model->set_affects_active_elements(false);
animation_impl_->AddKeyframeModel(std::move(keyframe_model));
- float start_scale = 0.f;
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::PENDING, &start_scale));
+ float max_scale = kNotScaled;
+ float start_scale = kNotScaled;
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(5.f, max_scale);
EXPECT_EQ(4.f, start_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::ACTIVE, &start_scale));
- EXPECT_EQ(0.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
animation_impl_->ActivateKeyframeEffects();
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::PENDING, &start_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(5.f, max_scale);
EXPECT_EQ(4.f, start_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::ACTIVE, &start_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(5.f, max_scale);
EXPECT_EQ(4.f, start_scale);
std::unique_ptr<KeyframedTransformAnimationCurve> curve2(
KeyframedTransformAnimationCurve::Create());
- TransformOperations operations3;
+ TransformOperations operations2a;
+ operations2a.AppendScale(1.0, 2.0, 3.0);
curve2->AddKeyframe(
- TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr));
- operations3.AppendScale(6.0, 5.0, 4.0);
+ TransformKeyframe::Create(base::TimeDelta(), operations2a, nullptr));
+ TransformOperations operations2b;
+ operations2b.AppendScale(6.0, 5.0, 4.0);
curve2->AddKeyframe(TransformKeyframe::Create(
- base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));
+ base::TimeDelta::FromSecondsD(1.0), operations2b, nullptr));
animation_impl_->RemoveKeyframeModel(1);
keyframe_model =
@@ -2306,163 +2333,54 @@ TEST_F(ElementAnimationsTest, AnimationStartScale) {
std::unique_ptr<KeyframedTransformAnimationCurve> curve3(
KeyframedTransformAnimationCurve::Create());
- TransformOperations operations4;
- operations4.AppendScale(5.0, 3.0, 1.0);
+ TransformOperations operations3a;
+ operations3a.AppendScale(5.0, 3.0, 1.0);
curve3->AddKeyframe(
- TransformKeyframe::Create(base::TimeDelta(), operations4, nullptr));
- TransformOperations operations5;
+ TransformKeyframe::Create(base::TimeDelta(), operations3a, nullptr));
+ TransformOperations operations3b;
+ operations3b.AppendScale(1.5, 2.5, 3.5);
curve3->AddKeyframe(TransformKeyframe::Create(
- base::TimeDelta::FromSecondsD(1.0), operations5, nullptr));
+ base::TimeDelta::FromSecondsD(1.0), operations3b, nullptr));
keyframe_model =
KeyframeModel::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM);
keyframe_model->set_affects_active_elements(false);
animation_impl_->AddKeyframeModel(std::move(keyframe_model));
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::PENDING, &start_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(3.5f, max_scale);
EXPECT_EQ(6.f, start_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::ACTIVE, &start_scale));
- EXPECT_EQ(0.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(kNotScaled, max_scale);
+ EXPECT_EQ(kNotScaled, start_scale);
animation_impl_->ActivateKeyframeEffects();
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::PENDING, &start_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(3.5f, max_scale);
EXPECT_EQ(6.f, start_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::ACTIVE, &start_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(3.5f, max_scale);
EXPECT_EQ(6.f, start_scale);
animation_impl_->keyframe_effect()->GetKeyframeModelById(2)->SetRunState(
KeyframeModel::FINISHED, TicksFromSecondsF(0.0));
- // Only unfinished animations should be considered by
- // AnimationStartScale.
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::PENDING, &start_scale));
+ // Only unfinished animations should be considered by GetAnimationScales.
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
+ EXPECT_EQ(3.5f, max_scale);
EXPECT_EQ(5.f, start_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->AnimationStartScale(
- ElementListType::ACTIVE, &start_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
+ EXPECT_EQ(3.5f, max_scale);
EXPECT_EQ(5.f, start_scale);
}
-TEST_F(ElementAnimationsTest, MaximumTargetScale) {
- CreateTestLayer(true, false);
- AttachTimelineAnimationLayer();
- CreateImplTimelineAndAnimation();
-
- float max_scale = 0.f;
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_EQ(0.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->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<KeyframeModel> keyframe_model(KeyframeModel::Create(
- std::move(curve1), 1, 1, TargetProperty::TRANSFORM));
- keyframe_model->set_affects_active_elements(false);
- animation_impl_->AddKeyframeModel(std::move(keyframe_model));
-
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_EQ(4.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
- EXPECT_EQ(0.f, max_scale);
-
- animation_impl_->ActivateKeyframeEffects();
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_EQ(4.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->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));
-
- keyframe_model =
- KeyframeModel::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM);
- keyframe_model->set_affects_active_elements(false);
- animation_impl_->AddKeyframeModel(std::move(keyframe_model));
-
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_EQ(6.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
- EXPECT_EQ(4.f, max_scale);
-
- animation_impl_->ActivateKeyframeEffects();
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_EQ(6.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->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));
-
- keyframe_model =
- KeyframeModel::Create(std::move(curve3), 3, 3, TargetProperty::TRANSFORM);
- keyframe_model->set_affects_active_elements(false);
- animation_impl_->AddKeyframeModel(std::move(keyframe_model));
-
- EXPECT_FALSE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
- EXPECT_EQ(6.f, max_scale);
-
- animation_impl_->ActivateKeyframeEffects();
- EXPECT_FALSE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_FALSE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
-
- animation_impl_->keyframe_effect()->GetKeyframeModelById(3)->SetRunState(
- KeyframeModel::FINISHED, TicksFromSecondsF(0.0));
- animation_impl_->keyframe_effect()->GetKeyframeModelById(2)->SetRunState(
- KeyframeModel::FINISHED, TicksFromSecondsF(0.0));
-
- // Only unfinished animations should be considered by
- // MaximumTargetScale.
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
- EXPECT_EQ(4.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
- EXPECT_EQ(4.f, max_scale);
-}
-
-TEST_F(ElementAnimationsTest, MaximumTargetScaleWithDirection) {
+TEST_F(ElementAnimationsTest, GetAnimationScalesWithDirection) {
CreateTestLayer(true, false);
AttachTimelineAnimationLayer();
CreateImplTimelineAndAnimation();
@@ -2483,83 +2401,100 @@ TEST_F(ElementAnimationsTest, MaximumTargetScaleWithDirection) {
KeyframeModel* keyframe_model = keyframe_model_owned.get();
animation_impl_->AddKeyframeModel(std::move(keyframe_model_owned));
- float max_scale = 0.f;
+ float max_scale = 999;
+ float start_scale = 999;
EXPECT_GT(keyframe_model->playback_rate(), 0.0);
// NORMAL direction with positive playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::NORMAL);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(3.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
+ EXPECT_EQ(3.f, start_scale);
// ALTERNATE direction with positive playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::ALTERNATE_NORMAL);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(3.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
+ EXPECT_EQ(3.f, start_scale);
// REVERSE direction with positive playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(6.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
+ EXPECT_EQ(6.f, start_scale);
// ALTERNATE reverse direction.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(6.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
+ EXPECT_EQ(6.f, start_scale);
keyframe_model->set_playback_rate(-1.0);
// NORMAL direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::NORMAL);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(6.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
+ EXPECT_EQ(6.f, start_scale);
// ALTERNATE direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::ALTERNATE_NORMAL);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(6.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(3.f, max_scale);
+ EXPECT_EQ(6.f, start_scale);
// REVERSE direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(3.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
+ EXPECT_EQ(3.f, start_scale);
// ALTERNATE reverse direction with negative playback rate.
keyframe_model->set_direction(KeyframeModel::Direction::REVERSE);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::PENDING, &max_scale));
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::PENDING, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
- EXPECT_TRUE(animation_impl_->keyframe_effect()->MaximumTargetScale(
- ElementListType::ACTIVE, &max_scale));
+ EXPECT_EQ(3.f, start_scale);
+ EXPECT_TRUE(animation_impl_->keyframe_effect()->GetAnimationScales(
+ ElementListType::ACTIVE, &max_scale, &start_scale));
EXPECT_EQ(6.f, max_scale);
+ EXPECT_EQ(3.f, start_scale);
}
TEST_F(ElementAnimationsTest, NewlyPushedAnimationWaitsForActivation) {
@@ -3348,6 +3283,221 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenFilterAnimationChanges) {
element_id_, ElementListType::ACTIVE));
}
+TEST_F(ElementAnimationsTest,
+ ObserverNotifiedWhenBackdropFilterAnimationChanges) {
+ CreateTestLayer(true, true);
+ AttachTimelineAnimationLayer();
+ CreateImplTimelineAndAnimation();
+
+ auto events = CreateEventsForTesting();
+
+ EXPECT_FALSE(client_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ // Case 1: An animation that's allowed to run until its finish point.
+ AddAnimatedBackdropFilterToAnimation(animation_.get(), 1.0, 0.f, 1.f);
+ EXPECT_TRUE(client_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ PushProperties();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->ActivateKeyframeEffects();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->Tick(kInitialTickTime);
+ animation_impl_->UpdateState(true, events.get());
+
+ animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ events->events_.clear();
+
+ // Finish the animation.
+ animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
+ animation_->UpdateState(true, nullptr);
+ EXPECT_FALSE(client_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ PushProperties();
+
+ // Finished animations are pushed, but animations_impl hasn't yet ticked
+ // at/past the end of the animation.
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
+ animation_impl_->UpdateState(true, events.get());
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ // Case 2: An animation that's removed before it finishes.
+ int keyframe_model_id =
+ AddAnimatedBackdropFilterToAnimation(animation_.get(), 10.0, 0.f, 1.f);
+ EXPECT_TRUE(client_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ PushProperties();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->ActivateKeyframeEffects();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
+ animation_impl_->UpdateState(true, events.get());
+
+ animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ events->events_.clear();
+
+ animation_->RemoveKeyframeModel(keyframe_model_id);
+ EXPECT_FALSE(client_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ PushProperties();
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->ActivateKeyframeEffects();
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ // Case 3: An animation that's aborted before it finishes.
+ keyframe_model_id =
+ AddAnimatedBackdropFilterToAnimation(animation_.get(), 10.0, 0.f, 0.5f);
+ EXPECT_TRUE(client_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ PushProperties();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->ActivateKeyframeEffects();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_TRUE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
+ animation_impl_->UpdateState(true, events.get());
+
+ animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ events->events_.clear();
+
+ animation_impl_->AbortKeyframeModelsWithProperty(
+ TargetProperty::BACKDROP_FILTER, false);
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(4000));
+ animation_impl_->UpdateState(true, events.get());
+
+ element_animations_->NotifyAnimationAborted(events->events_[0]);
+ EXPECT_FALSE(client_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ // Case 4 : An animation that's not in effect.
+ keyframe_model_id =
+ AddAnimatedBackdropFilterToAnimation(animation_.get(), 1.0, 0.f, 0.5f);
+ animation_->keyframe_effect()
+ ->GetKeyframeModelById(keyframe_model_id)
+ ->set_time_offset(base::TimeDelta::FromMilliseconds(-10000));
+ animation_->keyframe_effect()
+ ->GetKeyframeModelById(keyframe_model_id)
+ ->set_fill_mode(KeyframeModel::FillMode::NONE);
+
+ PushProperties();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::PENDING));
+ EXPECT_FALSE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+
+ animation_impl_->ActivateKeyframeEffects();
+ EXPECT_TRUE(client_impl_.GetHasPotentialBackdropFilterAnimation(
+ element_id_, ElementListType::ACTIVE));
+ EXPECT_FALSE(client_impl_.GetBackdropFilterIsCurrentlyAnimating(
+ element_id_, ElementListType::ACTIVE));
+}
+
TEST_F(ElementAnimationsTest, ClippedOpacityValues) {
CreateTestLayer(false, false);
AttachTimelineAnimationLayer();
@@ -3704,9 +3854,11 @@ TEST_F(ElementAnimationsTest, DestroyTestMainLayerBeforePushProperties) {
EXPECT_EQ(1u, host_->ticking_animations_for_testing().size());
DestroyTestMainLayer();
+ host_->UpdateAnimationState(true, nullptr);
EXPECT_EQ(0u, host_->ticking_animations_for_testing().size());
PushProperties();
+ host_impl_->ActivateAnimations(nullptr);
EXPECT_EQ(0u, host_->ticking_animations_for_testing().size());
EXPECT_EQ(0u, host_impl_->ticking_animations_for_testing().size());
}
diff --git a/chromium/cc/animation/keyframe_effect.cc b/chromium/cc/animation/keyframe_effect.cc
index 6a6dc76a121..d1d55431893 100644
--- a/chromium/cc/animation/keyframe_effect.cc
+++ b/chromium/cc/animation/keyframe_effect.cc
@@ -183,13 +183,11 @@ void KeyframeEffect::RemoveFromTicking() {
void KeyframeEffect::UpdateState(bool start_ready_keyframe_models,
AnimationEvents* events) {
DCHECK(has_bound_element_animations());
- if (!element_animations_->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;
+ start_ready_keyframe_models = false;
if (start_ready_keyframe_models)
PromoteStartedKeyframeModels(events);
@@ -204,6 +202,9 @@ void KeyframeEffect::UpdateState(bool start_ready_keyframe_models,
PromoteStartedKeyframeModels(events);
}
}
+
+ if (!element_animations()->has_element_in_any_list())
+ RemoveFromTicking();
}
void KeyframeEffect::UpdateTickingState() {
@@ -460,27 +461,6 @@ bool KeyframeEffect::HasNonDeletedKeyframeModel() const {
return false;
}
-bool KeyframeEffect::HasOnlyTranslationTransforms(
- ElementListType list_type) const {
- for (const auto& keyframe_model : keyframe_models_) {
- if (keyframe_model->is_finished() ||
- keyframe_model->target_property_id() != TargetProperty::TRANSFORM)
- continue;
-
- if ((list_type == ElementListType::ACTIVE &&
- !keyframe_model->affects_active_elements()) ||
- (list_type == ElementListType::PENDING &&
- !keyframe_model->affects_pending_elements()))
- continue;
-
- const TransformAnimationCurve* transform_animation_curve =
- keyframe_model->curve()->ToTransformAnimationCurve();
- if (!transform_animation_curve->IsTranslation())
- return false;
- }
- return true;
-}
-
bool KeyframeEffect::AnimationsPreserveAxisAlignment() const {
for (const auto& keyframe_model : keyframe_models_) {
if (keyframe_model->is_finished() ||
@@ -495,9 +475,13 @@ bool KeyframeEffect::AnimationsPreserveAxisAlignment() const {
return true;
}
-bool KeyframeEffect::AnimationStartScale(ElementListType list_type,
- float* start_scale) const {
- *start_scale = 0.f;
+bool KeyframeEffect::GetAnimationScales(ElementListType list_type,
+ float* maximum_scale,
+ float* starting_scale) const {
+ *maximum_scale = kNotScaled;
+ *starting_scale = kNotScaled;
+ bool maximum_scale_valid = true;
+ bool starting_scale_valid = true;
for (const auto& keyframe_model : keyframe_models_) {
if (keyframe_model->is_finished() ||
keyframe_model->target_property_id() != TargetProperty::TRANSFORM)
@@ -509,41 +493,9 @@ bool KeyframeEffect::AnimationStartScale(ElementListType list_type,
!keyframe_model->affects_pending_elements()))
continue;
- bool forward_direction = true;
- switch (keyframe_model->direction()) {
- case KeyframeModel::Direction::NORMAL:
- case KeyframeModel::Direction::ALTERNATE_NORMAL:
- forward_direction = keyframe_model->playback_rate() >= 0.0;
- break;
- case KeyframeModel::Direction::REVERSE:
- case KeyframeModel::Direction::ALTERNATE_REVERSE:
- forward_direction = keyframe_model->playback_rate() < 0.0;
- break;
- }
-
const TransformAnimationCurve* transform_animation_curve =
keyframe_model->curve()->ToTransformAnimationCurve();
- float keyframe_model_start_scale = 0.f;
- if (!transform_animation_curve->AnimationStartScale(
- forward_direction, &keyframe_model_start_scale))
- return false;
- *start_scale = std::max(*start_scale, keyframe_model_start_scale);
- }
- return true;
-}
-
-bool KeyframeEffect::MaximumTargetScale(ElementListType list_type,
- float* max_scale) const {
- *max_scale = 0.f;
- for (const auto& keyframe_model : keyframe_models_) {
- if (keyframe_model->is_finished() ||
- keyframe_model->target_property_id() != TargetProperty::TRANSFORM)
- continue;
-
- if ((list_type == ElementListType::ACTIVE &&
- !keyframe_model->affects_active_elements()) ||
- (list_type == ElementListType::PENDING &&
- !keyframe_model->affects_pending_elements()))
+ if (transform_animation_curve->IsTranslation())
continue;
bool forward_direction = true;
@@ -558,15 +510,32 @@ bool KeyframeEffect::MaximumTargetScale(ElementListType list_type,
break;
}
- const TransformAnimationCurve* transform_animation_curve =
- keyframe_model->curve()->ToTransformAnimationCurve();
- float keyframe_model_scale = 0.f;
- if (!transform_animation_curve->MaximumTargetScale(forward_direction,
- &keyframe_model_scale))
+ if (maximum_scale_valid) {
+ float keyframe_model_maximum_scale = kNotScaled;
+ if (transform_animation_curve->MaximumTargetScale(
+ forward_direction, &keyframe_model_maximum_scale)) {
+ *maximum_scale = std::max(*maximum_scale, keyframe_model_maximum_scale);
+ } else {
+ maximum_scale_valid = false;
+ *maximum_scale = kNotScaled;
+ }
+ }
+
+ if (starting_scale_valid) {
+ float keyframe_model_starting_scale = kNotScaled;
+ if (transform_animation_curve->AnimationStartScale(
+ forward_direction, &keyframe_model_starting_scale)) {
+ *starting_scale =
+ std::max(*starting_scale, keyframe_model_starting_scale);
+ } else {
+ starting_scale_valid = false;
+ *starting_scale = kNotScaled;
+ }
+ }
+
+ if (!maximum_scale_valid && !starting_scale_valid)
return false;
- *max_scale = std::max(*max_scale, keyframe_model_scale);
}
-
return true;
}
@@ -681,6 +650,15 @@ void KeyframeEffect::PurgeKeyframeModelsMarkedForDeletion(bool impl_only) {
});
}
+void KeyframeEffect::PurgeDeletedKeyframeModels() {
+ base::EraseIf(keyframe_models_,
+ [](const std::unique_ptr<KeyframeModel>& keyframe_model) {
+ return keyframe_model->run_state() ==
+ KeyframeModel::WAITING_FOR_DELETION &&
+ !keyframe_model->affects_pending_elements();
+ });
+}
+
void KeyframeEffect::PushNewKeyframeModelsToImplThread(
KeyframeEffect* keyframe_effect_impl) const {
// Any new KeyframeModels owned by the main thread's Animation are
@@ -746,22 +724,15 @@ void KeyframeEffect::RemoveKeyframeModelsCompletedOnMainThread(
// elements, and should stop affecting active elements after the next call
// to ActivateKeyframeEffects. If already WAITING_FOR_DELETION, they can be
// removed immediately.
- auto& keyframe_models = keyframe_effect_impl->keyframe_models_;
- for (const auto& keyframe_model : keyframe_models) {
+ for (const std::unique_ptr<KeyframeModel>& keyframe_model :
+ keyframe_effect_impl->keyframe_models_) {
if (IsCompleted(keyframe_model.get(), this)) {
keyframe_model->set_affects_pending_elements(false);
keyframe_model_completed = true;
}
}
- auto affects_active_only_and_is_waiting_for_deletion =
- [](const std::unique_ptr<KeyframeModel>& keyframe_model) {
- return keyframe_model->run_state() ==
- KeyframeModel::WAITING_FOR_DELETION &&
- !keyframe_model->affects_pending_elements();
- };
- base::EraseIf(keyframe_models,
- affects_active_only_and_is_waiting_for_deletion);
+ keyframe_effect_impl->PurgeDeletedKeyframeModels();
if (has_bound_element_animations() && keyframe_model_completed)
element_animations_->SetNeedsPushProperties();
}
diff --git a/chromium/cc/animation/keyframe_effect.h b/chromium/cc/animation/keyframe_effect.h
index 500f0bd5352..3bcb0347439 100644
--- a/chromium/cc/animation/keyframe_effect.h
+++ b/chromium/cc/animation/keyframe_effect.h
@@ -121,19 +121,17 @@ class CC_ANIMATION_EXPORT KeyframeEffect {
bool HasNonDeletedKeyframeModel() const;
- bool HasOnlyTranslationTransforms(ElementListType list_type) const;
-
bool AnimationsPreserveAxisAlignment() const;
- // Sets |start_scale| to the maximum of starting keyframe_model scale along
- // any dimension at any destination in active KeyframeModels. Returns false
- // if the starting scale cannot be computed.
- bool AnimationStartScale(ElementListType, float* start_scale) const;
-
- // Sets |max_scale| to the maximum scale along any dimension at any
- // destination in active KeyframeModels. Returns false if the maximum scale
- // cannot be computed.
- bool MaximumTargetScale(ElementListType, float* max_scale) const;
+ // Gets scales transform animations. On return, |maximum_scale| is the maximum
+ // scale along any dimension at any destination in active scale animations,
+ // and |starting_scale| is the maximum of starting animation scale along any
+ // dimension at any destination in active scale animations. They are set to
+ // kNotScaled if there is no active scale animation or the scales cannot be
+ // computed. Returns false if the scales cannot be computed.
+ bool GetAnimationScales(ElementListType,
+ float* maximum_scale,
+ float* starting_scale) const;
// Returns true if there is a keyframe_model that is either currently
// animating the given property or scheduled to animate this property in the
@@ -169,6 +167,7 @@ class CC_ANIMATION_EXPORT KeyframeEffect {
private:
void StartKeyframeModels(base::TimeTicks monotonic_time);
void PromoteStartedKeyframeModels(AnimationEvents* events);
+ void PurgeDeletedKeyframeModels();
void MarkKeyframeModelsForDeletion(base::TimeTicks, AnimationEvents* events);
void MarkFinishedKeyframeModels(base::TimeTicks monotonic_time);
diff --git a/chromium/cc/animation/keyframed_animation_curve_unittest.cc b/chromium/cc/animation/keyframed_animation_curve_unittest.cc
index 05ab2145f74..4b678bdfac6 100644
--- a/chromium/cc/animation/keyframed_animation_curve_unittest.cc
+++ b/chromium/cc/animation/keyframed_animation_curve_unittest.cc
@@ -602,30 +602,6 @@ TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtEnd) {
}
}
-// Tests a frames timing function.
-TEST(KeyframedAnimationCurveTest, FramesTimingFunction) {
- std::unique_ptr<KeyframedFloatAnimationCurve> curve(
- KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f,
- FramesTimingFunction::Create(5)));
- curve->AddKeyframe(
- FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
-
- struct Expected {
- double time;
- float value;
- } expectations[] = {
- {0.0, 0.f}, {0.1999, 0.f}, {0.2001, 0.25f}, {0.3999, 0.25f},
- {0.4001, 0.5f}, {0.5999, 0.5f}, {0.6001, 0.75f}, {0.7999, 0.75f},
- {0.8001, 1.f}, {1.0, 1.f},
- };
- for (const auto& expectation : expectations) {
- EXPECT_FLOAT_EQ(
- expectation.value,
- curve->GetValue(base::TimeDelta::FromSecondsD(expectation.time)));
- }
-}
-
// Tests that animations that are translations are correctly identified.
TEST(KeyframedAnimationCurveTest, IsTranslation) {
std::unique_ptr<KeyframedTransformAnimationCurve> curve(
@@ -916,23 +892,6 @@ TEST(KeyframedAnimationCurveTest, StepsTimingEndInputsOutsideZeroOneRange) {
EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
}
-// Tests that a frames timing function works as expected for inputs outside of
-// range [0,1]
-TEST(KeyframedAnimationCurveTest, FramesTimingInputsOutsideZeroOneRange) {
- std::unique_ptr<KeyframedFloatAnimationCurve> curve(
- KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f,
- FramesTimingFunction::Create(5)));
- curve->AddKeyframe(
- FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
- // Curve timing function producing timing outputs outside of range [0,1].
- curve->SetTimingFunction(
- CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
-
- EXPECT_FLOAT_EQ(-0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
- EXPECT_FLOAT_EQ(2.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
-}
-
// Tests that an animation with a curve timing function and multiple keyframes
// works as expected.
TEST(KeyframedAnimationCurveTest, CurveTimingMultipleKeyframes) {
diff --git a/chromium/cc/animation/scroll_timeline.cc b/chromium/cc/animation/scroll_timeline.cc
index 16ef8ded216..cc4b5bf7140 100644
--- a/chromium/cc/animation/scroll_timeline.cc
+++ b/chromium/cc/animation/scroll_timeline.cc
@@ -47,25 +47,33 @@ std::unique_ptr<ScrollTimeline> ScrollTimeline::CreateImplInstance() const {
time_range_, fill_);
}
+bool ScrollTimeline::IsActive(const ScrollTree& scroll_tree,
+ bool is_active_tree) const {
+ // If pending tree with our scroller hasn't been activated, or the scroller
+ // has been removed (e.g. if it is no longer composited).
+ if ((is_active_tree && !active_id_) || (!is_active_tree && !pending_id_))
+ return false;
+
+ ElementId scroller_id =
+ is_active_tree ? active_id_.value() : pending_id_.value();
+ // The scroller is not in the ScrollTree if it is not currently scrollable
+ // (e.g. has overflow: visible). In this case the timeline is not active.
+ return scroll_tree.FindNodeFromElementId(scroller_id);
+}
+
base::Optional<base::TimeTicks> ScrollTimeline::CurrentTime(
const ScrollTree& scroll_tree,
bool is_active_tree) const {
- // We may be asked for the CurrentTime before the pending tree with our
- // scroller has been activated, or after the scroller has been removed (e.g.
- // if it is no longer composited). In these cases the best we can do is to
- // return an unresolved time value.
- if ((is_active_tree && !active_id_) || (!is_active_tree && !pending_id_))
+ // If the timeline is not active return unresolved value by the spec.
+ // https://github.com/WICG/scroll-animations/issues/31
+ // https://wicg.github.io/scroll-animations/#current-time-algorithm
+ if (!IsActive(scroll_tree, is_active_tree))
return base::nullopt;
ElementId scroller_id =
is_active_tree ? active_id_.value() : pending_id_.value();
-
- // The scroller may not be in the ScrollTree if it is not currently scrollable
- // (e.g. has overflow: visible). By the spec, return an unresolved time value.
const ScrollNode* scroll_node =
scroll_tree.FindNodeFromElementId(scroller_id);
- if (!scroll_node)
- return base::nullopt;
gfx::ScrollOffset offset =
scroll_tree.GetPixelSnappedScrollOffset(scroll_node->id);
diff --git a/chromium/cc/animation/scroll_timeline.h b/chromium/cc/animation/scroll_timeline.h
index 759d2615d32..152c1a642db 100644
--- a/chromium/cc/animation/scroll_timeline.h
+++ b/chromium/cc/animation/scroll_timeline.h
@@ -41,6 +41,11 @@ class CC_ANIMATION_EXPORT ScrollTimeline {
// compositor.
std::unique_ptr<ScrollTimeline> CreateImplInstance() const;
+ // ScrollTimeline is active if the scroll node exists in active or pending
+ // scroll tree.
+ virtual bool IsActive(const ScrollTree& scroll_tree,
+ bool is_active_tree) const;
+
// Calculate the current time of the ScrollTimeline. This is either a
// base::TimeTicks value or base::nullopt if the current time is unresolved.
// The internal calculations are performed using doubles and the result is
diff --git a/chromium/cc/animation/scroll_timeline_unittest.cc b/chromium/cc/animation/scroll_timeline_unittest.cc
index 490b9428466..0b62b8f4ec8 100644
--- a/chromium/cc/animation/scroll_timeline_unittest.cc
+++ b/chromium/cc/animation/scroll_timeline_unittest.cc
@@ -181,8 +181,8 @@ TEST_F(ScrollTimelineTest, ActiveTimeIsSetOnlyAfterPromotion) {
base::nullopt, base::nullopt, 100,
KeyframeModel::FillMode::NONE);
- // Now create an impl version of the ScrollTimeline. Initilly this should only
- // have a pending scroller id, as the active tree may not yet have the
+ // Now create an impl version of the ScrollTimeline. Initially this should
+ // only have a pending scroller id, as the active tree may not yet have the
// scroller in it (as in this case).
std::unique_ptr<ScrollTimeline> impl_timeline =
main_timeline.CreateImplInstance();
@@ -379,4 +379,41 @@ TEST_F(ScrollTimelineTest, CurrentTimeHandlesFillMode) {
time_range, fill_auto_timeline.CurrentTime(scroll_tree(), false));
}
+TEST_F(ScrollTimelineTest, Activeness) {
+ // ScrollTimeline with zero scroller id is inactive.
+ ScrollTimeline inactive_timeline1(base::nullopt, ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, 100,
+ KeyframeModel::FillMode::NONE);
+ EXPECT_FALSE(
+ inactive_timeline1.IsActive(scroll_tree(), false /*is_active_tree*/));
+ EXPECT_FALSE(
+ inactive_timeline1.IsActive(scroll_tree(), true /*is_active_tree*/));
+
+ // ScrollTimeline with a scroller that is not in the scroll tree is
+ // inactive.
+ ScrollTimeline inactive_timeline2(ElementId(2), ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, 100,
+ KeyframeModel::FillMode::NONE);
+ EXPECT_FALSE(
+ inactive_timeline2.IsActive(scroll_tree(), false /*is_active_tree*/));
+ // Activate the scroll tree.
+ inactive_timeline2.PromoteScrollTimelinePendingToActive();
+ EXPECT_FALSE(
+ inactive_timeline2.IsActive(scroll_tree(), true /*is_active_tree*/));
+
+ ScrollTimeline active_timeline(scroller_id(), ScrollTimeline::ScrollDown,
+ base::nullopt, base::nullopt, 100,
+ KeyframeModel::FillMode::NONE);
+ EXPECT_TRUE(
+ active_timeline.IsActive(scroll_tree(), false /*is_active_tree*/));
+ EXPECT_FALSE(
+ active_timeline.IsActive(scroll_tree(), true /*is_active_tree*/));
+
+ // Activate the scroll tree.
+ active_timeline.PromoteScrollTimelinePendingToActive();
+ EXPECT_TRUE(
+ active_timeline.IsActive(scroll_tree(), false /*is_active_tree*/));
+ EXPECT_TRUE(active_timeline.IsActive(scroll_tree(), true /*is_active_tree*/));
+}
+
} // namespace cc
diff --git a/chromium/cc/animation/single_keyframe_effect_animation.cc b/chromium/cc/animation/single_keyframe_effect_animation.cc
index d102c3924b3..a467e5ee4e3 100644
--- a/chromium/cc/animation/single_keyframe_effect_animation.cc
+++ b/chromium/cc/animation/single_keyframe_effect_animation.cc
@@ -62,7 +62,7 @@ scoped_refptr<Animation> SingleKeyframeEffectAnimation::CreateImplInstance()
}
ElementId SingleKeyframeEffectAnimation::element_id() const {
- return element_id_of_keyframe_effect(GetKeyframeEffect()->id());
+ return GetKeyframeEffect()->element_id();
}
void SingleKeyframeEffectAnimation::AttachElement(ElementId element_id) {
diff --git a/chromium/cc/animation/timing_function.cc b/chromium/cc/animation/timing_function.cc
index 6b6110d986a..1c80aeeb28d 100644
--- a/chromium/cc/animation/timing_function.cc
+++ b/chromium/cc/animation/timing_function.cc
@@ -85,7 +85,7 @@ TimingFunction::Type StepsTimingFunction::GetType() const {
}
double StepsTimingFunction::GetValue(double t) const {
- return GetPreciseValue(t);
+ return GetPreciseValue(t, TimingFunction::LimitDirection::RIGHT);
}
std::unique_ptr<TimingFunction> StepsTimingFunction::Clone() const {
@@ -96,9 +96,15 @@ double StepsTimingFunction::Velocity(double x) const {
return 0;
}
-double StepsTimingFunction::GetPreciseValue(double t) const {
+double StepsTimingFunction::GetPreciseValue(double t,
+ LimitDirection direction) const {
const double steps = static_cast<double>(steps_);
double current_step = std::floor((steps * t) + GetStepsStartOffset());
+ // Adjust step if using a left limit at a discontinuous step boundary.
+ if (direction == LimitDirection::LEFT &&
+ steps * t - std::floor(steps * t) == 0) {
+ current_step -= 1;
+ }
if (t >= 0 && current_step < 0)
current_step = 0;
if (t <= 1 && current_step > steps)
@@ -118,36 +124,4 @@ float StepsTimingFunction::GetStepsStartOffset() const {
}
}
-std::unique_ptr<FramesTimingFunction> FramesTimingFunction::Create(int frames) {
- return base::WrapUnique(new FramesTimingFunction(frames));
-}
-
-FramesTimingFunction::FramesTimingFunction(int frames) : frames_(frames) {}
-
-FramesTimingFunction::~FramesTimingFunction() = default;
-
-TimingFunction::Type FramesTimingFunction::GetType() const {
- return Type::FRAMES;
-}
-
-double FramesTimingFunction::GetValue(double t) const {
- return GetPreciseValue(t);
-}
-
-std::unique_ptr<TimingFunction> FramesTimingFunction::Clone() const {
- return base::WrapUnique(new FramesTimingFunction(*this));
-}
-
-double FramesTimingFunction::Velocity(double x) const {
- return 0;
-}
-
-double FramesTimingFunction::GetPreciseValue(double t) const {
- const double frames = static_cast<double>(frames_);
- double output_progress = std::floor(frames * t) / (frames - 1);
- if (t <= 1 && output_progress > 1)
- output_progress = 1;
- return output_progress;
-}
-
} // namespace cc
diff --git a/chromium/cc/animation/timing_function.h b/chromium/cc/animation/timing_function.h
index 77969ac4188..4212bb28864 100644
--- a/chromium/cc/animation/timing_function.h
+++ b/chromium/cc/animation/timing_function.h
@@ -20,7 +20,10 @@ class CC_ANIMATION_EXPORT TimingFunction {
TimingFunction& operator=(const TimingFunction&) = delete;
// Note that LINEAR is a nullptr TimingFunction (for now).
- enum class Type { LINEAR, CUBIC_BEZIER, STEPS, FRAMES };
+ enum class Type { LINEAR, CUBIC_BEZIER, STEPS };
+
+ // Which limit to apply at a discontinuous boundary.
+ enum class LimitDirection { LEFT, RIGHT };
virtual Type GetType() const = 0;
virtual double GetValue(double t) const = 0;
@@ -87,7 +90,7 @@ class CC_ANIMATION_EXPORT StepsTimingFunction : public TimingFunction {
int steps() const { return steps_; }
StepPosition step_position() const { return step_position_; }
- double GetPreciseValue(double t) const;
+ double GetPreciseValue(double t, LimitDirection limit_direction) const;
private:
StepsTimingFunction(int steps, StepPosition step_position);
@@ -98,28 +101,6 @@ class CC_ANIMATION_EXPORT StepsTimingFunction : public TimingFunction {
StepPosition step_position_;
};
-class CC_ANIMATION_EXPORT FramesTimingFunction : public TimingFunction {
- public:
- static std::unique_ptr<FramesTimingFunction> Create(int frames);
- ~FramesTimingFunction() override;
-
- FramesTimingFunction& operator=(const FramesTimingFunction&) = delete;
-
- // TimingFunction implementation.
- Type GetType() const override;
- double GetValue(double t) const override;
- std::unique_ptr<TimingFunction> Clone() const override;
- double Velocity(double time) const override;
-
- int frames() const { return frames_; }
- double GetPreciseValue(double t) const;
-
- private:
- explicit FramesTimingFunction(int frames);
-
- int frames_;
-};
-
} // namespace cc
#endif // CC_ANIMATION_TIMING_FUNCTION_H_
diff --git a/chromium/cc/animation/worklet_animation.cc b/chromium/cc/animation/worklet_animation.cc
index 09f4de569cb..a6d109fac1b 100644
--- a/chromium/cc/animation/worklet_animation.cc
+++ b/chromium/cc/animation/worklet_animation.cc
@@ -8,6 +8,7 @@
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/keyframe_effect.h"
#include "cc/animation/scroll_timeline.h"
+#include "cc/trees/animation_effect_timings.h"
#include "cc/trees/animation_options.h"
namespace cc {
@@ -19,6 +20,7 @@ WorkletAnimation::WorkletAnimation(
double playback_rate,
std::unique_ptr<ScrollTimeline> scroll_timeline,
std::unique_ptr<AnimationOptions> options,
+ std::unique_ptr<AnimationEffectTimings> effect_timings,
bool is_controlling_instance)
: WorkletAnimation(cc_animation_id,
worklet_animation_id,
@@ -26,6 +28,7 @@ WorkletAnimation::WorkletAnimation(
playback_rate,
std::move(scroll_timeline),
std::move(options),
+ std::move(effect_timings),
is_controlling_instance,
nullptr) {}
@@ -36,6 +39,7 @@ WorkletAnimation::WorkletAnimation(
double playback_rate,
std::unique_ptr<ScrollTimeline> scroll_timeline,
std::unique_ptr<AnimationOptions> options,
+ std::unique_ptr<AnimationEffectTimings> effect_timings,
bool is_controlling_instance,
std::unique_ptr<KeyframeEffect> effect)
: SingleKeyframeEffectAnimation(cc_animation_id, std::move(effect)),
@@ -44,9 +48,11 @@ WorkletAnimation::WorkletAnimation(
scroll_timeline_(std::move(scroll_timeline)),
playback_rate_(playback_rate),
options_(std::move(options)),
+ effect_timings_(std::move(effect_timings)),
local_time_(base::nullopt),
start_time_(base::nullopt),
last_current_time_(base::nullopt),
+ has_pending_tree_lock_(false),
state_(State::PENDING),
is_impl_instance_(is_controlling_instance) {}
@@ -57,10 +63,12 @@ scoped_refptr<WorkletAnimation> WorkletAnimation::Create(
const std::string& name,
double playback_rate,
std::unique_ptr<ScrollTimeline> scroll_timeline,
- std::unique_ptr<AnimationOptions> options) {
+ std::unique_ptr<AnimationOptions> options,
+ std::unique_ptr<AnimationEffectTimings> effect_timings) {
return WrapRefCounted(new WorkletAnimation(
AnimationIdProvider::NextAnimationId(), worklet_animation_id, name,
- playback_rate, std::move(scroll_timeline), std::move(options), false));
+ playback_rate, std::move(scroll_timeline), std::move(options),
+ std::move(effect_timings), false));
}
scoped_refptr<Animation> WorkletAnimation::CreateImplInstance() const {
@@ -68,9 +76,9 @@ scoped_refptr<Animation> WorkletAnimation::CreateImplInstance() const {
if (scroll_timeline_)
impl_timeline = scroll_timeline_->CreateImplInstance();
- return WrapRefCounted(
- new WorkletAnimation(id(), worklet_animation_id_, name(), playback_rate_,
- std::move(impl_timeline), CloneOptions(), true));
+ return WrapRefCounted(new WorkletAnimation(
+ id(), worklet_animation_id_, name(), playback_rate_,
+ std::move(impl_timeline), CloneOptions(), CloneEffectTimings(), true));
}
void WorkletAnimation::PushPropertiesTo(Animation* animation_impl) {
@@ -103,37 +111,61 @@ void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
bool is_active_tree) {
+ bool is_timeline_active = IsTimelineActive(scroll_tree, is_active_tree);
// Record the monotonic time to be the start time first time state is
// generated. This time is used as the origin for computing the current time.
// The start time of scroll-linked animations is always initialized to zero.
// See: https://github.com/w3c/csswg-drafts/issues/2075
- if (!start_time_.has_value())
+ // To stay consistent with blink::WorkletAnimation, record start time only
+ // when the timeline becomes active.
+ if (!start_time_.has_value() && is_timeline_active)
start_time_ = scroll_timeline_ ? base::TimeTicks() : monotonic_time;
+ if (is_active_tree && has_pending_tree_lock_)
+ return;
+
// Skip running worklet animations with unchanged input time and reuse
// their value from the previous animation call.
if (!NeedsUpdate(monotonic_time, scroll_tree, is_active_tree))
return;
- double current_time =
+ DCHECK(is_timeline_active || state_ == State::REMOVED);
+
+ base::Optional<base::TimeDelta> current_time =
CurrentTime(monotonic_time, scroll_tree, is_active_tree);
- // TODO(yigu): If current_time becomes newly unresolved and last_current_time_
- // is resolved, we apply the last current time to the animation if the scroll
- // timeline becomes newly inactive. See https://crbug.com/906050.
+
+ // When the timeline is inactive (only the case with scroll timelines), the
+ // animation holds its last current time and last current output. This
+ // means we don't need to produce any new input state. See also:
+ // https://drafts.csswg.org/web-animations/#responding-to-a-newly-inactive-timeline
+ if (!is_timeline_active)
+ current_time = last_current_time_;
+
+ if (!current_time)
+ return;
last_current_time_ = current_time;
+ // Prevent active tree mutations from queuing up until pending tree is
+ // activated to preserve flow of time for scroll timelines.
+ has_pending_tree_lock_ = !is_active_tree && scroll_timeline_;
+
switch (state_) {
case State::PENDING:
// TODO(yigu): cc side WorkletAnimation is only capable of handling single
// keyframe effect at the moment. We should pass in the number of effects
// once Worklet Group Effect is fully implemented in cc.
// https://crbug.com/767043.
- input_state->Add({worklet_animation_id(), name(), current_time,
- CloneOptions(), 1 /* num_effects */});
+ input_state->Add({worklet_animation_id(), name(),
+ current_time->InMillisecondsF(), CloneOptions(),
+ CloneEffectTimings()});
state_ = State::RUNNING;
break;
case State::RUNNING:
- input_state->Update({worklet_animation_id(), current_time});
+ // TODO(jortaylo): EffectTimings need to be sent to the worklet during
+ // updates, otherwise the timing info will become outdated.
+ // https://crbug.com/915344.
+ input_state->Update(
+ {worklet_animation_id(), current_time->InMillisecondsF()});
break;
case State::REMOVED:
input_state->Remove(worklet_animation_id());
@@ -160,8 +192,7 @@ void WorkletAnimation::SetPlaybackRate(double playback_rate) {
if (start_time_ && last_current_time_) {
// Update startTime in order to maintain previous currentTime and,
// as a result, prevent the animation from jumping.
- base::TimeDelta current_time =
- base::TimeDelta::FromMillisecondsD(last_current_time_.value());
+ base::TimeDelta current_time = last_current_time_.value();
start_time_ = start_time_.value() + current_time / playback_rate_ -
current_time / playback_rate;
}
@@ -175,41 +206,47 @@ void WorkletAnimation::UpdatePlaybackRate(double playback_rate) {
SetNeedsPushProperties();
}
-double WorkletAnimation::CurrentTime(base::TimeTicks monotonic_time,
- const ScrollTree& scroll_tree,
- bool is_active_tree) {
+base::Optional<base::TimeDelta> WorkletAnimation::CurrentTime(
+ base::TimeTicks monotonic_time,
+ const ScrollTree& scroll_tree,
+ bool is_active_tree) {
+ DCHECK(IsTimelineActive(scroll_tree, is_active_tree));
base::TimeTicks timeline_time;
if (scroll_timeline_) {
base::Optional<base::TimeTicks> scroll_monotonic_time =
scroll_timeline_->CurrentTime(scroll_tree, is_active_tree);
if (!scroll_monotonic_time)
- return std::numeric_limits<double>::quiet_NaN();
+ return base::nullopt;
timeline_time = scroll_monotonic_time.value();
} else {
timeline_time = monotonic_time;
}
- return (timeline_time - start_time_.value()).InMillisecondsF() *
- playback_rate_;
+ return (timeline_time - start_time_.value()) * playback_rate_;
}
bool WorkletAnimation::NeedsUpdate(base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
bool is_active_tree) {
- // If we don't have a start time it means that an update was never sent to
- // the worklet therefore we need one.
- if (!start_time_.has_value())
- return true;
-
- DCHECK(state_ == State::PENDING || last_current_time_.has_value());
if (state_ == State::REMOVED)
return true;
- double current_time =
+ // When the timeline is inactive we apply the last current time to the
+ // animation.
+ if (!IsTimelineActive(scroll_tree, is_active_tree))
+ return false;
+
+ base::Optional<base::TimeDelta> current_time =
CurrentTime(monotonic_time, scroll_tree, is_active_tree);
bool needs_update = last_current_time_ != current_time;
return needs_update;
}
+bool WorkletAnimation::IsTimelineActive(const ScrollTree& scroll_tree,
+ bool is_active_tree) const {
+ return !scroll_timeline_ ||
+ scroll_timeline_->IsActive(scroll_tree, is_active_tree);
+}
+
void WorkletAnimation::UpdateScrollTimeline(
base::Optional<ElementId> scroller_id,
base::Optional<double> start_scroll_offset,
@@ -225,6 +262,7 @@ void WorkletAnimation::UpdateScrollTimeline(
void WorkletAnimation::PromoteScrollTimelinePendingToActive() {
if (scroll_timeline_)
scroll_timeline_->PromoteScrollTimelinePendingToActive();
+ ReleasePendingTreeLock();
}
void WorkletAnimation::RemoveKeyframeModel(int keyframe_model_id) {
diff --git a/chromium/cc/animation/worklet_animation.h b/chromium/cc/animation/worklet_animation.h
index d558e1b9a8d..508c0be4cf4 100644
--- a/chromium/cc/animation/worklet_animation.h
+++ b/chromium/cc/animation/worklet_animation.h
@@ -20,6 +20,7 @@ FORWARD_DECLARE_TEST(WorkletAnimationTest, NonImplInstanceDoesNotTickKeyframe);
} // namespace
class AnimationOptions;
+class AnimationEffectTimings;
class ScrollTimeline;
// A WorkletAnimation is an animation that allows its animation
@@ -42,13 +43,15 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
double playback_rate,
std::unique_ptr<ScrollTimeline> scroll_timeline,
std::unique_ptr<AnimationOptions> options,
+ std::unique_ptr<AnimationEffectTimings> effect_timings,
bool is_controlling_instance);
static scoped_refptr<WorkletAnimation> Create(
WorkletAnimationId worklet_animation_id,
const std::string& name,
double playback_rate,
std::unique_ptr<ScrollTimeline> scroll_timeline,
- std::unique_ptr<AnimationOptions> options);
+ std::unique_ptr<AnimationOptions> options,
+ std::unique_ptr<AnimationEffectTimings> effect_timings);
scoped_refptr<Animation> CreateImplInstance() const override;
WorkletAnimationId worklet_animation_id() { return worklet_animation_id_; }
@@ -87,6 +90,8 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
void RemoveKeyframeModel(int keyframe_model_id) override;
+ void ReleasePendingTreeLock() { has_pending_tree_lock_ = false; }
+
private:
FRIEND_TEST_ALL_PREFIXES(WorkletAnimationTest,
NonImplInstanceDoesNotTickKeyframe);
@@ -96,16 +101,19 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
double playback_rate,
std::unique_ptr<ScrollTimeline> scroll_timeline,
std::unique_ptr<AnimationOptions> options,
+ std::unique_ptr<AnimationEffectTimings> effect_timings,
bool is_controlling_instance,
std::unique_ptr<KeyframeEffect> effect);
~WorkletAnimation() override;
// Returns the current time to be passed into the underlying AnimationWorklet.
- // The current time is based on the timeline associated with the animation.
- double CurrentTime(base::TimeTicks monotonic_time,
- const ScrollTree& scroll_tree,
- bool is_active_tree);
+ // The current time is based on the timeline associated with the animation and
+ // in case of scroll timeline it may be nullopt when the associated scrolling
+ // node is not available in the particular ScrollTree.
+ base::Optional<base::TimeDelta> CurrentTime(base::TimeTicks monotonic_time,
+ const ScrollTree& scroll_tree,
+ bool is_active_tree);
// Returns true if the worklet animation needs to be updated which happens iff
// its current time is going to be different from last time given these input.
@@ -117,10 +125,17 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
return options_ ? options_->Clone() : nullptr;
}
+ std::unique_ptr<AnimationEffectTimings> CloneEffectTimings() const {
+ return effect_timings_ ? effect_timings_->Clone() : nullptr;
+ }
+
// Updates the playback rate of the Impl thread instance.
// Called by the UI thread WorletAnimation instance during commit.
void SetPlaybackRate(double playback_rate);
+ bool IsTimelineActive(const ScrollTree& scroll_tree,
+ bool is_active_tree) const;
+
WorkletAnimationId worklet_animation_id_;
std::string name_;
@@ -142,6 +157,7 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
double playback_rate_;
std::unique_ptr<AnimationOptions> options_;
+ std::unique_ptr<AnimationEffectTimings> effect_timings_;
// Local time is used as an input to the keyframe effect of this animation.
// The value comes from the user script that runs inside the animation worklet
@@ -149,9 +165,16 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
base::Optional<base::TimeDelta> local_time_;
base::Optional<base::TimeTicks> start_time_;
- // Last current time used for updatig. We use this to skip updating if current
- // time has not changed since last update.
- base::Optional<double> last_current_time_;
+
+ // Last current time used for updating. We use this to skip updating if
+ // current time has not changed since last update.
+ base::Optional<base::TimeDelta> last_current_time_;
+
+ // To ensure that 'time' progresses forward for scroll animations, we guard
+ // against allowing active tree mutations while the pending tree has a
+ // lock in the worklet. The lock is established when updating the input state
+ // for the pending tree and release on pending tree activation.
+ bool has_pending_tree_lock_;
State state_;
diff --git a/chromium/cc/animation/worklet_animation_unittest.cc b/chromium/cc/animation/worklet_animation_unittest.cc
index a1801ac3674..4d0e61ea073 100644
--- a/chromium/cc/animation/worklet_animation_unittest.cc
+++ b/chromium/cc/animation/worklet_animation_unittest.cc
@@ -12,10 +12,12 @@
#include "cc/trees/property_tree.h"
#include "testing/gmock/include/gmock/gmock.h"
+using ::testing::_;
+using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
-using ::testing::_;
+using ::testing::Unused;
namespace cc {
@@ -33,11 +35,11 @@ class WorkletAnimationTest : public AnimationTimelinesTest {
~WorkletAnimationTest() override = default;
void AttachWorkletAnimation() {
- client_.RegisterElement(element_id_, ElementListType::ACTIVE);
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
worklet_animation_ = WrapRefCounted(
new WorkletAnimation(1, worklet_animation_id_, "test_name", 1, nullptr,
- nullptr, true /* controlling instance*/));
+ nullptr, nullptr, true /* controlling instance*/));
worklet_animation_->AttachElement(element_id_);
host_->AddAnimationTimeline(timeline_);
timeline_->AttachAnimation(worklet_animation_);
@@ -58,6 +60,7 @@ class MockScrollTimeline : public ScrollTimeline {
KeyframeModel::FillMode::NONE) {}
MOCK_CONST_METHOD2(CurrentTime,
base::Optional<base::TimeTicks>(const ScrollTree&, bool));
+ MOCK_CONST_METHOD2(IsActive, bool(const ScrollTree&, bool));
};
TEST_F(WorkletAnimationTest, NonImplInstanceDoesNotTickKeyframe) {
@@ -67,7 +70,7 @@ TEST_F(WorkletAnimationTest, NonImplInstanceDoesNotTickKeyframe) {
scoped_refptr<WorkletAnimation> worklet_animation =
WrapRefCounted(new WorkletAnimation(
- 1, worklet_animation_id_, "test_name", 1, nullptr, nullptr,
+ 1, worklet_animation_id_, "test_name", 1, nullptr, nullptr, nullptr,
false /* not impl instance*/, std::move(effect)));
EXPECT_CALL(*mock_effect, Tick(_)).Times(0);
@@ -111,12 +114,13 @@ TEST_F(WorkletAnimationTest, LocalTimeIsUsedWhenTicking) {
TEST_F(WorkletAnimationTest, CurrentTimeCorrectlyUsesScrollTimeline) {
auto scroll_timeline = std::make_unique<MockScrollTimeline>();
+ EXPECT_CALL(*scroll_timeline, IsActive(_, _)).WillRepeatedly(Return(true));
EXPECT_CALL(*scroll_timeline, CurrentTime(_, _))
.WillRepeatedly(Return(
(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1234))));
scoped_refptr<WorkletAnimation> worklet_animation =
WorkletAnimation::Create(worklet_animation_id_, "test_name", 1,
- std::move(scroll_timeline), nullptr);
+ std::move(scroll_timeline), nullptr, nullptr);
ScrollTree scroll_tree;
std::unique_ptr<MutatorInputState> state =
@@ -131,7 +135,7 @@ TEST_F(WorkletAnimationTest, CurrentTimeCorrectlyUsesScrollTimeline) {
TEST_F(WorkletAnimationTest,
CurrentTimeFromRegularTimelineIsOffsetByStartTime) {
scoped_refptr<WorkletAnimation> worklet_animation = WorkletAnimation::Create(
- worklet_animation_id_, "test_name", 1, nullptr, nullptr);
+ worklet_animation_id_, "test_name", 1, nullptr, nullptr, nullptr);
base::TimeTicks first_ticks =
base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111);
@@ -169,7 +173,7 @@ TEST_F(WorkletAnimationTest, DocumentTimelineSetPlaybackRate) {
const double playback_rate_half = 0.5;
scoped_refptr<WorkletAnimation> worklet_animation =
WorkletAnimation::Create(worklet_animation_id_, "test_name",
- playback_rate_double, nullptr, nullptr);
+ playback_rate_double, nullptr, nullptr, nullptr);
base::TimeTicks first_ticks =
base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111);
@@ -219,27 +223,24 @@ TEST_F(WorkletAnimationTest, ScrollTimelineSetPlaybackRate) {
const double playback_rate_half = 0.5;
auto scroll_timeline = std::make_unique<MockScrollTimeline>();
- EXPECT_CALL(*scroll_timeline, CurrentTime(_, _))
- // First UpdateInputState call.
- .WillOnce(
- Return(base::TimeTicks() + base::TimeDelta::FromMilliseconds(50)))
- // First UpdateInputState call.
- .WillOnce(
- Return(base::TimeTicks() + base::TimeDelta::FromMilliseconds(50)))
- // Second UpdateInputState call.
- .WillRepeatedly(
- Return(base::TimeTicks() + base::TimeDelta::FromMilliseconds(100)));
-
scoped_refptr<WorkletAnimation> worklet_animation = WorkletAnimation::Create(
worklet_animation_id_, "test_name", playback_rate_double,
- std::move(scroll_timeline), nullptr);
+ std::move(scroll_timeline), nullptr, nullptr);
+ const MockScrollTimeline* mock_timeline =
+ static_cast<const MockScrollTimeline*>(
+ worklet_animation->scroll_timeline());
ScrollTree scroll_tree;
std::unique_ptr<MutatorInputState> state =
std::make_unique<MutatorInputState>();
// Start the animation.
+ EXPECT_CALL(*mock_timeline, IsActive(_, _)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_timeline, CurrentTime(_, _))
+ .WillRepeatedly(
+ Return(base::TimeTicks() + base::TimeDelta::FromMilliseconds(50)));
worklet_animation->UpdateInputState(state.get(), base::TimeTicks(),
scroll_tree, true);
+ Mock::VerifyAndClearExpectations(&mock_timeline);
std::unique_ptr<AnimationWorkletInput> input =
state->TakeWorkletState(worklet_animation_id_.worklet_id);
@@ -253,8 +254,13 @@ TEST_F(WorkletAnimationTest, ScrollTimelineSetPlaybackRate) {
state.reset(new MutatorInputState());
// Continue playing the animation.
+ EXPECT_CALL(*mock_timeline, IsActive(_, _)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_timeline, CurrentTime(_, _))
+ .WillRepeatedly(
+ Return(base::TimeTicks() + base::TimeDelta::FromMilliseconds(100)));
worklet_animation->UpdateInputState(state.get(), base::TimeTicks(),
scroll_tree, true);
+ Mock::VerifyAndClearExpectations(&mock_timeline);
input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
// Verify that the current time is updated half as fast as the timeline time.
@@ -262,6 +268,59 @@ TEST_F(WorkletAnimationTest, ScrollTimelineSetPlaybackRate) {
input->updated_animations[0].current_time);
}
+// Verifies correcteness of worklet animation current time when inactive
+// timeline becomes active and then inactive again.
+TEST_F(WorkletAnimationTest, InactiveScrollTimeline) {
+ auto scroll_timeline = std::make_unique<MockScrollTimeline>();
+
+ scoped_refptr<WorkletAnimation> worklet_animation = WorkletAnimation::Create(
+ worklet_animation_id_, "test_name", /*playback_rate*/ 1,
+ std::move(scroll_timeline), nullptr, nullptr);
+
+ const MockScrollTimeline* mock_timeline =
+ static_cast<const MockScrollTimeline*>(
+ worklet_animation->scroll_timeline());
+ ScrollTree scroll_tree;
+ std::unique_ptr<MutatorInputState> state =
+ std::make_unique<MutatorInputState>();
+
+ // Start the animation with inactive timeline.
+ EXPECT_CALL(*mock_timeline, IsActive(_, _)).WillRepeatedly(Return(false));
+ worklet_animation->UpdateInputState(state.get(), base::TimeTicks(),
+ scroll_tree, true);
+ Mock::VerifyAndClearExpectations(&mock_timeline);
+ std::unique_ptr<AnimationWorkletInput> input =
+ state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ EXPECT_FALSE(input);
+ state.reset(new MutatorInputState());
+
+ // Now the timeline is active.
+ EXPECT_CALL(*mock_timeline, IsActive(_, _)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_timeline, CurrentTime(_, _))
+ .WillRepeatedly(
+ Return(base::TimeTicks() + base::TimeDelta::FromMilliseconds(100)));
+ worklet_animation->UpdateInputState(state.get(), base::TimeTicks(),
+ scroll_tree, true);
+ Mock::VerifyAndClearExpectations(&mock_timeline);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ // Verify that the current time is updated when the timeline becomes newly
+ // active.
+ EXPECT_EQ(100, input->added_and_updated_animations[0].current_time);
+ state.reset(new MutatorInputState());
+
+ // Now the timeline is inactive.
+ EXPECT_CALL(*mock_timeline, IsActive(_, _)).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mock_timeline, CurrentTime(_, _))
+ .WillRepeatedly(
+ Return(base::TimeTicks() + base::TimeDelta::FromMilliseconds(200)));
+ worklet_animation->UpdateInputState(state.get(), base::TimeTicks(),
+ scroll_tree, true);
+ Mock::VerifyAndClearExpectations(&mock_timeline);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ // No update of the input state when the timeline is inactive.
+ EXPECT_FALSE(input);
+}
+
// This test verifies that worklet animation state is properly updated.
TEST_F(WorkletAnimationTest, UpdateInputStateProducesCorrectState) {
AttachWorkletAnimation();
@@ -369,6 +428,63 @@ TEST_F(WorkletAnimationTest, SkipUnchangedAnimations) {
EXPECT_EQ(input->removed_animations.size(), 1u);
}
+base::Optional<base::TimeTicks> FakeIncreasingScrollTimelineTime(Unused,
+ Unused) {
+ static base::TimeTicks current_time;
+ current_time += base::TimeDelta::FromSecondsD(0.1);
+ return current_time;
+}
+
+// This test verifies that worklet animation gets skipped properly if a pending
+// mutation cycle is holding a lock on the worklet.
+TEST_F(WorkletAnimationTest, SkipLockedAnimations) {
+ auto scroll_timeline = std::make_unique<MockScrollTimeline>();
+ EXPECT_CALL(*scroll_timeline, IsActive(_, _)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*scroll_timeline, CurrentTime(_, _))
+ .WillRepeatedly(Invoke(FakeIncreasingScrollTimelineTime));
+ scoped_refptr<WorkletAnimation> worklet_animation =
+ WorkletAnimation::Create(worklet_animation_id_, "test_name", 1,
+ std::move(scroll_timeline), nullptr, nullptr);
+
+ ScrollTree scroll_tree;
+ std::unique_ptr<MutatorInputState> state =
+ std::make_unique<MutatorInputState>();
+
+ base::TimeTicks time;
+ worklet_animation->UpdateInputState(state.get(), time, scroll_tree, true);
+ std::unique_ptr<AnimationWorkletInput> input =
+ state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ EXPECT_EQ(input->added_and_updated_animations.size(), 1u);
+ EXPECT_EQ(input->updated_animations.size(), 0u);
+
+ state.reset(new MutatorInputState());
+ // Different scroll time causes the input state to be updated.
+ worklet_animation->UpdateInputState(state.get(), time, scroll_tree, true);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ EXPECT_EQ(input->updated_animations.size(), 1u);
+
+ state.reset(new MutatorInputState());
+ // Different scroll time causes the input state to be updated. Pending
+ // mutation will grab a lock.
+ worklet_animation->UpdateInputState(state.get(), time, scroll_tree, false);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ EXPECT_EQ(input->updated_animations.size(), 1u);
+
+ state.reset(new MutatorInputState());
+ // Pending lock has not been released.
+ worklet_animation->UpdateInputState(state.get(), time, scroll_tree, true);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ EXPECT_FALSE(input);
+
+ worklet_animation->ReleasePendingTreeLock();
+
+ state.reset(new MutatorInputState());
+ // Pending lock has been released.
+ worklet_animation->UpdateInputState(state.get(), time, scroll_tree, true);
+ input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
+ EXPECT_EQ(input->updated_animations.size(), 1u);
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/base/rtree.h b/chromium/cc/base/rtree.h
index 24909814298..83504eac64a 100644
--- a/chromium/cc/base/rtree.h
+++ b/chromium/cc/base/rtree.h
@@ -230,60 +230,54 @@ auto RTree<T>::BuildRecursive(std::vector<Branch<T>>* branches, int level)
remainder = kMinChildren - remainder;
}
- int num_strips = static_cast<int>(std::ceil(std::sqrt(num_branches)));
- int num_tiles = static_cast<int>(
- std::ceil(num_branches / static_cast<float>(num_strips)));
size_t current_branch = 0;
size_t new_branch_index = 0;
- for (int i = 0; i < num_strips; ++i) {
- // Might be worth sorting by X here too.
- for (int j = 0; j < num_tiles && current_branch < branches->size(); ++j) {
- int increment_by = kMaxChildren;
- if (remainder != 0) {
- // if need be, omit some nodes to make up for remainder
- if (remainder <= kMaxChildren - kMinChildren) {
- increment_by -= remainder;
- remainder = 0;
- } else {
- increment_by = kMinChildren;
- remainder -= kMaxChildren - kMinChildren;
- }
+ while (current_branch < branches->size()) {
+ int increment_by = kMaxChildren;
+ if (remainder != 0) {
+ // if need be, omit some nodes to make up for remainder
+ if (remainder <= kMaxChildren - kMinChildren) {
+ increment_by -= remainder;
+ remainder = 0;
+ } else {
+ increment_by = kMinChildren;
+ remainder -= kMaxChildren - kMinChildren;
}
- Node<T>* node = AllocateNodeAtLevel(level);
- node->num_children = 1;
- node->children[0] = (*branches)[current_branch];
-
- Branch<T> branch;
- branch.bounds = (*branches)[current_branch].bounds;
- branch.subtree = node;
+ }
+ Node<T>* node = AllocateNodeAtLevel(level);
+ node->num_children = 1;
+ node->children[0] = (*branches)[current_branch];
+
+ Branch<T> branch;
+ branch.bounds = (*branches)[current_branch].bounds;
+ branch.subtree = node;
+ ++current_branch;
+ int x = branch.bounds.x();
+ int y = branch.bounds.y();
+ int right = branch.bounds.right();
+ int bottom = branch.bounds.bottom();
+ for (int k = 1; k < increment_by && current_branch < branches->size();
+ ++k) {
+ // We use a custom union instead of gfx::Rect::Union here, since this
+ // bypasses some empty checks and extra setters, which improves
+ // performance.
+ auto& bounds = (*branches)[current_branch].bounds;
+ x = std::min(x, bounds.x());
+ y = std::min(y, bounds.y());
+ right = std::max(right, bounds.right());
+ bottom = std::max(bottom, bounds.bottom());
+
+ node->children[k] = (*branches)[current_branch];
+ ++node->num_children;
++current_branch;
- int x = branch.bounds.x();
- int y = branch.bounds.y();
- int right = branch.bounds.right();
- int bottom = branch.bounds.bottom();
- for (int k = 1; k < increment_by && current_branch < branches->size();
- ++k) {
- // We use a custom union instead of gfx::Rect::Union here, since this
- // bypasses some empty checks and extra setters, which improves
- // performance.
- auto& bounds = (*branches)[current_branch].bounds;
- x = std::min(x, bounds.x());
- y = std::min(y, bounds.y());
- right = std::max(right, bounds.right());
- bottom = std::max(bottom, bounds.bottom());
-
- node->children[k] = (*branches)[current_branch];
- ++node->num_children;
- ++current_branch;
- }
- branch.bounds.SetRect(x, y, base::ClampSub(right, x),
- base::ClampSub(bottom, y));
-
- DCHECK_LT(new_branch_index, current_branch);
- (*branches)[new_branch_index] = std::move(branch);
- ++new_branch_index;
}
+ branch.bounds.SetRect(x, y, base::ClampSub(right, x),
+ base::ClampSub(bottom, y));
+
+ DCHECK_LT(new_branch_index, current_branch);
+ (*branches)[new_branch_index] = std::move(branch);
+ ++new_branch_index;
}
branches->resize(new_branch_index);
return BuildRecursive(branches, level + 1);
diff --git a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
index 6f2da14d012..a1f8b53f202 100644
--- a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
+++ b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -65,8 +65,8 @@ void RunBenchmark(RasterSource* raster_source,
image_settings->images_to_skip = {};
image_settings->image_to_current_frame_index = {};
- PlaybackImageProvider image_provider(image_decode_cache,
- std::move(image_settings));
+ PlaybackImageProvider image_provider(
+ image_decode_cache, gfx::ColorSpace(), std::move(image_settings));
RasterSource::PlaybackSettings settings;
settings.image_provider = &image_provider;
diff --git a/chromium/cc/debug/layer_tree_debug_state.cc b/chromium/cc/debug/layer_tree_debug_state.cc
index 6b51ff0b6f5..8c154cc8f55 100644
--- a/chromium/cc/debug/layer_tree_debug_state.cc
+++ b/chromium/cc/debug/layer_tree_debug_state.cc
@@ -12,6 +12,7 @@ namespace cc {
LayerTreeDebugState::LayerTreeDebugState()
: show_fps_counter(false),
show_debug_borders(false),
+ show_layout_shift_regions(false),
show_paint_rects(false),
show_property_changed_rects(false),
show_surface_damage_rects(false),
@@ -49,7 +50,7 @@ bool LayerTreeDebugState::ShowHudRects() const {
show_surface_damage_rects || show_screen_space_rects ||
show_touch_event_handler_rects || show_wheel_event_handler_rects ||
show_scroll_event_handler_rects || show_non_fast_scrollable_rects ||
- show_layer_animation_bounds_rects;
+ show_layer_animation_bounds_rects || show_layout_shift_regions;
}
bool LayerTreeDebugState::ShowMemoryStats() const {
@@ -61,6 +62,7 @@ bool LayerTreeDebugState::Equal(const LayerTreeDebugState& a,
return (
a.show_fps_counter == b.show_fps_counter &&
a.show_debug_borders == b.show_debug_borders &&
+ a.show_layout_shift_regions == b.show_layout_shift_regions &&
a.show_paint_rects == b.show_paint_rects &&
a.show_property_changed_rects == b.show_property_changed_rects &&
a.show_surface_damage_rects == b.show_surface_damage_rects &&
@@ -85,6 +87,7 @@ LayerTreeDebugState LayerTreeDebugState::Unite(const LayerTreeDebugState& a,
r.show_fps_counter |= b.show_fps_counter;
r.show_debug_borders |= b.show_debug_borders;
+ r.show_layout_shift_regions |= b.show_layout_shift_regions;
r.show_paint_rects |= b.show_paint_rects;
r.show_property_changed_rects |= b.show_property_changed_rects;
r.show_surface_damage_rects |= b.show_surface_damage_rects;
diff --git a/chromium/cc/debug/layer_tree_debug_state.h b/chromium/cc/debug/layer_tree_debug_state.h
index c7438b6fe48..50dd2308edb 100644
--- a/chromium/cc/debug/layer_tree_debug_state.h
+++ b/chromium/cc/debug/layer_tree_debug_state.h
@@ -32,6 +32,7 @@ class CC_DEBUG_EXPORT LayerTreeDebugState {
bool show_fps_counter;
DebugBorderTypes show_debug_borders;
+ bool show_layout_shift_regions;
bool show_paint_rects;
bool show_property_changed_rects;
bool show_surface_damage_rects;
diff --git a/chromium/cc/input/event_listener_properties.h b/chromium/cc/input/event_listener_properties.h
index a66ee2e6c65..f8891fe17e5 100644
--- a/chromium/cc/input/event_listener_properties.h
+++ b/chromium/cc/input/event_listener_properties.h
@@ -8,8 +8,8 @@
namespace cc {
enum class EventListenerClass {
- // This includes the pointerrawmove events which are non-rAF-aligned.
- kPointerRawMove,
+ // This includes the pointerrawupdate events which are non-rAF-aligned.
+ kPointerRawUpdate,
// This value includes "touchstart", "touchmove", and "pointer" events.
kTouchStartOrMove,
// This value includes "wheel" and "mousewheel" events.
diff --git a/chromium/cc/input/input_handler.cc b/chromium/cc/input/input_handler.cc
index 7105340cbbe..60e08fc8f96 100644
--- a/chromium/cc/input/input_handler.cc
+++ b/chromium/cc/input/input_handler.cc
@@ -10,6 +10,8 @@ InputHandlerScrollResult::InputHandlerScrollResult()
: did_scroll(false), did_overscroll_root(false) {
}
-InputHandlerPointerResult::InputHandlerPointerResult() : type(kUnhandled) {}
+InputHandlerPointerResult::InputHandlerPointerResult()
+ : type(kUnhandled),
+ scroll_units(ui::input_types::ScrollGranularity::kScrollByPrecisePixel) {}
} // namespace cc
diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h
index 6b39c27ef56..0c41e257c7d 100644
--- a/chromium/cc/input/input_handler.h
+++ b/chromium/cc/input/input_handler.h
@@ -17,6 +17,7 @@
#include "cc/input/touch_action.h"
#include "cc/trees/element_id.h"
#include "cc/trees/swap_promise_monitor.h"
+#include "ui/events/types/scroll_types.h"
namespace gfx {
class Point;
@@ -41,6 +42,9 @@ struct CC_EXPORT InputHandlerPointerResult {
// the pointer event.
PointerResultType type;
+ // Tells what scroll_units should be used.
+ ui::input_types::ScrollGranularity scroll_units;
+
// If the input handler processed the event as a scrollbar scroll, it will
// return a gfx::ScrollOffset that produces the necessary scroll. However,
// it is still the client's responsibility to generate the gesture scrolls
@@ -48,9 +52,6 @@ struct CC_EXPORT InputHandlerPointerResult {
// pointer event (due to the latency attribution that happens at the
// InputHandlerProxy level).
gfx::ScrollOffset scroll_offset;
-
- // TODO(arakeri): Extend this structure to contain scroll_units and
- // element_id. For now, assume kPrecisePixels and root layer scroll.
};
struct CC_EXPORT InputHandlerScrollResult {
@@ -188,7 +189,8 @@ class CC_EXPORT InputHandler {
// ScrollBegin() returned SCROLL_STARTED.
virtual InputHandlerScrollResult ScrollBy(ScrollState* scroll_state) = 0;
- virtual void MouseMoveAt(const gfx::Point& mouse_position) = 0;
+ virtual InputHandlerPointerResult MouseMoveAt(
+ const gfx::Point& mouse_position) = 0;
virtual InputHandlerPointerResult MouseDown(
const gfx::PointF& mouse_position) = 0;
virtual InputHandlerPointerResult MouseUp(
@@ -204,9 +206,10 @@ class CC_EXPORT InputHandler {
virtual void RequestUpdateForSynchronousInputHandler() = 0;
// Called when the root scroll offset has been changed in the synchronous
- // input handler by the application (outside of input event handling).
+ // input handler by the application (outside of input event handling). Offset
+ // is expected in "content/page coordinates".
virtual void SetSynchronousInputHandlerRootScrollOffset(
- const gfx::ScrollOffset& root_offset) = 0;
+ const gfx::ScrollOffset& root_content_offset) = 0;
virtual void PinchGestureBegin() = 0;
virtual void PinchGestureUpdate(float magnify_delta,
diff --git a/chromium/cc/input/scroll_snap_data.cc b/chromium/cc/input/scroll_snap_data.cc
index b09ded1e84f..2121d1ca658 100644
--- a/chromium/cc/input/scroll_snap_data.cc
+++ b/chromium/cc/input/scroll_snap_data.cc
@@ -112,6 +112,9 @@ void SnapContainerData::AddSnapAreaData(SnapAreaData snap_area_data) {
bool SnapContainerData::FindSnapPosition(
const SnapSelectionStrategy& strategy,
gfx::ScrollOffset* snap_position) const {
+ if (scroll_snap_type_.is_none)
+ return false;
+
gfx::ScrollOffset base_position = strategy.base_position();
SnapAxis axis = scroll_snap_type_.axis;
bool should_snap_on_x = strategy.ShouldSnapOnX() &&
diff --git a/chromium/cc/input/scroll_snap_data.h b/chromium/cc/input/scroll_snap_data.h
index 9938c0b7486..f68d90320c9 100644
--- a/chromium/cc/input/scroll_snap_data.h
+++ b/chromium/cc/input/scroll_snap_data.h
@@ -154,11 +154,15 @@ struct SnapAreaData {
typedef std::vector<SnapAreaData> SnapAreaList;
-// Snap container is a scroll container that has non-'none' value for
-// scroll-snap-type. It can be snapped to one of its snap areas when a scroll
-// happens.
+// Snap container is a scroll container that at least one snap area assigned to
+// it. If the snap-type is not 'none', then it can be snapped to one of its
+// snap areas when a scroll happens.
// This data structure describes the data needed for SnapCoordinator to perform
// snapping in the snap container.
+//
+// Note that the snap area data should only be used when snap-type is not 'none'
+// There is not guarantee that this information is up-to-date otherwise. In
+// fact, we skip updating these info as an optiomization.
class CC_EXPORT SnapContainerData {
public:
SnapContainerData();
diff --git a/chromium/cc/input/scrollbar.h b/chromium/cc/input/scrollbar.h
index bd785ff779b..ec23fef5f0d 100644
--- a/chromium/cc/input/scrollbar.h
+++ b/chromium/cc/input/scrollbar.h
@@ -11,6 +11,7 @@
#include "ui/gfx/geometry/rect.h"
static const int kPixelsPerLineStep = 40;
+static const float kMinFractionToStepWhenPaging = 0.875f;
namespace cc {
@@ -23,7 +24,9 @@ enum ScrollbarPart {
TICKMARKS,
BACK_BUTTON,
FORWARD_BUTTON,
- NO_PART
+ BACK_TRACK,
+ FORWARD_TRACK,
+ NO_PART,
};
class Scrollbar {
diff --git a/chromium/cc/input/scrollbar_controller.cc b/chromium/cc/input/scrollbar_controller.cc
index 403d3ceaaf8..d29a2574cc6 100644
--- a/chromium/cc/input/scrollbar_controller.cc
+++ b/chromium/cc/input/scrollbar_controller.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "cc/base/math_util.h"
#include "cc/input/scrollbar.h"
#include "cc/input/scrollbar_controller.h"
#include "cc/trees/layer_tree_impl.h"
@@ -14,7 +15,10 @@ namespace cc {
ScrollbarController::ScrollbarController(
LayerTreeHostImpl* layer_tree_host_impl)
: layer_tree_host_impl_(layer_tree_host_impl),
- scrollbar_scroll_is_active_(false) {}
+ scrollbar_scroll_is_active_(false),
+ thumb_drag_in_progress_(false),
+ currently_captured_scrollbar_(nullptr),
+ previous_pointer_position_(gfx::PointF(0, 0)) {}
// Performs hit test and prepares scroll deltas that will be used by GSB and
// GSU.
@@ -22,12 +26,115 @@ InputHandlerPointerResult ScrollbarController::HandleMouseDown(
const gfx::PointF position_in_widget) {
InputHandlerPointerResult scroll_result;
LayerImpl* layer_impl = GetLayerHitByPoint(position_in_widget);
- if (layer_impl && layer_impl->is_scrollbar()) {
- scrollbar_scroll_is_active_ = true;
- scroll_result.type = PointerResultType::kScrollbarScroll;
- scroll_result.scroll_offset =
- GetScrollStateBasedOnHitTest(layer_impl, position_in_widget);
+
+ // If a non-custom scrollbar layer was not found, we return early as there is
+ // no point in setting additional state in the ScrollbarController.
+ if (!(layer_impl && layer_impl->ToScrollbarLayer()))
+ return scroll_result;
+
+ currently_captured_scrollbar_ = layer_impl->ToScrollbarLayer();
+ scroll_result.type = PointerResultType::kScrollbarScroll;
+ layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
+ scroll_result.scroll_offset =
+ GetScrollDeltaFromPointerDown(position_in_widget);
+ previous_pointer_position_ = position_in_widget;
+ scrollbar_scroll_is_active_ = true;
+ if (thumb_drag_in_progress_) {
+ scroll_result.scroll_units =
+ ui::input_types::ScrollGranularity::kScrollByPrecisePixel;
+ } else {
+ // TODO(arakeri): This needs to be updated to kLine once cc implements
+ // handling it. crbug.com/959441
+ scroll_result.scroll_units =
+ ui::input_types::ScrollGranularity::kScrollByPixel;
}
+
+ return scroll_result;
+}
+
+// Performs hit test and prepares scroll deltas that will be used by GSU.
+InputHandlerPointerResult ScrollbarController::HandleMouseMove(
+ const gfx::PointF position_in_widget) {
+ InputHandlerPointerResult scroll_result;
+ if (!thumb_drag_in_progress_)
+ return scroll_result;
+
+ scroll_result.type = PointerResultType::kScrollbarScroll;
+ const ScrollbarOrientation orientation =
+ currently_captured_scrollbar_->orientation();
+ if (orientation == ScrollbarOrientation::VERTICAL)
+ scroll_result.scroll_offset.set_y(position_in_widget.y() -
+ previous_pointer_position_.y());
+ else
+ scroll_result.scroll_offset.set_x(position_in_widget.x() -
+ previous_pointer_position_.x());
+
+ LayerImpl* owner_scroll_layer =
+ layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId(
+ currently_captured_scrollbar_->scroll_element_id());
+
+ // Calculating the delta by which the scroller layer should move when
+ // dragging the thumb depends on the following factors:
+ // - scrollbar_track_length
+ // - scrollbar_thumb_length
+ // - scroll_layer_length
+ // - viewport_length
+ // - device_scale_factor
+ // - position_in_widget
+ //
+ // When a thumb drag is in progress, for every pixel that the pointer moves,
+ // the delta for the corresponding scroll_layer needs to be scaled by the
+ // following ratio:
+ // scaled_scroller_to_scrollbar_ratio =
+ // (scroll_layer_length - viewport_length) /
+ // (scrollbar_track_length - scrollbar_thumb_length)
+ //
+ // |<--------------------- scroll_layer_length -------------------------->|
+ //
+ // +------------------------------------------------+......................
+ // | | .
+ // |<-------------- viewport_length --------------->| .
+ // | | .
+ // | | .
+ // | | .
+ // | | .
+ // | | .
+ // | | .
+ // | | .
+ // | | .
+ // | | .
+ // | |<------- scrollbar_track_length --------->| | .
+ // | | .
+ // +--+-----+----------------------------+-------+--+......................
+ // |<|| |############################| ||>|
+ // +--+-----+----------------------------+-------+--+
+ //
+ // |<- scrollbar_thumb_length ->|
+ //
+ layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
+ float scroll_layer_length =
+ currently_captured_scrollbar_->scroll_layer_length();
+ float scrollbar_track_length = currently_captured_scrollbar_->TrackLength();
+ gfx::Rect thumb_rect(currently_captured_scrollbar_->ComputeThumbQuadRect());
+ float scrollbar_thumb_length = orientation == ScrollbarOrientation::VERTICAL
+ ? thumb_rect.height()
+ : thumb_rect.width();
+
+ float viewport_length =
+ orientation == ScrollbarOrientation::VERTICAL
+ ? owner_scroll_layer->scroll_container_bounds().height()
+ : (owner_scroll_layer->scroll_container_bounds().width());
+ float scaled_scroller_to_scrollbar_ratio =
+ ((scroll_layer_length - viewport_length) /
+ (scrollbar_track_length - scrollbar_thumb_length)) *
+ layer_tree_host_impl_->active_tree()->device_scale_factor();
+ scroll_result.scroll_offset.Scale(scaled_scroller_to_scrollbar_ratio);
+ previous_pointer_position_ = position_in_widget;
+ // Thumb drags have more granularity and are purely dependent on the pointer
+ // movement. Hence we use kPrecisePixel when dragging the thumb.
+ scroll_result.scroll_units =
+ ui::input_types::ScrollGranularity::kScrollByPrecisePixel;
+
return scroll_result;
}
@@ -39,6 +146,7 @@ InputHandlerPointerResult ScrollbarController::HandleMouseUp(
scrollbar_scroll_is_active_ = false;
scroll_result.type = PointerResultType::kScrollbarScroll;
}
+ thumb_drag_in_progress_ = false;
return scroll_result;
}
@@ -57,20 +165,62 @@ LayerImpl* ScrollbarController::GetLayerHitByPoint(
return layer_impl;
}
+int ScrollbarController::GetScrollDeltaForScrollbarPart(
+ ScrollbarPart scrollbar_part) {
+ int scroll_delta = 0;
+ int viewport_length = 0;
+ LayerImpl* owner_scroll_layer = nullptr;
+
+ switch (scrollbar_part) {
+ case ScrollbarPart::BACK_BUTTON:
+ case ScrollbarPart::FORWARD_BUTTON:
+ scroll_delta = kPixelsPerLineStep;
+ break;
+ case ScrollbarPart::BACK_TRACK:
+ case ScrollbarPart::FORWARD_TRACK:
+ owner_scroll_layer =
+ layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId(
+ currently_captured_scrollbar_->scroll_element_id());
+ viewport_length =
+ currently_captured_scrollbar_->orientation() ==
+ ScrollbarOrientation::VERTICAL
+ ? owner_scroll_layer->scroll_container_bounds().height()
+ : (owner_scroll_layer->scroll_container_bounds().width());
+ scroll_delta = viewport_length * kMinFractionToStepWhenPaging;
+ break;
+ default:
+ scroll_delta = 0;
+ }
+ return scroll_delta *
+ layer_tree_host_impl_->active_tree()->device_scale_factor();
+}
+
// Determines the scroll offsets based on hit test results.
-gfx::ScrollOffset ScrollbarController::GetScrollStateBasedOnHitTest(
- const LayerImpl* scrollbar_layer_impl,
+gfx::ScrollOffset ScrollbarController::GetScrollDeltaFromPointerDown(
const gfx::PointF position_in_widget) {
- const ScrollbarLayerImplBase* scrollbar_layer =
- static_cast<const ScrollbarLayerImplBase*>(scrollbar_layer_impl);
- const ScrollbarOrientation orientation = scrollbar_layer->orientation();
+ const ScrollbarOrientation orientation =
+ currently_captured_scrollbar_->orientation();
- ScrollbarPart scrollbar_part =
- scrollbar_layer->IdentifyScrollbarPart(position_in_widget);
+ // position_in_widget needs to be transformed and made relative to the
+ // scrollbar layer because hit testing assumes layer relative coordinates.
+ ScrollbarPart scrollbar_part = ScrollbarPart::NO_PART;
+ gfx::Transform inverse_screen_space_transform(
+ gfx::Transform::kSkipInitialization);
+ if (!currently_captured_scrollbar_->ScreenSpaceTransform().GetInverse(
+ &inverse_screen_space_transform))
+ return gfx::ScrollOffset(0, 0);
- float scroll_delta =
- layer_tree_host_impl_->active_tree()->device_scale_factor() *
- kPixelsPerLineStep;
+ bool clipped;
+ gfx::PointF scroller_relative_position(MathUtil::ProjectPoint(
+ inverse_screen_space_transform, position_in_widget, &clipped));
+
+ if (clipped)
+ return gfx::ScrollOffset(0, 0);
+
+ scrollbar_part = currently_captured_scrollbar_->IdentifyScrollbarPart(
+ scroller_relative_position);
+
+ float scroll_delta = GetScrollDeltaForScrollbarPart(scrollbar_part);
// See CreateScrollStateForGesture for more information on how these values
// will be interpreted.
@@ -82,7 +232,19 @@ gfx::ScrollOffset ScrollbarController::GetScrollStateBasedOnHitTest(
return orientation == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, scroll_delta) // Down arrow
: gfx::ScrollOffset(scroll_delta, 0); // Right arrow
+ } else if (scrollbar_part == ScrollbarPart::THUMB) {
+ // Offsets are calculated in HandleMouseMove.
+ thumb_drag_in_progress_ = true;
+ } else if (scrollbar_part == ScrollbarPart::BACK_TRACK) {
+ return orientation == ScrollbarOrientation::VERTICAL
+ ? gfx::ScrollOffset(0, -scroll_delta) // Track click up
+ : gfx::ScrollOffset(-scroll_delta, 0); // Track click left
+ } else if (scrollbar_part == ScrollbarPart::FORWARD_TRACK) {
+ return orientation == ScrollbarOrientation::VERTICAL
+ ? gfx::ScrollOffset(0, scroll_delta) // Track click down
+ : gfx::ScrollOffset(scroll_delta, 0); // Track click right
}
+
return gfx::ScrollOffset(0, 0);
}
diff --git a/chromium/cc/input/scrollbar_controller.h b/chromium/cc/input/scrollbar_controller.h
index 0434f78bd11..3ce462461bf 100644
--- a/chromium/cc/input/scrollbar_controller.h
+++ b/chromium/cc/input/scrollbar_controller.h
@@ -22,17 +22,31 @@ class CC_EXPORT ScrollbarController {
InputHandlerPointerResult HandleMouseDown(
const gfx::PointF position_in_widget);
+ InputHandlerPointerResult HandleMouseMove(
+ const gfx::PointF position_in_widget);
InputHandlerPointerResult HandleMouseUp(const gfx::PointF position_in_widget);
private:
// Returns a gfx::ScrollOffset object which contains scroll deltas for the
// synthetic Gesture events.
- gfx::ScrollOffset GetScrollStateBasedOnHitTest(
- const LayerImpl* scrollbar_layer_impl,
+ gfx::ScrollOffset GetScrollDeltaFromPointerDown(
const gfx::PointF position_in_widget);
LayerImpl* GetLayerHitByPoint(const gfx::PointF position_in_widget);
+ int GetScrollDeltaForScrollbarPart(ScrollbarPart scrollbar_part);
+
LayerTreeHostImpl* layer_tree_host_impl_;
+
+ // Used to safeguard against firing GSE without firing GSB and GSU. For
+ // example, if mouse is pressed outside the scrollbar but released after
+ // moving inside the scrollbar, a GSE will get queued up without this flag.
bool scrollbar_scroll_is_active_;
+
+ // Used to tell if the scrollbar thumb is getting dragged.
+ bool thumb_drag_in_progress_;
+ const ScrollbarLayerImplBase* currently_captured_scrollbar_;
+
+ // This is relative to the RenderWidget's origin.
+ gfx::PointF previous_pointer_position_;
};
} // namespace cc
diff --git a/chromium/cc/input/snap_fling_controller_unittest.cc b/chromium/cc/input/snap_fling_controller_unittest.cc
index 5deb03cb565..ebbf5b18cfd 100644
--- a/chromium/cc/input/snap_fling_controller_unittest.cc
+++ b/chromium/cc/input/snap_fling_controller_unittest.cc
@@ -77,9 +77,10 @@ TEST_F(SnapFlingControllerTest, CreatesAndAnimatesCurveOnFirstInertialGSU) {
EXPECT_CALL(mock_client_,
GetSnapFlingInfo(testing::_, testing::_, testing::_))
- .WillOnce(DoAll(testing::SetArgPointee<1>(gfx::Vector2dF(0, 0)),
- testing::SetArgPointee<2>(gfx::Vector2dF(0, 100)),
- testing::Return(true)));
+ .WillOnce(
+ testing::DoAll(testing::SetArgPointee<1>(gfx::Vector2dF(0, 0)),
+ testing::SetArgPointee<2>(gfx::Vector2dF(0, 100)),
+ testing::Return(true)));
EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(1);
EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(1);
EXPECT_TRUE(controller_->HandleGestureScrollUpdate(gsu));
diff --git a/chromium/cc/layers/heads_up_display_layer.cc b/chromium/cc/layers/heads_up_display_layer.cc
index 6d7044e2703..e291e6ee99a 100644
--- a/chromium/cc/layers/heads_up_display_layer.cc
+++ b/chromium/cc/layers/heads_up_display_layer.cc
@@ -65,6 +65,15 @@ std::unique_ptr<LayerImpl> HeadsUpDisplayLayer::CreateLayerImpl(
return HeadsUpDisplayLayerImpl::Create(tree_impl, id());
}
+const std::vector<gfx::Rect>& HeadsUpDisplayLayer::LayoutShiftRects() const {
+ return layout_shift_rects_;
+}
+
+void HeadsUpDisplayLayer::SetLayoutShiftRects(
+ const std::vector<gfx::Rect>& rects) {
+ layout_shift_rects_ = rects;
+}
+
void HeadsUpDisplayLayer::PushPropertiesTo(LayerImpl* layer) {
Layer::PushPropertiesTo(layer);
TRACE_EVENT0("cc", "HeadsUpDisplayLayer::PushPropertiesTo");
@@ -72,6 +81,7 @@ void HeadsUpDisplayLayer::PushPropertiesTo(LayerImpl* layer) {
static_cast<HeadsUpDisplayLayerImpl*>(layer);
layer_impl->SetHUDTypeface(typeface_);
+ layer_impl->SetLayoutShiftRects(layout_shift_rects_);
}
} // namespace cc
diff --git a/chromium/cc/layers/heads_up_display_layer.h b/chromium/cc/layers/heads_up_display_layer.h
index 1337fb639fb..1dea4e99e44 100644
--- a/chromium/cc/layers/heads_up_display_layer.h
+++ b/chromium/cc/layers/heads_up_display_layer.h
@@ -12,6 +12,7 @@
#include "cc/layers/layer.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
+#include "ui/gfx/geometry/rect.h"
namespace cc {
@@ -25,6 +26,9 @@ class CC_EXPORT HeadsUpDisplayLayer : public Layer {
void UpdateLocationAndSize(const gfx::Size& device_viewport,
float device_scale_factor);
+ const std::vector<gfx::Rect>& LayoutShiftRects() const;
+ void SetLayoutShiftRects(const std::vector<gfx::Rect>& rects);
+
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
// Layer overrides.
@@ -38,6 +42,7 @@ class CC_EXPORT HeadsUpDisplayLayer : public Layer {
~HeadsUpDisplayLayer() override;
sk_sp<SkTypeface> typeface_;
+ std::vector<gfx::Rect> layout_shift_rects_;
};
} // namespace cc
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc
index 0a9ea808774..75431c15d8f 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl.cc
@@ -10,6 +10,7 @@
#include <algorithm>
#include <vector>
+#include "base/memory/shared_memory_mapping.h"
#include "base/numerics/safe_conversions.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
@@ -156,12 +157,12 @@ class HudSoftwareBacking : public ResourcePool::SoftwareBacking {
const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
uint64_t tracing_process_id,
int importance) const override {
- pmd->CreateSharedMemoryOwnershipEdge(
- buffer_dump_guid, shared_memory->mapped_id(), importance);
+ pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid,
+ shared_mapping.guid(), importance);
}
LayerTreeFrameSink* layer_tree_frame_sink;
- std::unique_ptr<base::SharedMemory> shared_memory;
+ base::WritableSharedMemoryMapping shared_mapping;
};
bool HeadsUpDisplayLayerImpl::WillDraw(
@@ -320,15 +321,14 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
auto backing = std::make_unique<HudSoftwareBacking>();
backing->layer_tree_frame_sink = layer_tree_frame_sink;
backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
- backing->shared_memory = viz::bitmap_allocation::AllocateMappedBitmap(
- pool_resource.size(), pool_resource.format());
+ base::MappedReadOnlyRegion mapped_region =
+ viz::bitmap_allocation::AllocateSharedBitmap(pool_resource.size(),
+ pool_resource.format());
+ backing->shared_mapping = std::move(mapped_region.mapping);
- mojo::ScopedSharedBufferHandle handle =
- viz::bitmap_allocation::DuplicateAndCloseMappedBitmap(
- backing->shared_memory.get(), pool_resource.size(),
- pool_resource.format());
- layer_tree_frame_sink->DidAllocateSharedBitmap(std::move(handle),
- backing->shared_bitmap_id);
+ layer_tree_frame_sink->DidAllocateSharedBitmap(
+ viz::bitmap_allocation::ToMojoHandle(std::move(mapped_region.region)),
+ backing->shared_bitmap_id);
pool_resource.set_software_backing(std::move(backing));
}
@@ -443,7 +443,7 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
auto* backing =
static_cast<HudSoftwareBacking*>(pool_resource.software_backing());
sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(
- info, backing->shared_memory->memory(), info.minRowBytes());
+ info, backing->shared_mapping.memory(), info.minRowBytes());
SkiaPaintCanvas canvas(surface->getCanvas());
DrawHudContents(&canvas);
@@ -514,6 +514,16 @@ void HeadsUpDisplayLayerImpl::SetHUDTypeface(sk_sp<SkTypeface> typeface) {
NoteLayerPropertyChanged();
}
+const std::vector<gfx::Rect>& HeadsUpDisplayLayerImpl::LayoutShiftRects()
+ const {
+ return layout_shift_rects_;
+}
+
+void HeadsUpDisplayLayerImpl::SetLayoutShiftRects(
+ const std::vector<gfx::Rect>& rects) {
+ layout_shift_rects_ = rects;
+}
+
void HeadsUpDisplayLayerImpl::PushPropertiesTo(LayerImpl* layer) {
LayerImpl::PushPropertiesTo(layer);
@@ -521,6 +531,7 @@ void HeadsUpDisplayLayerImpl::PushPropertiesTo(LayerImpl* layer) {
static_cast<HeadsUpDisplayLayerImpl*>(layer);
layer_impl->SetHUDTypeface(typeface_);
+ layer_impl->SetLayoutShiftRects(layout_shift_rects_);
}
void HeadsUpDisplayLayerImpl::UpdateHudContents() {
@@ -594,11 +605,11 @@ void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
if (align == TextAlign::kCenter) {
auto width =
- font.measureText(text.c_str(), text.length(), kUTF8_SkTextEncoding);
+ font.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8);
x -= width * 0.5f;
} else if (align == TextAlign::kRight) {
auto width =
- font.measureText(text.c_str(), text.length(), kUTF8_SkTextEncoding);
+ font.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8);
x -= width;
}
@@ -953,7 +964,7 @@ void HeadsUpDisplayLayerImpl::DrawDebugRect(
SkFont label_font(typeface_, kFontHeight);
const SkScalar label_text_width = label_font.measureText(
- label_text.c_str(), label_text.length(), kUTF8_SkTextEncoding);
+ label_text.c_str(), label_text.length(), SkTextEncoding::kUTF8);
canvas->drawRect(SkRect::MakeWH(label_text_width + 2 * kPadding,
kFontHeight + 2 * kPadding),
label_flags);
@@ -980,6 +991,9 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
std::string label_text;
switch (debug_rects[i].type) {
+ case LAYOUT_SHIFT_RECT_TYPE:
+ // TODO(rnasri@): Handle layout shift rects drawing.
+ break;
case PAINT_RECT_TYPE:
new_paint_rects.push_back(debug_rects[i]);
continue;
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.h b/chromium/cc/layers/heads_up_display_layer_impl.h
index 7f209eb7267..4b1f4bf6ee2 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.h
+++ b/chromium/cc/layers/heads_up_display_layer_impl.h
@@ -64,6 +64,8 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
bool IsAnimatingHUDContents() const { return fade_step_ > 0; }
void SetHUDTypeface(sk_sp<SkTypeface> typeface);
+ void SetLayoutShiftRects(const std::vector<gfx::Rect>& rects);
+ const std::vector<gfx::Rect>& LayoutShiftRects() const;
// This evicts hud quad appended during render pass preparation.
void EvictHudQuad(const viz::RenderPassList& list);
@@ -148,6 +150,7 @@ class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
sk_sp<SkSurface> staging_surface_;
sk_sp<SkTypeface> typeface_;
+ std::vector<gfx::Rect> layout_shift_rects_;
float internal_contents_scale_;
gfx::Size internal_content_bounds_;
diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc
index 54907feef3d..24db5b0a3cc 100644
--- a/chromium/cc/layers/layer.cc
+++ b/chromium/cc/layers/layer.cc
@@ -601,6 +601,10 @@ void Layer::SetBackdropFilterBounds(const gfx::RRectF& backdrop_filter_bounds) {
inputs_.backdrop_filter_bounds = backdrop_filter_bounds;
}
+void Layer::ClearBackdropFilterBounds() {
+ inputs_.backdrop_filter_bounds.reset();
+}
+
void Layer::SetBackdropFilterQuality(const float quality) {
inputs_.backdrop_filter_quality = quality;
}
@@ -615,7 +619,7 @@ void Layer::SetFiltersOrigin(const gfx::PointF& filters_origin) {
SetNeedsCommit();
}
-void Layer::SetRoundedCorner(const std::array<uint32_t, 4>& corner_radii) {
+void Layer::SetRoundedCorner(const gfx::RoundedCornersF& corner_radii) {
DCHECK(IsPropertyChangeAllowed());
if (inputs_.corner_radii == corner_radii)
return;
@@ -1264,9 +1268,22 @@ void Layer::SetShouldFlattenTransform(bool should_flatten) {
SetSubtreePropertyChanged();
}
+#if DCHECK_IS_ON()
+std::string Layer::DebugName() const {
+ if (inputs_.client) {
+ if (auto debug_info = inputs_.client->TakeDebugInfo(this))
+ return debug_info->ToBaseValue()->FindKey("layer_name")->GetString();
+ }
+ return "";
+}
+#endif
+
std::string Layer::ToString() const {
return base::StringPrintf(
"layer_id: %d\n"
+#if DCHECK_IS_ON()
+ " name: %s\n"
+#endif
" Bounds: %s\n"
" ElementId: %s\n"
" OffsetToTransformParent: %s\n"
@@ -1276,7 +1293,11 @@ std::string Layer::ToString() const {
" effect_tree_index: %d\n"
" scroll_tree_index: %d\n"
" transform_tree_index: %d\n",
- id(), bounds().ToString().c_str(), element_id().ToString().c_str(),
+ id(),
+#if DCHECK_IS_ON()
+ DebugName().c_str(),
+#endif
+ bounds().ToString().c_str(), element_id().ToString().c_str(),
offset_to_transform_parent().ToString().c_str(),
position().ToString().c_str(), scrollable(), clip_tree_index(),
effect_tree_index(), scroll_tree_index(), transform_tree_index());
@@ -1394,6 +1415,7 @@ void Layer::SetStickyPositionConstraint(
if (inputs_.sticky_position_constraint == constraint)
return;
inputs_.sticky_position_constraint = constraint;
+ SetSubtreePropertyChanged();
SetPropertyTreesNeedRebuild();
SetNeedsCommit();
}
@@ -1598,6 +1620,10 @@ void Layer::OnFilterAnimated(const FilterOperations& filters) {
inputs_.filters = filters;
}
+void Layer::OnBackdropFilterAnimated(const FilterOperations& backdrop_filters) {
+ inputs_.backdrop_filters = backdrop_filters;
+}
+
void Layer::OnOpacityAnimated(float opacity) {
inputs_.opacity = opacity;
}
diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h
index 5a2fa5bff11..04740451da9 100644
--- a/chromium/cc/layers/layer.h
+++ b/chromium/cc/layers/layer.h
@@ -34,6 +34,7 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/rrect_f.h"
#include "ui/gfx/transform.h"
@@ -249,16 +250,13 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// Set or get the rounded corner radii which is applied to the layer and its
// subtree (as if they are together as a single composited entity) when
// blitting into their target. Setting this makes the layer masked to bounds.
- void SetRoundedCorner(const std::array<uint32_t, 4>& corner_radii);
- const std::array<uint32_t, 4>& corner_radii() const {
+ void SetRoundedCorner(const gfx::RoundedCornersF& corner_radii);
+ const gfx::RoundedCornersF& corner_radii() const {
return inputs_.corner_radii;
}
// Returns true if any of the corner has a non-zero radius set.
- bool HasRoundedCorner() const {
- return corner_radii()[0] + corner_radii()[1] + corner_radii()[2] +
- corner_radii()[3];
- }
+ bool HasRoundedCorner() const { return !corner_radii().IsEmpty(); }
// Set or get the flag that disables the requirement of a render surface for
// this layer due to it having rounded corners. This improves performance at
@@ -318,7 +316,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
}
void SetBackdropFilterBounds(const gfx::RRectF& backdrop_filter_bounds);
- const gfx::RRectF& backdrop_filter_bounds() const {
+ void ClearBackdropFilterBounds();
+ const base::Optional<gfx::RRectF>& backdrop_filter_bounds() const {
return inputs_.backdrop_filter_bounds;
}
@@ -337,7 +336,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// Set or get whether this layer should be a hit test target
void SetHitTestable(bool should_hit_test);
- bool HitTestable() const;
+ virtual bool HitTestable() const;
// Set or gets if this layer is a container for fixed position layers in its
// subtree. Such layers will be positioned and transformed relative to this
@@ -799,6 +798,11 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
return should_flatten_screen_space_transform_from_property_tree_;
}
+#if DCHECK_IS_ON()
+ // For debugging, containing information about the associated DOM, etc.
+ std::string DebugName() const;
+#endif
+
std::string ToString() const;
// Called when a property has been modified in a way that the layer knows
@@ -878,6 +882,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// Interactions with attached animations.
void OnFilterAnimated(const FilterOperations& filters);
+ void OnBackdropFilterAnimated(const FilterOperations& backdrop_filters);
void OnOpacityAnimated(float opacity);
void OnTransformAnimated(const gfx::Transform& transform);
@@ -954,13 +959,13 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
FilterOperations filters;
FilterOperations backdrop_filters;
- gfx::RRectF backdrop_filter_bounds;
+ base::Optional<gfx::RRectF> backdrop_filter_bounds;
gfx::PointF filters_origin;
float backdrop_filter_quality;
// Corner clip radius for the 4 corners of the layer in the following order:
// top left, top right, bottom right, bottom left
- std::array<uint32_t, 4> corner_radii;
+ gfx::RoundedCornersF corner_radii;
// If set, disables this layer's rounded corner from triggering a render
// surface on itself if possible.
diff --git a/chromium/cc/layers/layer_client.h b/chromium/cc/layers/layer_client.h
index c7bb4862c2f..fb4b6408f29 100644
--- a/chromium/cc/layers/layer_client.h
+++ b/chromium/cc/layers/layer_client.h
@@ -29,7 +29,7 @@ class CC_EXPORT LayerClient {
// A pointer to the layer is provided for the convenience of layer clients
// which service multiple layers.
virtual std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
- Layer* layer) = 0;
+ const Layer* layer) = 0;
virtual void DidChangeScrollbarsHiddenIfOverlay(bool) = 0;
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc
index 580dd90ba22..86ccf0fc4aa 100644
--- a/chromium/cc/layers/layer_impl.cc
+++ b/chromium/cc/layers/layer_impl.cc
@@ -143,7 +143,7 @@ void LayerImpl::PopulateSharedQuadState(viz::SharedQuadState* state,
draw_properties_.rounded_corner_bounds,
draw_properties_.clip_rect, draw_properties_.is_clipped,
contents_opaque, draw_properties_.opacity,
- effect_node->has_render_surface ? SkBlendMode::kSrcOver
+ effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver
: effect_node->blend_mode,
GetSortingContextId());
state->is_fast_rounded_corner = draw_properties_.is_fast_rounded_corner;
@@ -169,7 +169,7 @@ void LayerImpl::PopulateScaledSharedQuadState(viz::SharedQuadState* state,
draw_properties().rounded_corner_bounds,
draw_properties().clip_rect, draw_properties().is_clipped,
contents_opaque, draw_properties().opacity,
- effect_node->has_render_surface ? SkBlendMode::kSrcOver
+ effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver
: effect_node->blend_mode,
GetSortingContextId());
state->is_fast_rounded_corner = draw_properties().is_fast_rounded_corner;
@@ -524,6 +524,12 @@ bool LayerImpl::IsActive() const {
}
gfx::Size LayerImpl::bounds() const {
+ // As an optimization, we do not need to include the viewport bounds delta if
+ // the layer is not a viewport layer.
+ if (viewport_layer_type_ == NOT_VIEWPORT_LAYER) {
+ DCHECK(ViewportBoundsDelta().IsZero());
+ return bounds_;
+ }
auto viewport_bounds_delta = gfx::ToCeiledVector2d(ViewportBoundsDelta());
return gfx::Size(bounds_.width() + viewport_bounds_delta.x(),
bounds_.height() + viewport_bounds_delta.y());
diff --git a/chromium/cc/layers/layer_impl_test_properties.h b/chromium/cc/layers/layer_impl_test_properties.h
index c29aee7fb31..0d2c134b2b4 100644
--- a/chromium/cc/layers/layer_impl_test_properties.h
+++ b/chromium/cc/layers/layer_impl_test_properties.h
@@ -49,7 +49,7 @@ struct CC_EXPORT LayerImplTestProperties {
float opacity;
FilterOperations filters;
FilterOperations backdrop_filters;
- gfx::RRectF backdrop_filter_bounds;
+ base::Optional<gfx::RRectF> backdrop_filter_bounds;
float backdrop_filter_quality;
gfx::PointF filters_origin;
SkBlendMode blend_mode;
@@ -70,6 +70,7 @@ struct CC_EXPORT LayerImplTestProperties {
bool user_scrollable_vertical = true;
OverscrollBehavior overscroll_behavior;
base::Optional<SnapContainerData> snap_container_data;
+ gfx::RRectF rounded_corner_bounds;
};
} // namespace cc
diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc
index f969da4f3bb..0a02373e4d9 100644
--- a/chromium/cc/layers/layer_unittest.cc
+++ b/chromium/cc/layers/layer_unittest.cc
@@ -351,8 +351,7 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
grand_child->PushPropertiesTo(grand_child_impl.get()));
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
- const std::array<uint32_t, 4> radii{1, 2, 3, 4};
- EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetRoundedCorner(radii));
+ EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetRoundedCorner({1, 2, 3, 4}));
EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
root->PushPropertiesTo(root_impl.get());
child->PushPropertiesTo(child_impl.get());
@@ -430,6 +429,40 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
child2->PushPropertiesTo(child2_impl.get());
grand_child->PushPropertiesTo(grand_child_impl.get()));
+ // Setting the sticky constraints requires a subtree change. It shouldn't be
+ // required if they don't change.
+ LayerStickyPositionConstraint arbitrary_constraint;
+ arbitrary_constraint.is_sticky = true;
+ arbitrary_constraint.is_anchored_top = true;
+ arbitrary_constraint.top_offset = 50;
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
+ EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
+ root->SetStickyPositionConstraint(arbitrary_constraint));
+ EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
+ root->PushPropertiesTo(root_impl.get());
+ child->PushPropertiesTo(child_impl.get());
+ child2->PushPropertiesTo(child2_impl.get());
+ grand_child->PushPropertiesTo(grand_child_impl.get());
+ layer_tree_host_->ClearLayersThatShouldPushProperties());
+
+ EXECUTE_AND_VERIFY_SUBTREE_NOT_CHANGED(
+ root->SetStickyPositionConstraint(arbitrary_constraint));
+ EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
+ root->PushPropertiesTo(root_impl.get());
+ child->PushPropertiesTo(child_impl.get());
+ child2->PushPropertiesTo(child2_impl.get());
+ grand_child->PushPropertiesTo(grand_child_impl.get()));
+
+ arbitrary_constraint.top_offset = 10;
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
+ EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
+ root->SetStickyPositionConstraint(arbitrary_constraint));
+ EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
+ root->PushPropertiesTo(root_impl.get());
+ child->PushPropertiesTo(child_impl.get());
+ child2->PushPropertiesTo(child2_impl.get());
+ grand_child->PushPropertiesTo(grand_child_impl.get()));
+
gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
root->SetPosition(arbitrary_point_f);
diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer.cc b/chromium/cc/layers/painted_overlay_scrollbar_layer.cc
index ca94e661013..e6fcf5ff6ec 100644
--- a/chromium/cc/layers/painted_overlay_scrollbar_layer.cc
+++ b/chromium/cc/layers/painted_overlay_scrollbar_layer.cc
@@ -73,10 +73,10 @@ void PaintedOverlayScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
scrollbar_layer->SetThumbThickness(thumb_thickness_);
scrollbar_layer->SetThumbLength(thumb_length_);
if (scrollbar_->Orientation() == HORIZONTAL) {
- scrollbar_layer->SetTrackStart(track_rect_.x() - location_.x());
+ scrollbar_layer->SetTrackStart(track_rect_.x());
scrollbar_layer->SetTrackLength(track_rect_.width());
} else {
- scrollbar_layer->SetTrackStart(track_rect_.y() - location_.y());
+ scrollbar_layer->SetTrackStart(track_rect_.y());
scrollbar_layer->SetTrackLength(track_rect_.height());
}
diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc
index ddf202b095a..deda561b810 100644
--- a/chromium/cc/layers/painted_scrollbar_layer.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer.cc
@@ -74,12 +74,10 @@ void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
scrollbar_layer->SetForwardButtonRect(forward_button_rect_);
scrollbar_layer->SetThumbLength(thumb_length_);
if (scrollbar_->Orientation() == HORIZONTAL) {
- scrollbar_layer->SetTrackStart(
- track_rect_.x() - location_.x());
+ scrollbar_layer->SetTrackStart(track_rect_.x());
scrollbar_layer->SetTrackLength(track_rect_.width());
} else {
- scrollbar_layer->SetTrackStart(
- track_rect_.y() - location_.y());
+ scrollbar_layer->SetTrackStart(track_rect_.y());
scrollbar_layer->SetTrackLength(track_rect_.height());
}
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
index 66275d92f98..0788e665719 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
@@ -217,6 +217,36 @@ gfx::Rect PaintedScrollbarLayerImpl::ForwardButtonRect() const {
return forward_button_rect_;
}
+gfx::Rect PaintedScrollbarLayerImpl::BackTrackRect() const {
+ gfx::Rect thumb_rect = ComputeThumbQuadRect();
+ if (orientation() == HORIZONTAL) {
+ int rect_x = back_button_rect_.x() + back_button_rect_.width();
+ int rect_y = back_button_rect_.y();
+ return gfx::Rect(rect_x, rect_y, thumb_rect.x() - rect_x,
+ back_button_rect_.height());
+ } else {
+ int rect_x = back_button_rect_.x();
+ int rect_y = back_button_rect_.y() + back_button_rect_.height();
+ return gfx::Rect(rect_x, rect_y, back_button_rect_.width(),
+ thumb_rect.y() - rect_y);
+ }
+}
+
+gfx::Rect PaintedScrollbarLayerImpl::ForwardTrackRect() const {
+ gfx::Rect thumb_rect = ComputeThumbQuadRect();
+ if (orientation() == HORIZONTAL) {
+ int rect_x = thumb_rect.x() + thumb_rect.width();
+ int rect_y = thumb_rect.y();
+ return gfx::Rect(rect_x, rect_y, forward_button_rect_.x() - rect_x,
+ forward_button_rect_.height());
+ } else {
+ int rect_x = thumb_rect.x();
+ int rect_y = thumb_rect.y() + thumb_rect.height();
+ return gfx::Rect(rect_x, rect_y, forward_button_rect_.width(),
+ forward_button_rect_.y() - rect_y);
+ }
+}
+
void PaintedScrollbarLayerImpl::SetTrackLength(int track_length) {
if (track_length_ == track_length)
return;
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.h b/chromium/cc/layers/painted_scrollbar_layer_impl.h
index 13a9b4f41db..37be215c49c 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl.h
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl.h
@@ -62,6 +62,8 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase {
gfx::Rect BackButtonRect() const override;
gfx::Rect ForwardButtonRect() const override;
+ gfx::Rect BackTrackRect() const override;
+ gfx::Rect ForwardTrackRect() const override;
int ThumbThickness() const override;
LayerTreeSettings::ScrollbarAnimator GetScrollbarAnimator() const override;
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
index bef40d67ea2..d2d4c6af676 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
@@ -80,8 +80,10 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) {
const viz::DrawQuad* thumb_draw_quad = impl.quad_list().ElementAt(0);
const viz::DrawQuad* track_draw_quad = impl.quad_list().ElementAt(1);
- EXPECT_EQ(viz::DrawQuad::TEXTURE_CONTENT, thumb_draw_quad->material);
- EXPECT_EQ(viz::DrawQuad::TEXTURE_CONTENT, track_draw_quad->material);
+ EXPECT_EQ(viz::DrawQuad::Material::kTextureContent,
+ thumb_draw_quad->material);
+ EXPECT_EQ(viz::DrawQuad::Material::kTextureContent,
+ track_draw_quad->material);
const viz::TextureDrawQuad* thumb_quad =
viz::TextureDrawQuad::MaterialCast(thumb_draw_quad);
diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc
index 9f53aa0cb72..b9cbcd3241a 100644
--- a/chromium/cc/layers/picture_layer_impl.cc
+++ b/chromium/cc/layers/picture_layer_impl.cc
@@ -484,8 +484,8 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
shared_quad_state, offset_geometry_rect,
offset_visible_geometry_rect, needs_blending,
draw_info.resource_id_for_export(), texture_rect,
- draw_info.resource_size(), draw_info.contents_swizzled(),
- draw_info.is_premultiplied(), nearest_neighbor_,
+ draw_info.resource_size(), draw_info.is_premultiplied(),
+ nearest_neighbor_,
!layer_tree_impl()->settings().enable_edge_anti_aliasing);
ValidateQuadResources(quad);
has_draw_quad = true;
diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc
index 1ecd3df1423..d98fed6c1d0 100644
--- a/chromium/cc/layers/picture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/picture_layer_impl_unittest.cc
@@ -1508,7 +1508,7 @@ TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) {
active_layer()->DidDraw(nullptr);
ASSERT_EQ(1u, render_pass->quad_list.size());
- EXPECT_EQ(viz::DrawQuad::PICTURE_CONTENT,
+ EXPECT_EQ(viz::DrawQuad::Material::kPictureContent,
render_pass->quad_list.front()->material);
EXPECT_EQ(render_pass->quad_list.front()->rect, layer_rect);
EXPECT_FALSE(render_pass->quad_list.front()->needs_blending);
@@ -1545,7 +1545,7 @@ TEST_F(PictureLayerImplTest, ResourcelessPartialRecording) {
gfx::Rect quad_visible = gfx::IntersectRects(scaled_visible, scaled_recorded);
ASSERT_EQ(1U, render_pass->quad_list.size());
- EXPECT_EQ(viz::DrawQuad::PICTURE_CONTENT,
+ EXPECT_EQ(viz::DrawQuad::Material::kPictureContent,
render_pass->quad_list.front()->material);
const viz::DrawQuad* quad = render_pass->quad_list.front();
EXPECT_EQ(quad_visible, quad->rect);
@@ -1621,7 +1621,7 @@ TEST_F(PictureLayerImplTest, FarScrolledQuadsShifted) {
last_height = draw_quad->rect.height();
}
EXPECT_LT(last_y, 5000);
- EXPECT_EQ(draw_quad->material, viz::DrawQuad::TILED_CONTENT);
+ EXPECT_EQ(draw_quad->material, viz::DrawQuad::Material::kTiledContent);
auto transform = [draw_quad](const gfx::Rect& rect) {
gfx::RectF result(rect);
@@ -1699,7 +1699,7 @@ TEST_F(PictureLayerImplTest, FarScrolledSolidColorQuadsShifted) {
last_height = draw_quad->rect.height();
}
EXPECT_LT(last_y, 5000);
- EXPECT_EQ(draw_quad->material, viz::DrawQuad::SOLID_COLOR);
+ EXPECT_EQ(draw_quad->material, viz::DrawQuad::Material::kSolidColor);
auto transform = [draw_quad](const gfx::Rect& rect) {
gfx::RectF result(rect);
@@ -3931,9 +3931,9 @@ TEST_F(PictureLayerImplTestWithDelegatingRenderer,
// Even when OOM, quads should be produced, and should be different material
// from quads with resource.
EXPECT_LT(max_tiles, render_pass->quad_list.size());
- EXPECT_EQ(viz::DrawQuad::Material::TILED_CONTENT,
+ EXPECT_EQ(viz::DrawQuad::Material::kTiledContent,
render_pass->quad_list.front()->material);
- EXPECT_EQ(viz::DrawQuad::Material::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
render_pass->quad_list.back()->material);
}
@@ -4657,8 +4657,8 @@ void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid,
EXPECT_EQ(4u, render_pass->quad_list.size());
viz::DrawQuad::Material expected =
- test_for_solid ? viz::DrawQuad::Material::SOLID_COLOR
- : viz::DrawQuad::Material::TILED_CONTENT;
+ test_for_solid ? viz::DrawQuad::Material::kSolidColor
+ : viz::DrawQuad::Material::kTiledContent;
EXPECT_EQ(expected, render_pass->quad_list.front()->material);
}
@@ -5283,7 +5283,7 @@ TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) {
active_layer->DidDraw(nullptr);
ASSERT_FALSE(render_pass->quad_list.empty());
- EXPECT_EQ(viz::DrawQuad::TILED_CONTENT,
+ EXPECT_EQ(viz::DrawQuad::Material::kTiledContent,
render_pass->quad_list.front()->material);
// Tiles are ready at correct scale, so should not set had_incomplete_tile.
diff --git a/chromium/cc/layers/recording_source_unittest.cc b/chromium/cc/layers/recording_source_unittest.cc
index dbdcaa17c49..34f3508c062 100644
--- a/chromium/cc/layers/recording_source_unittest.cc
+++ b/chromium/cc/layers/recording_source_unittest.cc
@@ -16,6 +16,10 @@
namespace cc {
namespace {
+gfx::ColorSpace DefaultColorSpace() {
+ return gfx::ColorSpace::CreateSRGB();
+}
+
std::unique_ptr<FakeRecordingSource> CreateRecordingSource(
const gfx::Rect& viewport) {
gfx::Rect layer_rect(viewport.right(), viewport.bottom());
@@ -106,7 +110,8 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) {
std::vector<const DrawImage*> images;
raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128),
&images);
- DrawImage image(*images[0], scale, PaintImage::kDefaultFrameIndex);
+ DrawImage image(*images[0], scale, PaintImage::kDefaultFrameIndex,
+ DefaultColorSpace());
EXPECT_EQ(1u, images.size());
EXPECT_FLOAT_EQ(scale, image.scale().width());
EXPECT_FLOAT_EQ(scale, image.scale().height());
diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc
index ea81934163c..6acd6825c0b 100644
--- a/chromium/cc/layers/render_surface_impl.cc
+++ b/chromium/cc/layers/render_surface_impl.cc
@@ -153,7 +153,7 @@ const FilterOperations& RenderSurfaceImpl::BackdropFilters() const {
return OwningEffectNode()->backdrop_filters;
}
-const gfx::RRectF& RenderSurfaceImpl::BackdropFilterBounds() const {
+base::Optional<gfx::RRectF> RenderSurfaceImpl::BackdropFilterBounds() const {
return OwningEffectNode()->backdrop_filter_bounds;
}
@@ -573,7 +573,7 @@ void RenderSurfaceImpl::TileMaskLayer(
constexpr float backdrop_filter_quality = 1.0;
switch (temp_quad->material) {
- case viz::DrawQuad::TILED_CONTENT: {
+ case viz::DrawQuad::Material::kTiledContent: {
DCHECK_EQ(1U, temp_quad->resources.count);
// When the |temp_quad| is actually a texture, we need to calculate
// |mask_uv_rect|. The |mask_uv_rect| is the normalized sub-rect for
@@ -622,7 +622,7 @@ void RenderSurfaceImpl::TileMaskLayer(
!layer_tree_impl_->settings().enable_edge_anti_aliasing,
backdrop_filter_quality);
} break;
- case viz::DrawQuad::SOLID_COLOR: {
+ case viz::DrawQuad::Material::kSolidColor: {
SkColor temp_color =
viz::SolidColorDrawQuad::MaterialCast(temp_quad)->color;
// Check the alpha channel of the color. We apply the mask by
@@ -642,7 +642,7 @@ void RenderSurfaceImpl::TileMaskLayer(
!layer_tree_impl_->settings().enable_edge_anti_aliasing,
backdrop_filter_quality);
} break;
- case viz::DrawQuad::DEBUG_BORDER:
+ case viz::DrawQuad::Material::kDebugBorder:
NOTIMPLEMENTED();
break;
default:
diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h
index 15dd8c98384..89a270cf933 100644
--- a/chromium/cc/layers/render_surface_impl.h
+++ b/chromium/cc/layers/render_surface_impl.h
@@ -159,7 +159,7 @@ class CC_EXPORT RenderSurfaceImpl {
const FilterOperations& Filters() const;
const FilterOperations& BackdropFilters() const;
- const gfx::RRectF& BackdropFilterBounds() const;
+ base::Optional<gfx::RRectF> BackdropFilterBounds() const;
gfx::PointF FiltersOrigin() const;
gfx::Transform SurfaceScale() const;
diff --git a/chromium/cc/layers/render_surface_unittest.cc b/chromium/cc/layers/render_surface_unittest.cc
index 2176380091b..577594b0abe 100644
--- a/chromium/cc/layers/render_surface_unittest.cc
+++ b/chromium/cc/layers/render_surface_unittest.cc
@@ -68,7 +68,7 @@ class FakePictureLayerImplForRenderSurfaceTest : public FakePictureLayerImpl {
for (const auto& rect : quad_rects_) {
auto* quad = render_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>();
quad->SetNew(shared_quad_state, rect, rect, needs_blending, 0,
- gfx::RectF(rect), bounds(), false, false, false, false);
+ gfx::RectF(rect), bounds(), false, false, false);
}
}
diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.cc b/chromium/cc/layers/scrollbar_layer_impl_base.cc
index fb4ed8fb758..419b0517b81 100644
--- a/chromium/cc/layers/scrollbar_layer_impl_base.cc
+++ b/chromium/cc/layers/scrollbar_layer_impl_base.cc
@@ -290,6 +290,14 @@ gfx::Rect ScrollbarLayerImplBase::ForwardButtonRect() const {
return gfx::Rect(0, 0);
}
+gfx::Rect ScrollbarLayerImplBase::BackTrackRect() const {
+ return gfx::Rect(0, 0);
+}
+
+gfx::Rect ScrollbarLayerImplBase::ForwardTrackRect() const {
+ return gfx::Rect(0, 0);
+}
+
// This manages identifying which part of a composited scrollbar got hit based
// on the position_in_widget.
ScrollbarPart ScrollbarLayerImplBase::IdentifyScrollbarPart(
@@ -298,9 +306,19 @@ ScrollbarPart ScrollbarLayerImplBase::IdentifyScrollbarPart(
position_in_widget.y());
if (BackButtonRect().Contains(pointer_location))
return ScrollbarPart::BACK_BUTTON;
+
if (ForwardButtonRect().Contains(pointer_location))
return ScrollbarPart::FORWARD_BUTTON;
+ if (ComputeThumbQuadRect().Contains(pointer_location))
+ return ScrollbarPart::THUMB;
+
+ if (BackTrackRect().Contains(pointer_location))
+ return ScrollbarPart::BACK_TRACK;
+
+ if (ForwardTrackRect().Contains(pointer_location))
+ return ScrollbarPart::FORWARD_TRACK;
+
// TODO(arakeri): Once crbug.com/952314 is fixed, add a DCHECK to verify that
// the point that is passed in is within the TrackRect. Also, please note that
// hit testing other scrollbar parts is not yet implemented.
diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.h b/chromium/cc/layers/scrollbar_layer_impl_base.h
index 5255f520e4f..b1c225235b5 100644
--- a/chromium/cc/layers/scrollbar_layer_impl_base.h
+++ b/chromium/cc/layers/scrollbar_layer_impl_base.h
@@ -66,8 +66,12 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl {
virtual LayerTreeSettings::ScrollbarAnimator GetScrollbarAnimator() const;
+ virtual float TrackLength() const = 0;
+ virtual int ThumbLength() const = 0;
virtual gfx::Rect BackButtonRect() const;
virtual gfx::Rect ForwardButtonRect() const;
+ virtual gfx::Rect BackTrackRect() const;
+ virtual gfx::Rect ForwardTrackRect() const;
virtual ScrollbarPart IdentifyScrollbarPart(
const gfx::PointF position_in_widget) const;
// Only PaintedOverlayScrollbar(Aura Overlay Scrollbar) need to know
@@ -82,8 +86,6 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl {
bool is_overlay);
~ScrollbarLayerImplBase() override;
- virtual int ThumbLength() const = 0;
- virtual float TrackLength() const = 0;
virtual int TrackStart() const = 0;
// Indicates whether the thumb length can be changed without going back to the
// main thread.
diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc
index c46e3eef674..3320d74868f 100644
--- a/chromium/cc/layers/scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/scrollbar_layer_unittest.cc
@@ -414,10 +414,13 @@ TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) {
root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0));
scrollbar_layer->SetBounds(gfx::Size(70, 10));
scrollbar_layer->SetScrollElementId(root_layer->element_id());
+
+ // The track_rect should be relative to the scrollbar's origin.
scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10));
- scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
+ scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(10, 10, 50, 10));
scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10);
scrollbar_layer->fake_scrollbar()->set_thumb_length(4);
+
LayerImpl* root_layer_impl = nullptr;
PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr;
@@ -452,10 +455,13 @@ TEST_F(ScrollbarLayerTest, ThumbRect) {
root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0));
scrollbar_layer->SetBounds(gfx::Size(70, 10));
scrollbar_layer->SetScrollElementId(root_layer->element_id());
+
+ // The track_rect should be relative to the scrollbar's origin.
scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10));
- scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
+ scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(10, 10, 50, 10));
scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10);
scrollbar_layer->fake_scrollbar()->set_thumb_length(4);
+
layer_tree_host_->UpdateLayers();
LayerImpl* root_layer_impl = nullptr;
PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr;
@@ -493,7 +499,7 @@ TEST_F(ScrollbarLayerTest, ThumbRect) {
// Shrink the scrollbar layer to cover only the track.
scrollbar_layer->SetBounds(gfx::Size(50, 10));
scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(30, 10));
- scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
+ scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 10, 50, 10));
UPDATE_AND_EXTRACT_LAYER_POINTERS();
EXPECT_EQ(gfx::Rect(44, 0, 6, 4).ToString(),
@@ -502,7 +508,7 @@ TEST_F(ScrollbarLayerTest, ThumbRect) {
// Shrink the track in the non-scrolling dimension so that it only covers the
// middle third of the scrollbar layer (this does not affect the thumb
// position).
- scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 12, 50, 6));
+ scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 12, 50, 6));
UPDATE_AND_EXTRACT_LAYER_POINTERS();
EXPECT_EQ(gfx::Rect(44, 0, 6, 4).ToString(),
@@ -582,7 +588,7 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) {
const auto& quads = render_pass->quad_list;
ASSERT_EQ(1u, quads.size());
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR, quads.front()->material);
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor, quads.front()->material);
EXPECT_EQ(gfx::Rect(6, 0, 39, 3), quads.front()->rect);
}
@@ -597,7 +603,7 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) {
const auto& quads = render_pass->quad_list;
ASSERT_EQ(1u, quads.size());
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR, quads.front()->material);
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor, quads.front()->material);
EXPECT_EQ(gfx::Rect(8, 0, 19, 3), quads.front()->rect);
}
@@ -612,7 +618,7 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) {
const auto& quads = render_pass->quad_list;
ASSERT_EQ(1u, quads.size());
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR, quads.front()->material);
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor, quads.front()->material);
EXPECT_EQ(gfx::Rect(1, 0, 98, 3), quads.front()->rect);
}
}
@@ -669,7 +675,7 @@ TEST_F(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) {
const auto& quads = render_pass->quad_list;
ASSERT_EQ(1u, quads.size());
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR, quads.front()->material);
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor, quads.front()->material);
EXPECT_EQ(gfx::Rect(3, 0, 3, 3), quads.front()->rect);
}
}
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.cc b/chromium/cc/layers/solid_color_scrollbar_layer.cc
index c73f241a7ad..e91ad78fd38 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer.cc
+++ b/chromium/cc/layers/solid_color_scrollbar_layer.cc
@@ -76,6 +76,8 @@ void SolidColorScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
SolidColorScrollbarLayerImpl* scrollbar_layer =
static_cast<SolidColorScrollbarLayerImpl*>(layer);
+ DCHECK(!scrollbar_layer->HitTestable());
+
scrollbar_layer->SetScrollElementId(
solid_color_scrollbar_layer_inputs_.scroll_element_id);
}
@@ -96,4 +98,10 @@ void SolidColorScrollbarLayer::SetScrollElementId(ElementId element_id) {
SetNeedsCommit();
}
+bool SolidColorScrollbarLayer::HitTestable() const {
+ // Android scrollbars can't be interacted with by user input. They should
+ // avoid hit testing so we don't enter any scrollbar scrolling code paths.
+ return false;
+}
+
} // namespace cc
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.h b/chromium/cc/layers/solid_color_scrollbar_layer.h
index 67c4adb2463..0b937b48b09 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer.h
+++ b/chromium/cc/layers/solid_color_scrollbar_layer.h
@@ -34,6 +34,8 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface,
void SetNeedsDisplayRect(const gfx::Rect& rect) override;
+ bool HitTestable() const override;
+
// ScrollbarLayerInterface
void SetScrollElementId(ElementId element_id) override;
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
index 2ab831c59dd..b96e4bc3b68 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
@@ -58,6 +58,7 @@ SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl(
void SolidColorScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) {
ScrollbarLayerImplBase::PushPropertiesTo(layer);
+ DCHECK(!layer->HitTestable());
}
int SolidColorScrollbarLayerImpl::ThumbThickness() const {
diff --git a/chromium/cc/layers/surface_layer.cc b/chromium/cc/layers/surface_layer.cc
index f2750e47cf6..ec1c8646a40 100644
--- a/chromium/cc/layers/surface_layer.cc
+++ b/chromium/cc/layers/surface_layer.cc
@@ -113,6 +113,10 @@ void SurfaceLayer::SetHasPointerEventsNone(bool has_pointer_events_none) {
SetNeedsCommit();
}
+void SurfaceLayer::SetIsReflection(bool is_reflection) {
+ is_reflection_ = true;
+}
+
void SurfaceLayer::SetMayContainVideo(bool may_contain_video) {
may_contain_video_ = may_contain_video;
}
@@ -150,6 +154,7 @@ void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) {
// Unless the client explicitly calls SetSurfaceId again after this
// commit, don't block on |surface_range_| again.
deadline_in_frames_ = 0u;
+ layer_impl->SetIsReflection(is_reflection_);
layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
layer_impl->SetSurfaceHitTestable(surface_hit_testable_);
layer_impl->SetHasPointerEventsNone(has_pointer_events_none_);
diff --git a/chromium/cc/layers/surface_layer.h b/chromium/cc/layers/surface_layer.h
index 9d15812f813..30e329a7ab9 100644
--- a/chromium/cc/layers/surface_layer.h
+++ b/chromium/cc/layers/surface_layer.h
@@ -44,7 +44,9 @@ class CC_EXPORT SurfaceLayer : public Layer {
void SetHasPointerEventsNone(bool has_pointer_events_none);
- void SetMayContainVideo(bool);
+ void SetIsReflection(bool is_reflection);
+
+ void SetMayContainVideo(bool may_contain_video);
// Layer overrides.
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
@@ -90,6 +92,9 @@ class CC_EXPORT SurfaceLayer : public Layer {
// TODO(sunxd): consider renaming it to oopif_has_pointer_events_none_ for
// disambiguation.
bool has_pointer_events_none_ = false;
+
+ // This surface layer is reflecting the root surface of another display.
+ bool is_reflection_ = false;
};
} // namespace cc
diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc
index 299d343bcf7..9d4a37a49d5 100644
--- a/chromium/cc/layers/surface_layer_impl.cc
+++ b/chromium/cc/layers/surface_layer_impl.cc
@@ -83,6 +83,14 @@ void SurfaceLayerImpl::SetHasPointerEventsNone(bool has_pointer_events_none) {
NoteLayerPropertyChanged();
}
+void SurfaceLayerImpl::SetIsReflection(bool is_reflection) {
+ if (is_reflection_ == is_reflection)
+ return;
+
+ is_reflection_ = is_reflection;
+ NoteLayerPropertyChanged();
+}
+
void SurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
LayerImpl::PushPropertiesTo(layer);
SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
@@ -93,6 +101,7 @@ void SurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
layer_impl->SetSurfaceHitTestable(surface_hit_testable_);
layer_impl->SetHasPointerEventsNone(has_pointer_events_none_);
+ layer_impl->SetIsReflection(is_reflection_);
}
bool SurfaceLayerImpl::WillDraw(
@@ -108,17 +117,40 @@ bool SurfaceLayerImpl::WillDraw(
update_submission_state_callback_.Run(will_draw);
}
- return surface_range_.IsValid() && will_draw;
+ return will_draw;
}
void SurfaceLayerImpl::AppendQuads(viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data) {
AppendRainbowDebugBorder(render_pass);
- if (!surface_range_.IsValid())
+
+ float device_scale_factor = layer_tree_impl()->device_scale_factor();
+
+ gfx::Rect quad_rect(gfx::ScaleToEnclosingRect(
+ gfx::Rect(bounds()), device_scale_factor, device_scale_factor));
+ gfx::Rect visible_quad_rect =
+ draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
+ gfx::Rect(bounds()));
+
+ visible_quad_rect = gfx::ScaleToEnclosingRect(
+ visible_quad_rect, device_scale_factor, device_scale_factor);
+ visible_quad_rect = gfx::IntersectRects(quad_rect, visible_quad_rect);
+
+ if (visible_quad_rect.IsEmpty())
return;
- auto* primary = CreateSurfaceDrawQuad(render_pass, surface_range_);
- if (primary) {
+ viz::SharedQuadState* shared_quad_state =
+ render_pass->CreateAndAppendSharedQuadState();
+
+ PopulateScaledSharedQuadState(shared_quad_state, device_scale_factor,
+ device_scale_factor, contents_opaque());
+
+ if (surface_range_.IsValid()) {
+ auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
+ quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
+ surface_range_, background_color(),
+ stretch_content_to_fill_bounds_, has_pointer_events_none_);
+ quad->is_reflection = is_reflection_;
// Add the primary surface ID as a dependency.
append_quads_data->activation_dependencies.push_back(surface_range_.end());
if (deadline_in_frames_) {
@@ -129,7 +161,13 @@ void SurfaceLayerImpl::AppendQuads(viz::RenderPass* render_pass,
} else {
append_quads_data->use_default_lower_bound_deadline = true;
}
+ } else {
+ auto* quad =
+ render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
+ quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
+ background_color(), false /* force_anti_aliasing_off */);
}
+
// Unless the client explicitly specifies otherwise, don't block on
// |surface_range_| more than once.
deadline_in_frames_ = 0u;
@@ -144,42 +182,6 @@ gfx::Rect SurfaceLayerImpl::GetEnclosingRectInTargetSpace() const {
layer_tree_impl()->device_scale_factor());
}
-viz::SurfaceDrawQuad* SurfaceLayerImpl::CreateSurfaceDrawQuad(
- viz::RenderPass* render_pass,
- const viz::SurfaceRange& surface_range) {
- DCHECK(surface_range.end().is_valid());
-
- float device_scale_factor = layer_tree_impl()->device_scale_factor();
-
- gfx::Rect quad_rect(gfx::ScaleToEnclosingRect(
- gfx::Rect(bounds()), device_scale_factor, device_scale_factor));
- gfx::Rect visible_quad_rect =
- draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
- gfx::Rect(bounds()));
-
- visible_quad_rect = gfx::ScaleToEnclosingRect(
- visible_quad_rect, device_scale_factor, device_scale_factor);
- visible_quad_rect = gfx::IntersectRects(quad_rect, visible_quad_rect);
-
- if (visible_quad_rect.IsEmpty())
- return nullptr;
-
- viz::SharedQuadState* shared_quad_state =
- render_pass->CreateAndAppendSharedQuadState();
-
- PopulateScaledSharedQuadState(shared_quad_state, device_scale_factor,
- device_scale_factor, contents_opaque());
-
- auto* surface_draw_quad =
- render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
- surface_draw_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
- surface_range, background_color(),
- stretch_content_to_fill_bounds_,
- has_pointer_events_none_);
-
- return surface_draw_quad;
-}
-
void SurfaceLayerImpl::GetDebugBorderProperties(SkColor* color,
float* width) const {
*color = DebugColors::SurfaceLayerBorderColor();
diff --git a/chromium/cc/layers/surface_layer_impl.h b/chromium/cc/layers/surface_layer_impl.h
index 1c3849f95a0..97b1f6ce9d0 100644
--- a/chromium/cc/layers/surface_layer_impl.h
+++ b/chromium/cc/layers/surface_layer_impl.h
@@ -61,6 +61,9 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
void SetHasPointerEventsNone(bool has_pointer_events_none);
bool has_pointer_events_none() const { return has_pointer_events_none_; }
+ void SetIsReflection(bool is_reflection);
+ bool is_reflection() const { return is_reflection_; }
+
// LayerImpl overrides.
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
void PushPropertiesTo(LayerImpl* layer) override;
@@ -75,10 +78,6 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
SurfaceLayerImpl(LayerTreeImpl* tree_impl, int id, UpdateSubmissionStateCB);
private:
- viz::SurfaceDrawQuad* CreateSurfaceDrawQuad(
- viz::RenderPass* render_pass,
- const viz::SurfaceRange& surface_range);
-
void GetDebugBorderProperties(SkColor* color, float* width) const override;
void AppendRainbowDebugBorder(viz::RenderPass* render_pass);
void AsValueInto(base::trace_event::TracedValue* dict) const override;
@@ -91,6 +90,7 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
bool stretch_content_to_fill_bounds_ = false;
bool surface_hit_testable_ = false;
bool has_pointer_events_none_ = false;
+ bool is_reflection_ = false;
bool will_draw_ = false;
};
diff --git a/chromium/cc/layers/texture_layer_impl.cc b/chromium/cc/layers/texture_layer_impl.cc
index 9d2e07594a9..6944908fbb2 100644
--- a/chromium/cc/layers/texture_layer_impl.cc
+++ b/chromium/cc/layers/texture_layer_impl.cc
@@ -110,15 +110,9 @@ void TextureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
LayerTreeFrameSink* sink = layer_tree_impl()->layer_tree_frame_sink();
for (const auto& pair : to_register_bitmaps_) {
- // Because we may want to notify a display compositor about this
- // base::SharedMemory more than one time, we need to be able to keep
- // making handles to share with it, so we can't close the
- // base::SharedMemory.
- mojo::ScopedSharedBufferHandle handle =
- viz::bitmap_allocation::DuplicateWithoutClosingMappedBitmap(
- pair.second->shared_memory(), pair.second->size(),
- pair.second->format());
- sink->DidAllocateSharedBitmap(std::move(handle), pair.first);
+ sink->DidAllocateSharedBitmap(viz::bitmap_allocation::ToMojoHandle(
+ pair.second->shared_region().Duplicate()),
+ pair.first);
}
// All |to_register_bitmaps_| have been registered above, so we can move them
// all to the |registered_bitmaps_|.
diff --git a/chromium/cc/layers/texture_layer_impl_unittest.cc b/chromium/cc/layers/texture_layer_impl_unittest.cc
index eaad5053f05..13a352cd982 100644
--- a/chromium/cc/layers/texture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/texture_layer_impl_unittest.cc
@@ -56,7 +56,8 @@ TEST(TextureLayerImplTest, Occlusion) {
auto resource = viz::TransferableResource::MakeGL(
gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D,
gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456));
+ gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456),
+ layer_size, false /* is_overlay_candidate */);
TextureLayerImpl* texture_layer_impl =
impl.AddChildToRoot<TextureLayerImpl>();
diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc
index 64697a6c848..7aec79fdf9a 100644
--- a/chromium/cc/layers/texture_layer_unittest.cc
+++ b/chromium/cc/layers/texture_layer_unittest.cc
@@ -129,11 +129,13 @@ struct CommonResourceObjects {
base::Unretained(&mock_callback_), mailbox_name2_);
const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
+ gfx::Size size(128, 128);
resource1_ = viz::TransferableResource::MakeGL(
- mailbox_name1_, GL_LINEAR, arbitrary_target1, sync_token1_);
+ mailbox_name1_, GL_LINEAR, arbitrary_target1, sync_token1_, size,
+ false /* is_overlay_candidate */);
resource2_ = viz::TransferableResource::MakeGL(
- mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_);
- gfx::Size size(128, 128);
+ mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_, size,
+ false /* is_overlay_candidate */);
shared_bitmap_id_ = viz::SharedBitmap::GenerateId();
sw_release_callback_ = base::BindRepeating(
&MockReleaseCallback::Release2, base::Unretained(&mock_callback_),
@@ -686,9 +688,11 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
&TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
base::Unretained(this), mailbox_char));
+ const gfx::Size size(64, 64);
auto resource = viz::TransferableResource::MakeGL(
MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
- SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
+ SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
+ false /* is_overlay_candidate */);
layer_->SetTransferableResource(resource, std::move(callback));
// Damage the layer so we send a new frame with the new resource to the
// Display compositor.
@@ -763,8 +767,10 @@ class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback,
base::Unretained(this), sync_token));
+ constexpr gfx::Size size(64, 64);
auto resource = viz::TransferableResource::MakeGL(
- MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D, sync_token);
+ MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D, sync_token,
+ size, false /* is_overlay_candidate */);
layer_->SetTransferableResource(resource, std::move(callback));
}
@@ -1023,9 +1029,10 @@ class TextureLayerNoExtraCommitForMailboxTest
return true;
}
- *resource = viz::TransferableResource::MakeGL(MailboxFromChar('1'),
- GL_LINEAR, GL_TEXTURE_2D,
- SyncTokenFromUInt(0x123));
+ constexpr gfx::Size size(64, 64);
+ *resource = viz::TransferableResource::MakeGL(
+ MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D,
+ SyncTokenFromUInt(0x123), size, false /* is_overlay_candidate */);
*release_callback = viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerNoExtraCommitForMailboxTest::ResourceReleased,
base::Unretained(this)));
@@ -1107,9 +1114,11 @@ class TextureLayerChangeInvisibleMailboxTest
}
viz::TransferableResource MakeResource(char name) {
+ constexpr gfx::Size size(64, 64);
return viz::TransferableResource::MakeGL(
MailboxFromChar(name), GL_LINEAR, GL_TEXTURE_2D,
- SyncTokenFromUInt(static_cast<uint32_t>(name)));
+ SyncTokenFromUInt(static_cast<uint32_t>(name)), size,
+ false /* is_overlay_candidate */);
}
void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
@@ -1216,8 +1225,10 @@ class TextureLayerReleaseResourcesBase
SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* resource,
std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
+ constexpr gfx::Size size(64, 64);
*resource = viz::TransferableResource::MakeGL(
- MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1));
+ MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1),
+ size, false /* is_overlay_candidate */);
*release_callback = viz::SingleReleaseCallback::Create(
base::BindOnce(&TextureLayerReleaseResourcesBase::ResourceReleased,
base::Unretained(this)));
@@ -1293,9 +1304,11 @@ class TextureLayerWithResourceMainThreadDeleted : public LayerTreeTest {
viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerWithResourceMainThreadDeleted::ReleaseCallback,
base::Unretained(this)));
+ constexpr gfx::Size size(64, 64);
auto resource = viz::TransferableResource::MakeGL(
MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
- SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
+ SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
+ false /* is_overlay_candidate */);
layer_->SetTransferableResource(resource, std::move(callback));
}
@@ -1363,9 +1376,11 @@ class TextureLayerWithResourceImplThreadDeleted : public LayerTreeTest {
viz::SingleReleaseCallback::Create(base::BindOnce(
&TextureLayerWithResourceImplThreadDeleted::ReleaseCallback,
base::Unretained(this)));
+ constexpr gfx::Size size(64, 64);
auto resource = viz::TransferableResource::MakeGL(
MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
- SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
+ SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
+ false /* is_overlay_candidate */);
layer_->SetTransferableResource(resource, std::move(callback));
}
@@ -1518,7 +1533,7 @@ class SoftwareTextureLayerSwitchTreesTest : public SoftwareTextureLayerTest {
id_ = viz::SharedBitmap::GenerateId();
bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
}
@@ -1622,7 +1637,7 @@ class SoftwareTextureLayerPurgeMemoryTest : public SoftwareTextureLayerTest {
id_ = viz::SharedBitmap::GenerateId();
bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
}
@@ -1702,11 +1717,11 @@ class SoftwareTextureLayerMultipleRegisterTest
id1_ = viz::SharedBitmap::GenerateId();
bitmap1_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id1_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id1_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
id2_ = viz::SharedBitmap::GenerateId();
bitmap2_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id2_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id2_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
}
@@ -1796,11 +1811,11 @@ class SoftwareTextureLayerRegisterUnregisterTest
id1_ = viz::SharedBitmap::GenerateId();
bitmap1_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id1_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id1_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
id2_ = viz::SharedBitmap::GenerateId();
bitmap2_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id2_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id2_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
}
@@ -1885,7 +1900,7 @@ class SoftwareTextureLayerLoseFrameSinkTest : public SoftwareTextureLayerTest {
id_ = viz::SharedBitmap::GenerateId();
bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
}
@@ -2000,7 +2015,7 @@ class SoftwareTextureLayerUnregisterRegisterTest
id_ = viz::SharedBitmap::GenerateId();
bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
- id_, viz::bitmap_allocation::AllocateMappedBitmap(size, format), size,
+ id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
format);
}
diff --git a/chromium/cc/layers/video_frame_provider.h b/chromium/cc/layers/video_frame_provider.h
index af413093231..7ae08903b6b 100644
--- a/chromium/cc/layers/video_frame_provider.h
+++ b/chromium/cc/layers/video_frame_provider.h
@@ -93,6 +93,10 @@ class CC_EXPORT VideoFrameProvider {
// frame missed its intended deadline.
virtual void PutCurrentFrame() = 0;
+ // Returns the interval at which the provider expects to have new frames for
+ // the client.
+ virtual base::TimeDelta GetPreferredRenderInterval() = 0;
+
protected:
virtual ~VideoFrameProvider() {}
};
diff --git a/chromium/cc/layers/video_layer.h b/chromium/cc/layers/video_layer.h
index 0ae52c85ee1..45cacd34d0f 100644
--- a/chromium/cc/layers/video_layer.h
+++ b/chromium/cc/layers/video_layer.h
@@ -8,7 +8,7 @@
#include "base/callback.h"
#include "cc/cc_export.h"
#include "cc/layers/layer.h"
-#include "media/base/video_rotation.h"
+#include "media/base/video_transformation.h"
namespace media { class VideoFrame; }
diff --git a/chromium/cc/layers/video_layer_impl.h b/chromium/cc/layers/video_layer_impl.h
index 0f715c7d319..5d3aa87a9de 100644
--- a/chromium/cc/layers/video_layer_impl.h
+++ b/chromium/cc/layers/video_layer_impl.h
@@ -10,7 +10,7 @@
#include "cc/cc_export.h"
#include "cc/layers/layer_impl.h"
#include "components/viz/common/resources/release_callback.h"
-#include "media/base/video_rotation.h"
+#include "media/base/video_transformation.h"
namespace media {
class VideoFrame;
diff --git a/chromium/cc/layers/video_layer_impl_unittest.cc b/chromium/cc/layers/video_layer_impl_unittest.cc
index a8ba9a7ccdd..e70372f5b65 100644
--- a/chromium/cc/layers/video_layer_impl_unittest.cc
+++ b/chromium/cc/layers/video_layer_impl_unittest.cc
@@ -328,7 +328,7 @@ TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) {
EXPECT_EQ(1u, impl.quad_list().size());
const viz::DrawQuad* draw_quad = impl.quad_list().ElementAt(0);
- ASSERT_EQ(viz::DrawQuad::YUV_VIDEO_CONTENT, draw_quad->material);
+ ASSERT_EQ(viz::DrawQuad::Material::kYuvVideoContent, draw_quad->material);
const auto* yuv_draw_quad =
static_cast<const viz::YUVVideoDrawQuad*>(draw_quad);
@@ -366,7 +366,7 @@ TEST(VideoLayerImplTest, HibitSoftwareVideoFrameGeneratesYUVQuad) {
EXPECT_EQ(1u, impl.quad_list().size());
const viz::DrawQuad* draw_quad = impl.quad_list().ElementAt(0);
- ASSERT_EQ(viz::DrawQuad::YUV_VIDEO_CONTENT, draw_quad->material);
+ ASSERT_EQ(viz::DrawQuad::Material::kYuvVideoContent, draw_quad->material);
const auto* yuv_draw_quad =
static_cast<const viz::YUVVideoDrawQuad*>(draw_quad);
@@ -408,7 +408,7 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) {
EXPECT_EQ(1u, impl.quad_list().size());
const viz::DrawQuad* draw_quad = impl.quad_list().ElementAt(0);
- ASSERT_EQ(viz::DrawQuad::YUV_VIDEO_CONTENT, draw_quad->material);
+ ASSERT_EQ(viz::DrawQuad::Material::kYuvVideoContent, draw_quad->material);
const auto* yuv_draw_quad =
static_cast<const viz::YUVVideoDrawQuad*>(draw_quad);
@@ -451,7 +451,7 @@ TEST(VideoLayerImplTest, NativeARGBFrameGeneratesTextureQuad) {
EXPECT_EQ(1u, impl.quad_list().size());
const viz::DrawQuad* draw_quad = impl.quad_list().ElementAt(0);
- ASSERT_EQ(viz::DrawQuad::TEXTURE_CONTENT, draw_quad->material);
+ ASSERT_EQ(viz::DrawQuad::Material::kTextureContent, draw_quad->material);
const viz::TextureDrawQuad* texture_draw_quad =
viz::TextureDrawQuad::MaterialCast(draw_quad);
diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc
index c8985f23b49..8bbe7293b32 100644
--- a/chromium/cc/layers/viewport.cc
+++ b/chromium/cc/layers/viewport.cc
@@ -34,7 +34,7 @@ void Viewport::Pan(const gfx::Vector2dF& delta) {
host_impl_->active_tree());
}
-Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta,
+Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& physical_delta,
const gfx::Point& viewport_point,
bool is_direct_manipulation,
bool affect_browser_controls,
@@ -42,28 +42,30 @@ Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta,
if (!OuterScrollNode())
return ScrollResult();
- gfx::Vector2dF content_delta = delta;
+ gfx::Vector2dF scroll_node_delta = physical_delta;
- if (affect_browser_controls && ShouldBrowserControlsConsumeScroll(delta))
- content_delta -= ScrollBrowserControls(delta);
+ if (affect_browser_controls &&
+ ShouldBrowserControlsConsumeScroll(physical_delta))
+ scroll_node_delta -= ScrollBrowserControls(physical_delta);
- gfx::Vector2dF pending_content_delta = content_delta;
+ gfx::Vector2dF pending_scroll_node_delta = scroll_node_delta;
// Attempt to scroll inner viewport first.
- pending_content_delta -= host_impl_->ScrollSingleNode(
- InnerScrollNode(), pending_content_delta, viewport_point,
+ pending_scroll_node_delta -= host_impl_->ScrollSingleNode(
+ InnerScrollNode(), pending_scroll_node_delta, viewport_point,
is_direct_manipulation, &scroll_tree());
// Now attempt to scroll the outer viewport.
if (scroll_outer_viewport) {
- pending_content_delta -= host_impl_->ScrollSingleNode(
- OuterScrollNode(), pending_content_delta, viewport_point,
+ pending_scroll_node_delta -= host_impl_->ScrollSingleNode(
+ OuterScrollNode(), pending_scroll_node_delta, viewport_point,
is_direct_manipulation, &scroll_tree());
}
ScrollResult result;
- result.consumed_delta = delta - AdjustOverscroll(pending_content_delta);
- result.content_scrolled_delta = content_delta - pending_content_delta;
+ result.consumed_delta =
+ physical_delta - AdjustOverscroll(pending_scroll_node_delta);
+ result.content_scrolled_delta = scroll_node_delta - pending_scroll_node_delta;
return result;
}
diff --git a/chromium/cc/layers/viewport.h b/chromium/cc/layers/viewport.h
index b5c00b80d08..9143b58b747 100644
--- a/chromium/cc/layers/viewport.h
+++ b/chromium/cc/layers/viewport.h
@@ -46,10 +46,12 @@ class CC_EXPORT Viewport {
// Scrolls the viewport, applying the unique bubbling between the inner and
// outer viewport unless the scroll_outer_viewport bit is off. Scrolls can be
- // consumed by browser controls.
- ScrollResult ScrollBy(const gfx::Vector2dF& delta,
+ // consumed by browser controls. The delta is in physical pixels, that is, it
+ // will be scaled by the page scale to ensure the content moves
+ // |physical_delta| number of pixels.
+ ScrollResult ScrollBy(const gfx::Vector2dF& physical_delta,
const gfx::Point& viewport_point,
- bool is_wheel_scroll,
+ bool is_direct_manipulation,
bool affect_browser_controls,
bool scroll_outer_viewport);
diff --git a/chromium/cc/paint/discardable_image_map_unittest.cc b/chromium/cc/paint/discardable_image_map_unittest.cc
index 2b9eee61fc1..8e4a0734995 100644
--- a/chromium/cc/paint/discardable_image_map_unittest.cc
+++ b/chromium/cc/paint/discardable_image_map_unittest.cc
@@ -56,11 +56,14 @@ class DiscardableImageMapTest : public testing::Test {
const DiscardableImageMap& image_map,
const gfx::Rect& rect) {
std::vector<const DrawImage*> draw_image_ptrs;
+ // Choose a not-SRGB-and-not-invalid target color space to verify that it
+ // is passed correctly to the resulting DrawImages.
+ gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50();
image_map.GetDiscardableImagesInRect(rect, &draw_image_ptrs);
std::vector<DrawImage> draw_images;
for (const auto* image : draw_image_ptrs)
- draw_images.push_back(
- DrawImage(*image, 1.f, PaintImage::kDefaultFrameIndex));
+ draw_images.push_back(DrawImage(
+ *image, 1.f, PaintImage::kDefaultFrameIndex, target_color_space));
std::vector<PositionScaleDrawImage> position_draw_images;
std::vector<DrawImage> results;
@@ -77,6 +80,7 @@ class DiscardableImageMapTest : public testing::Test {
for (size_t i = 0; i < draw_images.size(); ++i) {
EXPECT_TRUE(draw_images[i].paint_image() ==
position_draw_images[i].image);
+ EXPECT_EQ(draw_images[i].target_color_space(), target_color_space);
}
return position_draw_images;
}
diff --git a/chromium/cc/paint/draw_image.cc b/chromium/cc/paint/draw_image.cc
index f7d5cbe86f7..8e920f6cce8 100644
--- a/chromium/cc/paint/draw_image.cc
+++ b/chromium/cc/paint/draw_image.cc
@@ -40,24 +40,28 @@ DrawImage::DrawImage(PaintImage image,
const SkIRect& src_rect,
SkFilterQuality filter_quality,
const SkMatrix& matrix,
- base::Optional<size_t> frame_index)
+ base::Optional<size_t> frame_index,
+ const base::Optional<gfx::ColorSpace>& color_space)
: paint_image_(std::move(image)),
src_rect_(src_rect),
filter_quality_(filter_quality),
- frame_index_(frame_index) {
+ frame_index_(frame_index),
+ target_color_space_(color_space) {
matrix_is_decomposable_ = ExtractScale(matrix, &scale_);
}
DrawImage::DrawImage(const DrawImage& other,
float scale_adjustment,
- size_t frame_index)
+ size_t frame_index,
+ const gfx::ColorSpace& color_space)
: paint_image_(other.paint_image_),
src_rect_(other.src_rect_),
filter_quality_(other.filter_quality_),
scale_(SkSize::Make(other.scale_.width() * scale_adjustment,
other.scale_.height() * scale_adjustment)),
matrix_is_decomposable_(other.matrix_is_decomposable_),
- frame_index_(frame_index) {}
+ frame_index_(frame_index),
+ target_color_space_(color_space) {}
DrawImage::DrawImage(const DrawImage& other) = default;
DrawImage::DrawImage(DrawImage&& other) = default;
@@ -69,7 +73,8 @@ DrawImage& DrawImage::operator=(const DrawImage& other) = default;
bool DrawImage::operator==(const DrawImage& other) const {
return paint_image_ == other.paint_image_ && src_rect_ == other.src_rect_ &&
filter_quality_ == other.filter_quality_ && scale_ == other.scale_ &&
- matrix_is_decomposable_ == other.matrix_is_decomposable_;
+ matrix_is_decomposable_ == other.matrix_is_decomposable_ &&
+ target_color_space_ == other.target_color_space_;
}
} // namespace cc
diff --git a/chromium/cc/paint/draw_image.h b/chromium/cc/paint/draw_image.h
index 63653793afe..c1c6957baa8 100644
--- a/chromium/cc/paint/draw_image.h
+++ b/chromium/cc/paint/draw_image.h
@@ -13,12 +13,13 @@
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
+#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size_f.h"
namespace cc {
// A DrawImage is a logical snapshot in time and space of a PaintImage. It
-// includes decisions about scaling, animation frame, etc.
+// includes decisions about scaling, animation frame, final colorspace, etc.
// It has not been decoded yet. DrawImage turns into DecodedDrawImage via
// ImageDecodeCache::GetDecodedImageForDraw during playback.
class CC_PAINT_EXPORT DrawImage {
@@ -29,9 +30,14 @@ class CC_PAINT_EXPORT DrawImage {
const SkIRect& src_rect,
SkFilterQuality filter_quality,
const SkMatrix& matrix,
- base::Optional<size_t> frame_index = base::nullopt);
- // Constructs a DrawImage from |other| by adjusting its scale and frame.
- DrawImage(const DrawImage& other, float scale_adjustment, size_t frame_index);
+ base::Optional<size_t> frame_index = base::nullopt,
+ const base::Optional<gfx::ColorSpace>& color_space = base::nullopt);
+ // Constructs a DrawImage from |other| by adjusting its scale and setting a
+ // new color_space.
+ DrawImage(const DrawImage& other,
+ float scale_adjustment,
+ size_t frame_index,
+ const gfx::ColorSpace& color_space);
DrawImage(const DrawImage& other);
DrawImage(DrawImage&& other);
~DrawImage();
@@ -46,6 +52,10 @@ class CC_PAINT_EXPORT DrawImage {
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 gfx::ColorSpace& target_color_space() const {
+ DCHECK(target_color_space_.has_value());
+ return *target_color_space_;
+ }
PaintImage::FrameKey frame_key() const {
return paint_image_.GetKeyForFrame(frame_index());
}
@@ -61,6 +71,7 @@ class CC_PAINT_EXPORT DrawImage {
SkSize scale_;
bool matrix_is_decomposable_;
base::Optional<size_t> frame_index_;
+ base::Optional<gfx::ColorSpace> target_color_space_;
};
} // namespace cc
diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc
index ff7b98fcc86..9e96fdbc3a3 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.cc
+++ b/chromium/cc/paint/image_transfer_cache_entry.cc
@@ -5,7 +5,6 @@
#include "cc/paint/image_transfer_cache_entry.h"
#include <utility>
-#include <vector>
#include "base/bind_helpers.h"
#include "base/logging.h"
@@ -16,6 +15,8 @@
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPixmap.h"
+#include "third_party/skia/include/core/SkYUVAIndex.h"
+#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/GrTypes.h"
@@ -143,29 +144,67 @@ ServiceImageTransferCacheEntry::ServiceImageTransferCacheEntry(
ServiceImageTransferCacheEntry& ServiceImageTransferCacheEntry::operator=(
ServiceImageTransferCacheEntry&& other) = default;
-bool ServiceImageTransferCacheEntry::BuildFromDecodedData(
+bool ServiceImageTransferCacheEntry::BuildFromHardwareDecodedImage(
GrContext* context,
- base::span<const uint8_t> decoded_image,
- size_t row_bytes,
- const SkImageInfo& image_info,
+ std::vector<sk_sp<SkImage>> plane_images,
+ size_t buffer_byte_size,
bool needs_mips,
sk_sp<SkColorSpace> target_color_space) {
context_ = context;
- has_mips_ = needs_mips;
- size_ = image_info.computeByteSize(row_bytes);
- if (size_ == SIZE_MAX)
+
+ // 1) Extract the planar textures from |plane_images|.
+ std::vector<GrBackendTexture> plane_backend_textures(3u);
+ DCHECK_EQ(3u, plane_images.size());
+ for (size_t plane = 0; plane < 3u; plane++) {
+ plane_backend_textures[plane] = plane_images[plane]->getBackendTexture(
+ true /* flushPendingGrContextIO */);
+ if (!plane_backend_textures[plane].isValid()) {
+ DLOG(ERROR) << "Invalid backend texture found";
+ return false;
+ }
+ if (needs_mips) {
+ // TODO(andrescj): generate mipmaps when requested. This will require some
+ // resource management: we either let Skia own the new textures or we take
+ // ownership and delete them in |destroy_callback|.
+ NOTIMPLEMENTED();
+ }
+ }
+ plane_images_ = std::move(plane_images);
+
+ // 2) Create a SkImage backed by the YUV textures extracted above. There are
+ // two assumptions here:
+ //
+ // - SkYUVColorSpace::kJPEG_SkYUVColorSpace is used for the YUV-to-RGB
+ // matrix.
+ // - The color space of the resulting image is sRGB.
+ //
+ // TODO(andrescj): support other YUV-to-RGB conversions and embedded color
+ // profiles.
+ SkYUVAIndex plane_indices[] = {
+ SkYUVAIndex{0, SkColorChannel::kR}, SkYUVAIndex{1, SkColorChannel::kR},
+ SkYUVAIndex{2, SkColorChannel::kR}, SkYUVAIndex{-1, SkColorChannel::kR}};
+ image_ = SkImage::MakeFromYUVATextures(
+ context_, SkYUVColorSpace::kJPEG_SkYUVColorSpace,
+ plane_backend_textures.data(), plane_indices,
+ plane_images_[0]->dimensions(), kTopLeft_GrSurfaceOrigin);
+ if (!image_) {
+ DLOG(ERROR) << "Could not create YUV SkImage";
return false;
- DCHECK_LE(size_, decoded_image.size());
+ }
- uint32_t width;
- uint32_t height;
- if (!base::CheckedNumeric<int>(image_info.width()).AssignIfValid(&width) ||
- !base::CheckedNumeric<int>(image_info.height()).AssignIfValid(&height)) {
+ // 3) Perform color space conversion if necessary.
+ if (target_color_space)
+ image_ = image_->makeColorSpace(target_color_space);
+ if (!image_) {
+ DLOG(ERROR) << "Could not do color space conversion";
return false;
}
- return MakeSkImage(SkPixmap(image_info, decoded_image.data(), row_bytes),
- width, height, target_color_space);
+ // 4) Fill out the rest of the information.
+ has_mips_ = false;
+ size_ = buffer_byte_size;
+ fits_on_gpu_ = true;
+ return true;
}
size_t ServiceImageTransferCacheEntry::CachedSize() const {
@@ -276,6 +315,14 @@ void ServiceImageTransferCacheEntry::EnsureMips() {
if (has_mips_)
return;
+ if (!plane_images_.empty()) {
+ // TODO(andrescj): generate mipmaps for hardware-accelerated decodes when
+ // requested. This will require some resource management: we either let Skia
+ // own the new textures or we take ownership and delete them in
+ // |destroy_callback_|.
+ NOTIMPLEMENTED();
+ }
+
has_mips_ = true;
// TODO(ericrk): consider adding in the DeleteSkImageAndPreventCaching
// optimization from GpuImageDecodeCache where we forcefully remove the
diff --git a/chromium/cc/paint/image_transfer_cache_entry.h b/chromium/cc/paint/image_transfer_cache_entry.h
index 5385c5b741f..e55a60d894f 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.h
+++ b/chromium/cc/paint/image_transfer_cache_entry.h
@@ -8,6 +8,8 @@
#include <stddef.h>
#include <stdint.h>
+#include <vector>
+
#include "base/atomic_sequence_num.h"
#include "base/containers/span.h"
#include "cc/paint/transfer_cache_entry.h"
@@ -16,7 +18,6 @@
class GrContext;
class SkColorSpace;
class SkImage;
-struct SkImageInfo;
class SkPixmap;
namespace cc {
@@ -60,21 +61,35 @@ class CC_PAINT_EXPORT ServiceImageTransferCacheEntry
ServiceImageTransferCacheEntry& operator=(
ServiceImageTransferCacheEntry&& other);
- // Populates this entry using |decoded_image| described by |row_bytes| and
- // |image_info|. The image is uploaded to the GPU if its dimensions are both
- // at most |context_|->maxTextureSize().
- bool BuildFromDecodedData(GrContext* context,
- base::span<const uint8_t> decoded_image,
- size_t row_bytes,
- const SkImageInfo& image_info,
- bool needs_mips,
- sk_sp<SkColorSpace> target_color_space);
+ // Populates this entry using the result of a hardware decode. The assumption
+ // is that |plane_images| are backed by textures that are in turn backed by a
+ // buffer (dmabuf in Chrome OS) containing the planes of the decoded image.
+ // |buffer_byte_size| is the size of the buffer. We assume the following:
+ //
+ // - |plane_images| represents a YUV 4:2:0 triplanar image.
+ // - The backing textures don't have mipmaps. We will generate the mipmaps if
+ // |needs_mips| is true.
+ // - The conversion from YUV to RGB will be performed assuming a JPEG image.
+ // - The colorspace of the resulting RGB image is sRGB. We will convert from
+ // this to |target_color_space| (if non-null).
+ //
+ // Returns true if the entry can be built, false otherwise.
+ //
+ // TODO(andrescj): actually generate the mipmaps when |needs_mips| is true.
+ bool BuildFromHardwareDecodedImage(GrContext* context,
+ std::vector<sk_sp<SkImage>> plane_images,
+ size_t buffer_byte_size,
+ bool needs_mips,
+ sk_sp<SkColorSpace> target_color_space);
// ServiceTransferCacheEntry implementation:
size_t CachedSize() const final;
bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
bool fits_on_gpu() const { return fits_on_gpu_; }
+ const std::vector<sk_sp<SkImage>>& plane_images() const {
+ return plane_images_;
+ }
const sk_sp<SkImage>& image() const { return image_; }
// Ensures the cached image has mips.
@@ -87,6 +102,7 @@ class CC_PAINT_EXPORT ServiceImageTransferCacheEntry
sk_sp<SkColorSpace> target_color_space);
GrContext* context_ = nullptr;
+ std::vector<sk_sp<SkImage>> plane_images_;
sk_sp<SkImage> image_;
bool has_mips_ = false;
size_t size_ = 0;
diff --git a/chromium/cc/paint/oop_pixeltest.cc b/chromium/cc/paint/oop_pixeltest.cc
index c1cf6f7a30a..9af0e518b94 100644
--- a/chromium/cc/paint/oop_pixeltest.cc
+++ b/chromium/cc/paint/oop_pixeltest.cc
@@ -82,8 +82,16 @@ class OopPixelTest : public testing::Test,
/*enable_oop_rasterization=*/false, /*support_locking=*/true);
gpu::ContextResult result = gles2_context_provider_->BindToCurrentThread();
DCHECK_EQ(result, gpu::ContextResult::kSuccess);
- CHECK_EQ(gles2_context_provider_->ContextCapabilities().max_texture_size,
- raster_context_provider_->ContextCapabilities().max_texture_size);
+ const int gles2_max_texture_size =
+ gles2_context_provider_->ContextCapabilities().max_texture_size;
+ gpu_image_cache_.reset(new GpuImageDecodeCache(
+ gles2_context_provider_.get(), false, kRGBA_8888_SkColorType,
+ kWorkingSetSize, gles2_max_texture_size,
+ PaintImage::kDefaultGeneratorClientId));
+
+ const int raster_max_texture_size =
+ raster_context_provider_->ContextCapabilities().max_texture_size;
+ ASSERT_EQ(raster_max_texture_size, gles2_max_texture_size);
}
// gpu::raster::GrShaderCache::Client implementation.
@@ -100,24 +108,12 @@ class OopPixelTest : public testing::Test,
&gr_shader_cache_, &activity_flags_);
gpu::ContextResult result = raster_context_provider_->BindToCurrentThread();
DCHECK_EQ(result, gpu::ContextResult::kSuccess);
- }
-
- void CreateGpuImageCache(const gfx::ColorSpace& color_space) {
- const int gles2_max_texture_size =
- raster_context_provider_->ContextCapabilities().max_texture_size;
- gpu_image_cache_.reset(new GpuImageDecodeCache(
- gles2_context_provider_.get(), false, kRGBA_8888_SkColorType,
- kWorkingSetSize, gles2_max_texture_size,
- PaintImage::kDefaultGeneratorClientId, color_space.ToSkColorSpace()));
- }
-
- void CreateOopImageCache(const gfx::ColorSpace& color_space) {
const int raster_max_texture_size =
raster_context_provider_->ContextCapabilities().max_texture_size;
oop_image_cache_.reset(new GpuImageDecodeCache(
raster_context_provider_.get(), true, kRGBA_8888_SkColorType,
kWorkingSetSize, raster_max_texture_size,
- PaintImage::kDefaultGeneratorClientId, color_space.ToSkColorSpace()));
+ PaintImage::kDefaultGeneratorClientId));
}
class RasterOptions {
@@ -156,13 +152,12 @@ class OopPixelTest : public testing::Test,
SkBitmap Raster(scoped_refptr<DisplayItemList> display_item_list,
const RasterOptions& options) {
- CreateOopImageCache(options.color_space);
-
GURL url("https://example.com/foo");
TestInProcessContextProvider::ScopedRasterContextLock lock(
raster_context_provider_.get(), url.possibly_invalid_spec().c_str());
PlaybackImageProvider image_provider(oop_image_cache_.get(),
+ options.color_space,
PlaybackImageProvider::Settings());
gpu::gles2::GLES2Interface* gl = gles2_context_provider_->ContextGL();
@@ -263,8 +258,6 @@ class OopPixelTest : public testing::Test,
SkBitmap RasterExpectedBitmap(
scoped_refptr<DisplayItemList> display_item_list,
const RasterOptions& options) {
- CreateGpuImageCache(options.color_space);
-
TestInProcessContextProvider::ScopedRasterContextLock lock(
gles2_context_provider_.get());
gles2_context_provider_->GrContext()->resetContext();
@@ -286,6 +279,7 @@ class OopPixelTest : public testing::Test,
options.shader_with_animated_images->set_has_animated_images(true);
PlaybackImageProvider image_provider(gpu_image_cache_.get(),
+ options.color_space,
PlaybackImageProvider::Settings());
auto raster_source = recording.CreateRasterSource();
diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc
index 7c047cd1019..1359b6362e6 100644
--- a/chromium/cc/paint/paint_op_buffer.cc
+++ b/chromium/cc/paint/paint_op_buffer.cc
@@ -1207,22 +1207,9 @@ void DrawImageOp::RasterWithFlags(const DrawImageOp* op,
const PaintFlags* flags,
SkCanvas* canvas,
const PlaybackParams& params) {
- // TODO(crbug.com/931704): make sure to support the case where paint worklet
- // generated images are used in other raster work such as canvas2d.
+ DCHECK(!op->image.IsPaintWorklet());
SkPaint paint = flags ? flags->ToSkPaint() : SkPaint();
- if (op->image.IsPaintWorklet()) {
- DCHECK(params.image_provider);
- ImageProvider::ScopedResult result =
- params.image_provider->GetRasterContent(DrawImage(op->image));
-
- DCHECK(IsScaleAdjustmentIdentity(op->scale_adjustment));
- SkAutoCanvasRestore save_restore(canvas, true);
- canvas->translate(op->left, op->top);
- result.paint_record()->Playback(canvas, params);
- return;
- }
-
if (!params.image_provider) {
const bool needs_scale = !IsScaleAdjustmentIdentity(op->scale_adjustment);
SkAutoCanvasRestore save_restore(canvas, needs_scale);
@@ -1261,15 +1248,32 @@ void DrawImageOp::RasterWithFlags(const DrawImageOp* op,
canvas->drawImage(decoded_image.image().get(), op->left, op->top, &paint);
}
-// TODO(xidachen): ensure paint worklet generated images are correctly handled.
void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
const PaintFlags* flags,
SkCanvas* canvas,
const PlaybackParams& params) {
+ SkPaint paint = flags ? flags->ToSkPaint() : SkPaint();
+ // TODO(crbug.com/931704): make sure to support the case where paint worklet
+ // generated images are used in other raster work such as canvas2d.
+ if (op->image.IsPaintWorklet()) {
+ DCHECK(params.image_provider);
+ ImageProvider::ScopedResult result =
+ params.image_provider->GetRasterContent(DrawImage(op->image));
+
+ DCHECK(IsScaleAdjustmentIdentity(op->scale_adjustment));
+ SkAutoCanvasRestore save_restore(canvas, true);
+ canvas->concat(
+ SkMatrix::MakeRectToRect(op->src, op->dst, SkMatrix::kFill_ScaleToFit));
+ canvas->clipRect(op->src);
+ canvas->saveLayer(&op->src, &paint);
+ DCHECK(result && result.paint_record());
+ result.paint_record()->Playback(canvas, params);
+ return;
+ }
+
// TODO(enne): Probably PaintCanvas should just use the skia enum directly.
SkCanvas::SrcRectConstraint skconstraint =
static_cast<SkCanvas::SrcRectConstraint>(op->constraint);
- SkPaint paint = flags ? flags->ToSkPaint() : SkPaint();
if (!params.image_provider) {
SkRect adjusted_src = AdjustSrcRectForScale(op->src, op->scale_adjustment);
diff --git a/chromium/cc/paint/paint_op_buffer_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
index d7fcd2edcb7..7e033867dfa 100644
--- a/chromium/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
@@ -35,6 +35,7 @@ class FontSupport : public gpu::ServiceFontManager::Client {
return it->second;
return CreateBuffer(shm_id);
}
+ void ReportProgress() override {}
private:
scoped_refptr<gpu::Buffer> CreateBuffer(uint32_t shm_id) {
diff --git a/chromium/cc/paint/paint_op_buffer_unittest.cc b/chromium/cc/paint/paint_op_buffer_unittest.cc
index 0f6f7b74eca..f40f19a4ac6 100644
--- a/chromium/cc/paint/paint_op_buffer_unittest.cc
+++ b/chromium/cc/paint/paint_op_buffer_unittest.cc
@@ -439,6 +439,18 @@ TEST(PaintOpBufferTest, DiscardableImagesTracking_PaintWorkletImage) {
EXPECT_TRUE(buffer.HasDiscardableImages());
}
+TEST(PaintOpBufferTest, DiscardableImagesTracking_PaintWorkletImageRect) {
+ scoped_refptr<TestPaintWorkletInput> input =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(32.0f, 32.0f));
+ PaintOpBuffer buffer;
+ PaintImage image = CreatePaintWorkletPaintImage(input);
+ SkRect src = SkRect::MakeEmpty();
+ SkRect dst = SkRect::MakeEmpty();
+ buffer.push<DrawImageRectOp>(image, src, dst, nullptr,
+ PaintCanvas::kStrict_SrcRectConstraint);
+ EXPECT_TRUE(buffer.HasDiscardableImages());
+}
+
TEST(PaintOpBufferTest, DiscardableImagesTracking_DrawImageRect) {
PaintOpBuffer buffer;
PaintImage image = CreateDiscardablePaintImage(gfx::Size(100, 100));
@@ -2844,7 +2856,7 @@ MATCHER_P2(MatchesShader, flags, scale, "") {
return true;
}
-TEST(PaintOpBufferTest, RasterPaintWorkletImage1) {
+TEST(PaintOpBufferTest, RasterPaintWorkletImageRectBasicCase) {
sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>();
PaintFlags noop_flags;
SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 100, 100);
@@ -2862,22 +2874,29 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImage1) {
scoped_refptr<TestPaintWorkletInput> input =
base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100));
PaintImage image = CreatePaintWorkletPaintImage(input);
- blink_buffer.push<DrawImageOp>(image, 0.0f, 0.0f, nullptr);
+ SkRect src = SkRect::MakeXYWH(0, 0, 100, 100);
+ SkRect dst = SkRect::MakeXYWH(0, 0, 100, 100);
+ blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr,
+ PaintCanvas::kStrict_SrcRectConstraint);
testing::StrictMock<MockCanvas> canvas;
testing::Sequence s;
EXPECT_CALL(canvas, willSave()).InSequence(s);
+ EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
+ EXPECT_CALL(canvas, willSave()).InSequence(s);
EXPECT_CALL(canvas, didConcat(SkMatrix::MakeTrans(8.0f, 8.0f)));
EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
EXPECT_CALL(canvas, OnDrawRectWithColor(0u));
EXPECT_CALL(canvas, willRestore()).InSequence(s);
EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
blink_buffer.Playback(&canvas, PlaybackParams(&provider));
}
-TEST(PaintOpBufferTest, RasterPaintWorkletImage2) {
+TEST(PaintOpBufferTest, RasterPaintWorkletImageRectTranslated) {
sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>();
PaintFlags noop_flags;
SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 10, 10);
@@ -2897,13 +2916,107 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImage2) {
scoped_refptr<TestPaintWorkletInput> input =
base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100));
PaintImage image = CreatePaintWorkletPaintImage(input);
- blink_buffer.push<DrawImageOp>(image, 5.0f, 7.0f, nullptr);
+ SkRect src = SkRect::MakeXYWH(0, 0, 100, 100);
+ SkRect dst = SkRect::MakeXYWH(5, 7, 100, 100);
+ blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr,
+ PaintCanvas::kStrict_SrcRectConstraint);
testing::StrictMock<MockCanvas> canvas;
testing::Sequence s;
EXPECT_CALL(canvas, willSave()).InSequence(s);
+ EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
+ EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
EXPECT_CALL(canvas, didConcat(SkMatrix::MakeTrans(5.0f, 7.0f)));
+ EXPECT_CALL(canvas, willSave()).InSequence(s);
+ EXPECT_CALL(canvas, didConcat(MatchesInvScale(scale_adjustment[0])));
+ EXPECT_CALL(canvas, onDrawImage(NonLazyImage(), 0.0f, 0.0f,
+ MatchesQuality(quality[0])));
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+
+ blink_buffer.Playback(&canvas, PlaybackParams(&provider));
+}
+
+TEST(PaintOpBufferTest, RasterPaintWorkletImageRectScaled) {
+ sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>();
+ PaintFlags noop_flags;
+ SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 10, 10);
+ paint_worklet_buffer->push<SaveLayerOp>(&savelayer_rect, &noop_flags);
+ PaintFlags draw_flags;
+ draw_flags.setFilterQuality(kLow_SkFilterQuality);
+ PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10));
+ paint_worklet_buffer->push<DrawImageOp>(paint_image, 0.0f, 0.0f, &draw_flags);
+
+ std::vector<SkSize> src_rect_offset = {SkSize::MakeEmpty()};
+ std::vector<SkSize> scale_adjustment = {SkSize::Make(0.2f, 0.2f)};
+ std::vector<SkFilterQuality> quality = {kHigh_SkFilterQuality};
+ MockImageProvider provider(src_rect_offset, scale_adjustment, quality);
+ provider.SetRecord(paint_worklet_buffer);
+
+ PaintOpBuffer blink_buffer;
+ scoped_refptr<TestPaintWorkletInput> input =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100));
+ PaintImage image = CreatePaintWorkletPaintImage(input);
+ SkRect src = SkRect::MakeXYWH(0, 0, 100, 100);
+ SkRect dst = SkRect::MakeXYWH(0, 0, 200, 150);
+ blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr,
+ PaintCanvas::kStrict_SrcRectConstraint);
+
+ testing::StrictMock<MockCanvas> canvas;
+ testing::Sequence s;
+
+ EXPECT_CALL(canvas, willSave()).InSequence(s);
+ EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
+ EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
+ EXPECT_CALL(canvas, didConcat(SkMatrix::MakeScale(2.f, 1.5f)));
+ EXPECT_CALL(canvas, willSave()).InSequence(s);
+ EXPECT_CALL(canvas, didConcat(MatchesInvScale(scale_adjustment[0])));
+ EXPECT_CALL(canvas, onDrawImage(NonLazyImage(), 0.0f, 0.0f,
+ MatchesQuality(quality[0])));
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
+
+ blink_buffer.Playback(&canvas, PlaybackParams(&provider));
+}
+
+TEST(PaintOpBufferTest, RasterPaintWorkletImageRectClipped) {
+ sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>();
+ PaintFlags noop_flags;
+ SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 60, 60);
+ paint_worklet_buffer->push<SaveLayerOp>(&savelayer_rect, &noop_flags);
+ PaintFlags draw_flags;
+ draw_flags.setFilterQuality(kLow_SkFilterQuality);
+ PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10));
+ // One rect inside the src-rect, one outside.
+ paint_worklet_buffer->push<DrawImageOp>(paint_image, 0.0f, 0.0f, &draw_flags);
+ paint_worklet_buffer->push<DrawImageOp>(paint_image, 50.0f, 50.0f,
+ &draw_flags);
+
+ std::vector<SkSize> src_rect_offset = {SkSize::MakeEmpty()};
+ std::vector<SkSize> scale_adjustment = {SkSize::Make(0.2f, 0.2f)};
+ std::vector<SkFilterQuality> quality = {kHigh_SkFilterQuality};
+ MockImageProvider provider(src_rect_offset, scale_adjustment, quality);
+ provider.SetRecord(paint_worklet_buffer);
+
+ PaintOpBuffer blink_buffer;
+ scoped_refptr<TestPaintWorkletInput> input =
+ base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100));
+ PaintImage image = CreatePaintWorkletPaintImage(input);
+ SkRect src = SkRect::MakeXYWH(0, 0, 20, 20);
+ SkRect dst = SkRect::MakeXYWH(0, 0, 20, 20);
+ blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr,
+ PaintCanvas::kStrict_SrcRectConstraint);
+
+ testing::StrictMock<MockCanvas> canvas;
+ testing::Sequence s;
+
+ EXPECT_CALL(canvas, willSave()).InSequence(s);
+ EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s);
EXPECT_CALL(canvas, willSave()).InSequence(s);
EXPECT_CALL(canvas, didConcat(MatchesInvScale(scale_adjustment[0])));
@@ -2912,6 +3025,7 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImage2) {
EXPECT_CALL(canvas, willRestore()).InSequence(s);
EXPECT_CALL(canvas, willRestore()).InSequence(s);
EXPECT_CALL(canvas, willRestore()).InSequence(s);
+ EXPECT_CALL(canvas, willRestore()).InSequence(s);
blink_buffer.Playback(&canvas, PlaybackParams(&provider));
}
diff --git a/chromium/cc/paint/paint_op_reader.cc b/chromium/cc/paint/paint_op_reader.cc
index 74366585d97..6dd4d8bb6a4 100644
--- a/chromium/cc/paint/paint_op_reader.cc
+++ b/chromium/cc/paint/paint_op_reader.cc
@@ -357,6 +357,7 @@ void PaintOpReader::Read(PaintImage* image) {
if (transfer_cache_entry_id == kInvalidImageTransferCacheEntryId)
return;
+ // The transfer cache entry for an image may not exist if the upload fails.
if (auto* entry =
options_.transfer_cache->GetEntryAs<ServiceImageTransferCacheEntry>(
transfer_cache_entry_id)) {
@@ -366,10 +367,6 @@ void PaintOpReader::Read(PaintImage* image) {
.set_id(PaintImage::GetNextId())
.set_image(entry->image(), PaintImage::kNonLazyStableId)
.TakePaintImage();
- } else {
- // If a transfer cache id exists, we must have a valid entry for it in the
- // cache.
- SetInvalid();
}
}
diff --git a/chromium/cc/paint/record_paint_canvas.cc b/chromium/cc/paint/record_paint_canvas.cc
index 836565414f8..b0277f51a5b 100644
--- a/chromium/cc/paint/record_paint_canvas.cc
+++ b/chromium/cc/paint/record_paint_canvas.cc
@@ -246,6 +246,7 @@ void RecordPaintCanvas::drawImage(const PaintImage& image,
SkScalar left,
SkScalar top,
const PaintFlags* flags) {
+ DCHECK(!image.IsPaintWorklet());
list_->push<DrawImageOp>(image, left, top, flags);
}
diff --git a/chromium/cc/paint/render_surface_filters.cc b/chromium/cc/paint/render_surface_filters.cc
index d82fdd069fa..0a9cb8bca72 100644
--- a/chromium/cc/paint/render_surface_filters.cc
+++ b/chromium/cc/paint/render_surface_filters.cc
@@ -11,6 +11,7 @@
#include "cc/paint/filter_operation.h"
#include "cc/paint/filter_operations.h"
#include "cc/paint/paint_filter.h"
+#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/effects/SkAlphaThresholdFilter.h"
@@ -26,31 +27,31 @@ namespace cc {
namespace {
-void GetBrightnessMatrix(float amount, SkScalar matrix[20]) {
+void GetBrightnessMatrix(float amount, float matrix[20]) {
// Spec implementation
// (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent)
// <feFunc[R|G|B] type="linear" slope="[amount]">
- memset(matrix, 0, 20 * sizeof(SkScalar));
+ memset(matrix, 0, 20 * sizeof(float));
matrix[0] = matrix[6] = matrix[12] = amount;
matrix[18] = 1.f;
}
-void GetSaturatingBrightnessMatrix(float amount, SkScalar matrix[20]) {
+void GetSaturatingBrightnessMatrix(float amount, float matrix[20]) {
// Legacy implementation used by internal clients.
// <feFunc[R|G|B] type="linear" intercept="[amount]"/>
- memset(matrix, 0, 20 * sizeof(SkScalar));
+ memset(matrix, 0, 20 * sizeof(float));
matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
- matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
+ matrix[4] = matrix[9] = matrix[14] = amount;
}
-void GetContrastMatrix(float amount, SkScalar matrix[20]) {
- memset(matrix, 0, 20 * sizeof(SkScalar));
+void GetContrastMatrix(float amount, float matrix[20]) {
+ memset(matrix, 0, 20 * sizeof(float));
matrix[0] = matrix[6] = matrix[12] = amount;
- matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255.f;
+ matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f);
matrix[18] = 1.f;
}
-void GetSaturateMatrix(float amount, SkScalar matrix[20]) {
+void GetSaturateMatrix(float amount, float matrix[20]) {
// Note, these values are computed to ensure MatrixNeedsClamping is false
// for amount in [0..1]
matrix[0] = 0.213f + 0.787f * amount;
@@ -69,7 +70,7 @@ void GetSaturateMatrix(float amount, SkScalar matrix[20]) {
matrix[18] = 1.f;
}
-void GetHueRotateMatrix(float hue, SkScalar matrix[20]) {
+void GetHueRotateMatrix(float hue, float matrix[20]) {
float cos_hue = cosf(hue * base::kPiFloat / 180.f);
float sin_hue = sinf(hue * base::kPiFloat / 180.f);
matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f;
@@ -89,20 +90,20 @@ void GetHueRotateMatrix(float hue, SkScalar matrix[20]) {
matrix[19] = 0.f;
}
-void GetInvertMatrix(float amount, SkScalar matrix[20]) {
- memset(matrix, 0, 20 * sizeof(SkScalar));
+void GetInvertMatrix(float amount, float matrix[20]) {
+ memset(matrix, 0, 20 * sizeof(float));
matrix[0] = matrix[6] = matrix[12] = 1.f - 2.f * amount;
- matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
+ matrix[4] = matrix[9] = matrix[14] = amount;
matrix[18] = 1.f;
}
-void GetOpacityMatrix(float amount, SkScalar matrix[20]) {
- memset(matrix, 0, 20 * sizeof(SkScalar));
+void GetOpacityMatrix(float amount, float matrix[20]) {
+ memset(matrix, 0, 20 * sizeof(float));
matrix[0] = matrix[6] = matrix[12] = 1.f;
matrix[18] = amount;
}
-void GetGrayscaleMatrix(float amount, SkScalar matrix[20]) {
+void GetGrayscaleMatrix(float amount, float matrix[20]) {
// Note, these values are computed to ensure MatrixNeedsClamping is false
// for amount in [0..1]
matrix[0] = 0.2126f + 0.7874f * amount;
@@ -124,7 +125,7 @@ void GetGrayscaleMatrix(float amount, SkScalar matrix[20]) {
matrix[18] = 1.f;
}
-void GetSepiaMatrix(float amount, SkScalar matrix[20]) {
+void GetSepiaMatrix(float amount, float matrix[20]) {
matrix[0] = 0.393f + 0.607f * amount;
matrix[1] = 0.769f - 0.769f * amount;
matrix[2] = 0.189f - 0.189f * amount;
@@ -144,10 +145,10 @@ void GetSepiaMatrix(float amount, SkScalar matrix[20]) {
matrix[18] = 1.f;
}
-sk_sp<PaintFilter> CreateMatrixImageFilter(const SkScalar matrix[20],
+sk_sp<PaintFilter> CreateMatrixImageFilter(const float matrix[20],
sk_sp<PaintFilter> input) {
- return sk_make_sp<ColorFilterPaintFilter>(
- SkColorFilters::MatrixRowMajor255(matrix), std::move(input));
+ return sk_make_sp<ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix),
+ std::move(input));
}
} // namespace
@@ -157,7 +158,7 @@ sk_sp<PaintFilter> RenderSurfaceFilters::BuildImageFilter(
const gfx::SizeF& size,
const gfx::Vector2dF& offset) {
sk_sp<PaintFilter> image_filter;
- SkScalar matrix[20];
+ float matrix[20];
for (size_t i = 0; i < filters.size(); ++i) {
const FilterOperation& op = filters.at(i);
switch (op.type()) {
@@ -271,7 +272,7 @@ sk_sp<PaintFilter> RenderSurfaceFilters::BuildImageFilter(
has_input = !!color_paint_filter->input();
}
- if (cf && cf->asColorMatrix(matrix) && !has_input) {
+ if (cf && cf->asAColorMatrix(matrix) && !has_input) {
image_filter =
CreateMatrixImageFilter(matrix, std::move(image_filter));
} else if (image_filter) {
diff --git a/chromium/cc/paint/skia_paint_canvas.cc b/chromium/cc/paint/skia_paint_canvas.cc
index 17829b3eb1a..45e6e8fd6a0 100644
--- a/chromium/cc/paint/skia_paint_canvas.cc
+++ b/chromium/cc/paint/skia_paint_canvas.cc
@@ -241,6 +241,7 @@ void SkiaPaintCanvas::drawImage(const PaintImage& image,
SkScalar left,
SkScalar top,
const PaintFlags* flags) {
+ DCHECK(!image.IsPaintWorklet());
base::Optional<ScopedRasterFlags> scoped_flags;
if (flags) {
scoped_flags.emplace(flags, image_provider_, canvas_->getTotalMatrix(),
diff --git a/chromium/cc/paint/transfer_cache_unittest.cc b/chromium/cc/paint/transfer_cache_unittest.cc
index 7b606ab9110..7eb83e82dd2 100644
--- a/chromium/cc/paint/transfer_cache_unittest.cc
+++ b/chromium/cc/paint/transfer_cache_unittest.cc
@@ -11,6 +11,7 @@
#include "cc/paint/raw_memory_transfer_cache_entry.h"
#include "cc/paint/transfer_cache_entry.h"
#include "cc/test/test_in_process_context_provider.h"
+#include "components/viz/test/test_gpu_service_holder.h"
#include "gpu/command_buffer/client/client_transfer_cache.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
@@ -20,7 +21,6 @@
#include "gpu/command_buffer/service/service_transfer_cache.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/ipc/raster_in_process_context.h"
-#include "gpu/ipc/test_gpu_thread_holder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkImage.h"
#include "ui/gl/gl_implementation.h"
@@ -48,7 +48,7 @@ class TransferCacheTest : public testing::Test {
context_ = std::make_unique<gpu::RasterInProcessContext>();
auto result = context_->Initialize(
- gpu::GetTestGpuThreadHolder()->GetTaskExecutor(), attribs,
+ viz::TestGpuServiceHolder::GetInstance()->task_executor(), attribs,
gpu::SharedMemoryLimits(), &gpu_memory_buffer_manager_, &image_factory_,
/*gpu_channel_manager_delegate=*/nullptr, nullptr, nullptr);
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
index f94e220c0f0..754ff6979a0 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
@@ -9,6 +9,7 @@
#include <algorithm>
+#include "base/memory/shared_memory_mapping.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
@@ -32,12 +33,12 @@ class BitmapSoftwareBacking : public ResourcePool::SoftwareBacking {
const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
uint64_t tracing_process_id,
int importance) const override {
- pmd->CreateSharedMemoryOwnershipEdge(
- buffer_dump_guid, shared_memory->mapped_id(), importance);
+ pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid, mapping.guid(),
+ importance);
}
LayerTreeFrameSink* frame_sink;
- std::unique_ptr<base::SharedMemory> shared_memory;
+ base::WritableSharedMemoryMapping mapping;
};
class BitmapRasterBufferImpl : public RasterBuffer {
@@ -107,14 +108,12 @@ BitmapRasterBufferProvider::AcquireBufferForRaster(
auto backing = std::make_unique<BitmapSoftwareBacking>();
backing->frame_sink = frame_sink_;
backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
- backing->shared_memory =
- viz::bitmap_allocation::AllocateMappedBitmap(size, viz::RGBA_8888);
-
- mojo::ScopedSharedBufferHandle handle =
- viz::bitmap_allocation::DuplicateAndCloseMappedBitmap(
- backing->shared_memory.get(), size, viz::RGBA_8888);
- frame_sink_->DidAllocateSharedBitmap(std::move(handle),
- backing->shared_bitmap_id);
+ base::MappedReadOnlyRegion mapped_region =
+ viz::bitmap_allocation::AllocateSharedBitmap(size, viz::RGBA_8888);
+ backing->mapping = std::move(mapped_region.mapping);
+ frame_sink_->DidAllocateSharedBitmap(
+ viz::bitmap_allocation::ToMojoHandle(std::move(mapped_region.region)),
+ backing->shared_bitmap_id);
resource.set_software_backing(std::move(backing));
}
@@ -122,7 +121,7 @@ BitmapRasterBufferProvider::AcquireBufferForRaster(
static_cast<BitmapSoftwareBacking*>(resource.software_backing());
return std::make_unique<BitmapRasterBufferImpl>(
- size, color_space, backing->shared_memory->memory(), resource_content_id,
+ size, color_space, backing->mapping.memory(), resource_content_id,
previous_content_id);
}
@@ -132,13 +131,6 @@ viz::ResourceFormat BitmapRasterBufferProvider::GetResourceFormat() const {
return viz::RGBA_8888;
}
-bool BitmapRasterBufferProvider::IsResourceSwizzleRequired() const {
- // This value only used by gpu compositing. Software compositing resources
- // are all in the native skia byte ordering, and the display compositor will
- // do its drawing in the same order.
- return false;
-}
-
bool BitmapRasterBufferProvider::IsResourcePremultiplied() const {
return true;
}
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.h b/chromium/cc/raster/bitmap_raster_buffer_provider.h
index e91ac1a4248..bdf1fc8d06d 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.h
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.h
@@ -36,7 +36,6 @@ class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider {
uint64_t previous_content_id) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
- bool IsResourceSwizzleRequired() const override;
bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc
index 45f9f93d6d9..79c32f61b5d 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.cc
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc
@@ -386,11 +386,6 @@ viz::ResourceFormat GpuRasterBufferProvider::GetResourceFormat() const {
return tile_format_;
}
-bool GpuRasterBufferProvider::IsResourceSwizzleRequired() const {
- // This doesn't require a swizzle because we rasterize to the correct format.
- return false;
-}
-
bool GpuRasterBufferProvider::IsResourcePremultiplied() const {
return !ShouldUnpremultiplyAndDitherResource(GetResourceFormat());
}
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.h b/chromium/cc/raster/gpu_raster_buffer_provider.h
index 52fb765d560..e6a435978a7 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.h
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.h
@@ -48,7 +48,6 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
uint64_t previous_content_id) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
- bool IsResourceSwizzleRequired() const override;
bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
index 4a248642b8d..daf5a89f012 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
@@ -189,10 +189,6 @@ viz::ResourceFormat OneCopyRasterBufferProvider::GetResourceFormat() const {
return tile_format_;
}
-bool OneCopyRasterBufferProvider::IsResourceSwizzleRequired() const {
- return !viz::PlatformColor::SameComponentOrder(GetResourceFormat());
-}
-
bool OneCopyRasterBufferProvider::IsResourcePremultiplied() const {
// TODO(ericrk): Handle unpremultiply/dither in one-copy case as well.
// https://crbug.com/789153
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.h b/chromium/cc/raster/one_copy_raster_buffer_provider.h
index a307c01cfb6..370e6cbf43c 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.h
@@ -51,7 +51,6 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
uint64_t previous_content_id) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
- bool IsResourceSwizzleRequired() const override;
bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
diff --git a/chromium/cc/raster/playback_image_provider.cc b/chromium/cc/raster/playback_image_provider.cc
index 4e8cff91335..cbda15cb848 100644
--- a/chromium/cc/raster/playback_image_provider.cc
+++ b/chromium/cc/raster/playback_image_provider.cc
@@ -19,8 +19,10 @@ void UnrefImageFromCache(DrawImage draw_image,
PlaybackImageProvider::PlaybackImageProvider(
ImageDecodeCache* cache,
+ const gfx::ColorSpace& target_color_space,
base::Optional<Settings>&& settings)
: cache_(cache),
+ target_color_space_(target_color_space),
settings_(std::move(settings)) {
DCHECK(cache_);
}
@@ -53,7 +55,7 @@ ImageProvider::ScopedResult PlaybackImageProvider::GetRasterContent(
? PaintImage::kDefaultFrameIndex
: it->second;
- DrawImage adjusted_image(draw_image, 1.f, frame_index);
+ DrawImage adjusted_image(draw_image, 1.f, frame_index, target_color_space_);
if (!cache_->UseCacheForDrawImage(adjusted_image)) {
return ScopedResult(DecodedDrawImage(
paint_image.GetSkImage(), SkSize::Make(0, 0), SkSize::Make(1.f, 1.f),
diff --git a/chromium/cc/raster/playback_image_provider.h b/chromium/cc/raster/playback_image_provider.h
index 864ec2568ac..70991ca2692 100644
--- a/chromium/cc/raster/playback_image_provider.h
+++ b/chromium/cc/raster/playback_image_provider.h
@@ -37,6 +37,7 @@ class CC_EXPORT PlaybackImageProvider : public ImageProvider {
// If no settings are provided, all images are skipped during rasterization.
PlaybackImageProvider(ImageDecodeCache* cache,
+ const gfx::ColorSpace& target_color_space,
base::Optional<Settings>&& settings);
PlaybackImageProvider(const PlaybackImageProvider&) = delete;
PlaybackImageProvider(PlaybackImageProvider&& other);
@@ -51,6 +52,7 @@ class CC_EXPORT PlaybackImageProvider : public ImageProvider {
private:
ImageDecodeCache* cache_;
+ gfx::ColorSpace target_color_space_;
base::Optional<Settings> settings_;
};
diff --git a/chromium/cc/raster/playback_image_provider_unittest.cc b/chromium/cc/raster/playback_image_provider_unittest.cc
index c5995098160..28d26f9e6b0 100644
--- a/chromium/cc/raster/playback_image_provider_unittest.cc
+++ b/chromium/cc/raster/playback_image_provider_unittest.cc
@@ -66,7 +66,7 @@ class MockDecodeCache : public StubDecodeCache {
TEST(PlaybackImageProviderTest, SkipsAllImages) {
MockDecodeCache cache;
- PlaybackImageProvider provider(&cache, base::nullopt);
+ PlaybackImageProvider provider(&cache, gfx::ColorSpace(), base::nullopt);
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
@@ -93,7 +93,8 @@ TEST(PlaybackImageProviderTest, SkipsSomeImages) {
settings.emplace();
settings->images_to_skip = {skip_image.stable_id()};
- PlaybackImageProvider provider(&cache, std::move(settings));
+ PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
+ std::move(settings));
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
@@ -107,7 +108,8 @@ TEST(PlaybackImageProviderTest, RefAndUnrefDecode) {
base::Optional<PlaybackImageProvider::Settings> settings;
settings.emplace();
- PlaybackImageProvider provider(&cache, std::move(settings));
+ PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
+ std::move(settings));
{
SkRect rect = SkRect::MakeWH(10, 10);
@@ -135,7 +137,8 @@ TEST(PlaybackImageProviderTest, SwapsGivenFrames) {
settings.emplace();
settings->image_to_current_frame_index = image_to_frame;
- PlaybackImageProvider provider(&cache, std::move(settings));
+ PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
+ std::move(settings));
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
@@ -151,7 +154,8 @@ TEST(PlaybackImageProviderTest, BitmapImages) {
base::Optional<PlaybackImageProvider::Settings> settings;
settings.emplace();
- PlaybackImageProvider provider(&cache, std::move(settings));
+ PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
+ std::move(settings));
{
SkIRect rect = SkIRect::MakeWH(10, 10);
@@ -172,7 +176,8 @@ TEST(PlaybackImageProviderTest, IgnoresImagesNotSupportedByCache) {
cache.set_use_cache_for_draw_image(false);
base::Optional<PlaybackImageProvider::Settings> settings;
settings.emplace();
- PlaybackImageProvider provider(&cache, std::move(settings));
+ PlaybackImageProvider provider(&cache, gfx::ColorSpace(),
+ std::move(settings));
{
SkIRect rect = SkIRect::MakeWH(10, 10);
SkMatrix matrix = SkMatrix::I();
diff --git a/chromium/cc/raster/raster_buffer_provider.cc b/chromium/cc/raster/raster_buffer_provider.cc
index f5935e2f90c..6252168a3b1 100644
--- a/chromium/cc/raster/raster_buffer_provider.cc
+++ b/chromium/cc/raster/raster_buffer_provider.cc
@@ -72,10 +72,13 @@ void RasterBufferProvider::PlaybackToMemory(
DCHECK(IsSupportedPlaybackToMemoryFormat(format)) << format;
+ SkColorType color_type =
+ ResourceFormatToClosestSkColorType(gpu_compositing, format);
+
// Uses kPremul_SkAlphaType since the result is not known to be opaque.
- SkImageInfo info =
- SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType,
- target_color_space.ToSkColorSpace());
+ SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), color_type,
+ kPremul_SkAlphaType,
+ target_color_space.ToSkColorSpace());
// Use unknown pixel geometry to disable LCD text.
SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry);
diff --git a/chromium/cc/raster/raster_buffer_provider.h b/chromium/cc/raster/raster_buffer_provider.h
index a4755ccfda0..a23befca140 100644
--- a/chromium/cc/raster/raster_buffer_provider.h
+++ b/chromium/cc/raster/raster_buffer_provider.h
@@ -61,9 +61,6 @@ class CC_EXPORT RasterBufferProvider {
// Returns the format to use for the tiles.
virtual viz::ResourceFormat GetResourceFormat() const = 0;
- // Determine if the resource requires swizzling.
- virtual bool IsResourceSwizzleRequired() const = 0;
-
// Determines if the resource is premultiplied.
virtual bool IsResourcePremultiplied() const = 0;
diff --git a/chromium/cc/raster/raster_source_unittest.cc b/chromium/cc/raster/raster_source_unittest.cc
index 21338cf9c19..0bd9e4fc367 100644
--- a/chromium/cc/raster/raster_source_unittest.cc
+++ b/chromium/cc/raster/raster_source_unittest.cc
@@ -266,19 +266,25 @@ TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) {
// Tile sized iterators. These should find only one pixel ref.
{
+ gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB();
std::vector<const DrawImage*> images;
raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), &images);
EXPECT_EQ(1u, images.size());
- DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex);
+ DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex,
+ target_color_space);
EXPECT_EQ(discardable_image[0][0], images[0]->paint_image());
+ EXPECT_EQ(target_color_space, image.target_color_space());
}
// Shifted tile sized iterators. These should find only one pixel ref.
{
+ gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50();
std::vector<const DrawImage*> images;
raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), &images);
EXPECT_EQ(1u, images.size());
- DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex);
+ DrawImage image(*images[0], 1.f, PaintImage::kDefaultFrameIndex,
+ target_color_space);
EXPECT_EQ(discardable_image[1][1], images[0]->paint_image());
+ EXPECT_EQ(target_color_space, image.target_color_space());
}
// Ensure there's no discardable pixel refs in the empty cell
{
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
index 6f491eb7a47..bce36db08b2 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -204,10 +204,6 @@ viz::ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat() const {
return tile_format_;
}
-bool ZeroCopyRasterBufferProvider::IsResourceSwizzleRequired() const {
- return !viz::PlatformColor::SameComponentOrder(GetResourceFormat());
-}
-
bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const {
return true;
}
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.h b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
index 6bb0e333976..653228c7c65 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
@@ -42,7 +42,6 @@ class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
uint64_t previous_content_id) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
- bool IsResourceSwizzleRequired() const override;
bool IsResourcePremultiplied() const override;
bool CanPartialRasterIntoProvidedResource() const override;
bool IsResourceReadyToDraw(
diff --git a/chromium/cc/resources/cross_thread_shared_bitmap.cc b/chromium/cc/resources/cross_thread_shared_bitmap.cc
index 642bd39d89e..edd1e5234ef 100644
--- a/chromium/cc/resources/cross_thread_shared_bitmap.cc
+++ b/chromium/cc/resources/cross_thread_shared_bitmap.cc
@@ -6,12 +6,15 @@
namespace cc {
-CrossThreadSharedBitmap::CrossThreadSharedBitmap(
- const viz::SharedBitmapId& id,
- std::unique_ptr<base::SharedMemory> memory,
- const gfx::Size& size,
- viz::ResourceFormat format)
- : id_(id), memory_(std::move(memory)), size_(size), format_(format) {}
+CrossThreadSharedBitmap::CrossThreadSharedBitmap(const viz::SharedBitmapId& id,
+ base::MappedReadOnlyRegion shm,
+ const gfx::Size& size,
+ viz::ResourceFormat format)
+ : id_(id),
+ region_(std::move(shm.region)),
+ mapping_(std::move(shm.mapping)),
+ size_(size),
+ format_(format) {}
CrossThreadSharedBitmap::~CrossThreadSharedBitmap() = default;
diff --git a/chromium/cc/resources/cross_thread_shared_bitmap.h b/chromium/cc/resources/cross_thread_shared_bitmap.h
index f594ef19df5..6d7017a6ace 100644
--- a/chromium/cc/resources/cross_thread_shared_bitmap.h
+++ b/chromium/cc/resources/cross_thread_shared_bitmap.h
@@ -7,8 +7,9 @@
#include <memory>
+#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/shared_memory_mapping.h"
#include "cc/cc_export.h"
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/resources/shared_bitmap.h"
@@ -16,22 +17,25 @@
namespace cc {
-// This class holds ownership of a base::SharedMemory segment for use as a
-// composited resource, and is refcounted in order to share ownership with the
-// LayerTreeHost, via TextureLayer, which needs access to the base::SharedMemory
-// from the compositor thread.
-// Because all the fields exposed are const, they can be used from any thread
-// without conflict, as they only read existing states.
+// This class holds ownership of a base::ReadOnlySharedMemoryRegion and its
+// base::WritableSharedMemoryMapping for use as a composited resource, and is
+// refcounted in order to share ownership with the LayerTreeHost, via
+// TextureLayer, which needs access to the base::ReadOnlySharedMemory from
+// the compositor thread. Because all the fields exposed are const, they can
+// be used from any thread without conflict, as they only read existing states.
class CC_EXPORT CrossThreadSharedBitmap
: public base::RefCountedThreadSafe<CrossThreadSharedBitmap> {
public:
CrossThreadSharedBitmap(const viz::SharedBitmapId& id,
- std::unique_ptr<base::SharedMemory> memory,
+ base::MappedReadOnlyRegion shm,
const gfx::Size& size,
viz::ResourceFormat format);
const viz::SharedBitmapId& id() const { return id_; }
- const base::SharedMemory* shared_memory() const { return memory_.get(); }
+ const base::ReadOnlySharedMemoryRegion& shared_region() const {
+ return region_;
+ }
+ void* memory() const { return mapping_.memory(); }
const gfx::Size& size() const { return size_; }
viz::ResourceFormat format() const { return format_; }
@@ -41,7 +45,8 @@ class CC_EXPORT CrossThreadSharedBitmap
~CrossThreadSharedBitmap();
const viz::SharedBitmapId id_;
- const std::unique_ptr<const base::SharedMemory> memory_;
+ const base::ReadOnlySharedMemoryRegion region_;
+ base::WritableSharedMemoryMapping mapping_;
const gfx::Size size_;
const viz::ResourceFormat format_;
};
diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc
index 7818ee15a1f..9c73860e220 100644
--- a/chromium/cc/resources/resource_pool.cc
+++ b/chromium/cc/resources/resource_pool.cc
@@ -321,7 +321,7 @@ bool ResourcePool::PrepareForExport(const InUsePoolResource& in_use_resource) {
resource->mark_avoid_reuse();
return false;
}
- transferable = viz::TransferableResource::MakeGLOverlay(
+ transferable = viz::TransferableResource::MakeGL(
gpu_backing->mailbox, GL_LINEAR, gpu_backing->texture_target,
gpu_backing->mailbox_sync_token, resource->size(),
gpu_backing->overlay_candidate);
diff --git a/chromium/cc/scheduler/compositor_frame_reporting_controller.cc b/chromium/cc/scheduler/compositor_frame_reporting_controller.cc
index f1587ed158d..1b17021fd22 100644
--- a/chromium/cc/scheduler/compositor_frame_reporting_controller.cc
+++ b/chromium/cc/scheduler/compositor_frame_reporting_controller.cc
@@ -31,8 +31,8 @@ void CompositorFrameReportingController::WillBeginImplFrame() {
void CompositorFrameReportingController::WillBeginMainFrame() {
DCHECK(reporters_[PipelineStage::kBeginImplFrame]);
- DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame],
- reporters_[PipelineStage::kBeginImplFrame]);
+ DCHECK(reporters_[PipelineStage::kBeginMainFrame] !=
+ reporters_[PipelineStage::kBeginImplFrame]);
reporters_[PipelineStage::kBeginImplFrame]->StartStage(
"SendBeginMainFrameToCommit");
AdvanceReporterStage(PipelineStage::kBeginImplFrame,
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index 5fdf97c2ebf..f9fed94544d 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -933,17 +933,6 @@ bool Scheduler::ShouldDropBeginFrame(const viz::BeginFrameArgs& args) const {
return true;
}
- // We shouldn't be handling missed frames in the browser process (i.e. where
- // commit_to_active_tree is set) since we don't know if we should create a
- // frame at this time. Doing so leads to issues like crbug.com/882907. This
- // early-out is a short term fix to keep fling animations smooth.
- // TODO(bokan): In the long term, the display compositor should decide
- // whether to issue a missed frame; it is tracked in
- // https://crbug.com/930890.
- if (args.type == viz::BeginFrameArgs::MISSED &&
- settings_.commit_to_active_tree)
- return true;
-
return false;
}
diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc
index a4433d47f1d..29479c7dd3c 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine.cc
@@ -365,11 +365,6 @@ bool SchedulerStateMachine::ShouldDraw() const {
if (forced_redraw_state_ == ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW)
return true;
- // Delay draws when we have pending animation worklet updates to give them
- // time to produce output before we draw.
- if (processing_animation_worklets_for_active_tree_)
- return false;
-
return needs_redraw_;
}
diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
index 489cd110217..676b83ee4ae 100644
--- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -2725,7 +2725,7 @@ TEST(SchedulerStateMachineTest, AllowSkippingActiveTreeFirstDraws) {
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
}
-TEST(SchedulerStateMachineTest, BlockDrawIfAnimationWorkletsPending) {
+TEST(SchedulerStateMachineTest, DelayDrawIfAnimationWorkletsPending) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
@@ -2774,6 +2774,8 @@ TEST(SchedulerStateMachineTest, BlockDrawIfAnimationWorkletsPending) {
EXPECT_EQ(SchedulerStateMachine::BeginImplFrameDeadlineMode::IMMEDIATE,
state.CurrentBeginImplFrameDeadlineMode());
+ // AnimationWorkletState does not effect CanDraw, only whether an early draw
+ // deadline should be used (crbug/937975).
state.SetNeedsRedraw(true);
state.OnBeginImplFrameDeadline();
EXPECT_IMPL_FRAME_STATE(
@@ -2782,7 +2784,7 @@ TEST(SchedulerStateMachineTest, BlockDrawIfAnimationWorkletsPending) {
state.NotifyAnimationWorkletStateChange(
SchedulerStateMachine::AnimationWorkletState::PROCESSING,
SchedulerStateMachine::TreeType::ACTIVE);
- EXPECT_FALSE(state.ShouldDraw());
+ EXPECT_TRUE(state.ShouldDraw());
state.NotifyAnimationWorkletStateChange(
SchedulerStateMachine::AnimationWorkletState::IDLE,
SchedulerStateMachine::TreeType::ACTIVE);
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index 35c81fd8416..2f5deee74de 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -639,26 +639,6 @@ TEST_F(SchedulerTest, VideoNeedsBeginFrames) {
EXPECT_FALSE(scheduler_->begin_frames_expected());
}
-// As a short term fix for https://crbug.com/882907, we should skip MISSED
-// frames from the browser compositor.
-// TODO(bokan): In the long term, the display compositor should decide
-// whether to issue a missed frame; it is tracked in
-// https://crbug.com/930890.
-TEST_F(SchedulerTest, BrowserCompositorSkipsMissedBeginFrames) {
- scheduler_settings_.commit_to_active_tree = true;
- SetUpScheduler(EXTERNAL_BFS);
- scheduler_->SetNeedsBeginMainFrame();
-
- task_runner_->AdvanceMockTickClock(viz::BeginFrameArgs::DefaultInterval());
- viz::BeginFrameArgs args =
- fake_external_begin_frame_source_->CreateBeginFrameArgs(
- BEGINFRAME_FROM_HERE, task_runner_->GetMockTickClock());
- args.type = viz::BeginFrameArgs::MISSED;
-
- fake_external_begin_frame_source_->TestOnBeginFrame(args);
- EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-}
-
TEST_F(SchedulerTest, RequestCommit) {
SetUpScheduler(EXTERNAL_BFS);
diff --git a/chromium/cc/tiles/checker_image_tracker.cc b/chromium/cc/tiles/checker_image_tracker.cc
index 2308d922a35..6eda401d7a5 100644
--- a/chromium/cc/tiles/checker_image_tracker.cc
+++ b/chromium/cc/tiles/checker_image_tracker.cc
@@ -387,6 +387,7 @@ void CheckerImageTracker::UpdateDecodeState(const DrawImage& draw_image,
std::max(decode_state->scale.fHeight, draw_image.scale().fHeight));
decode_state->filter_quality =
std::max(decode_state->filter_quality, draw_image.filter_quality());
+ decode_state->color_space = draw_image.target_color_space();
decode_state->frame_index = draw_image.frame_index();
}
@@ -426,7 +427,7 @@ void CheckerImageTracker::ScheduleNextImageDecode() {
it->second.filter_quality,
SkMatrix::MakeScale(it->second.scale.width(),
it->second.scale.height()),
- it->second.frame_index);
+ it->second.frame_index, it->second.color_space);
outstanding_image_decode_.emplace(candidate);
break;
}
diff --git a/chromium/cc/tiles/checker_image_tracker.h b/chromium/cc/tiles/checker_image_tracker.h
index f59f5a27620..ee5578f8fef 100644
--- a/chromium/cc/tiles/checker_image_tracker.h
+++ b/chromium/cc/tiles/checker_image_tracker.h
@@ -139,6 +139,7 @@ class CC_EXPORT CheckerImageTracker {
DecodePolicy policy = DecodePolicy::SYNC;
SkFilterQuality filter_quality = kNone_SkFilterQuality;
SkSize scale = SkSize::MakeEmpty();
+ gfx::ColorSpace color_space;
size_t frame_index = PaintImage::kDefaultFrameIndex;
};
diff --git a/chromium/cc/tiles/checker_image_tracker_unittest.cc b/chromium/cc/tiles/checker_image_tracker_unittest.cc
index 44cba670c23..47dc8ab1306 100644
--- a/chromium/cc/tiles/checker_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/checker_image_tracker_unittest.cc
@@ -125,7 +125,7 @@ class CheckerImageTrackerTest : public testing::Test,
.TakePaintImage(),
SkIRect::MakeWH(dimension, dimension),
kNone_SkFilterQuality, SkMatrix::I(),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, gfx::ColorSpace());
}
bool ShouldCheckerImage(const DrawImage& draw_image, WhichTree tree) {
@@ -433,7 +433,8 @@ TEST_F(CheckerImageTrackerTest, CheckersOnlyStaticCompletedImages) {
.set_paint_image_generator(CreatePaintImageGenerator(image_size))
.TakePaintImage(),
SkIRect::MakeWH(image_size.width(), image_size.height()),
- kNone_SkFilterQuality, SkMatrix::I(), PaintImage::kDefaultFrameIndex);
+ kNone_SkFilterQuality, SkMatrix::I(), PaintImage::kDefaultFrameIndex,
+ gfx::ColorSpace());
EXPECT_FALSE(
ShouldCheckerImage(completed_paint_image, WhichTree::PENDING_TREE));
}
@@ -460,10 +461,12 @@ TEST_F(CheckerImageTrackerTest, ChoosesMaxScaleAndQuality) {
SetUpTracker(true);
DrawImage image = CreateImage(ImageType::CHECKERABLE);
- DrawImage scaled_image1(image, 0.5f, PaintImage::kDefaultFrameIndex);
+ DrawImage scaled_image1(image, 0.5f, PaintImage::kDefaultFrameIndex,
+ gfx::ColorSpace());
DrawImage scaled_image2 =
DrawImage(image.paint_image(), image.src_rect(), kHigh_SkFilterQuality,
- SkMatrix::MakeScale(1.8f), PaintImage::kDefaultFrameIndex);
+ SkMatrix::MakeScale(1.8f), PaintImage::kDefaultFrameIndex,
+ gfx::ColorSpace());
std::vector<DrawImage> draw_images = {scaled_image1, scaled_image2};
CheckerImageTracker::ImageDecodeQueue image_decode_queue =
@@ -538,7 +541,7 @@ TEST_F(CheckerImageTrackerTest, UseSrcRectForSize) {
DrawImage image = CreateImage(ImageType::CHECKERABLE);
image = DrawImage(image.paint_image(), SkIRect::MakeWH(200, 200),
image.filter_quality(), SkMatrix::I(),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, image.target_color_space());
EXPECT_FALSE(ShouldCheckerImage(image, WhichTree::PENDING_TREE));
}
diff --git a/chromium/cc/tiles/decoded_image_tracker.cc b/chromium/cc/tiles/decoded_image_tracker.cc
index 197b749f63e..5db3f198b6d 100644
--- a/chromium/cc/tiles/decoded_image_tracker.cc
+++ b/chromium/cc/tiles/decoded_image_tracker.cc
@@ -39,6 +39,7 @@ DecodedImageTracker::~DecodedImageTracker() {
void DecodedImageTracker::QueueImageDecode(
const PaintImage& image,
+ const gfx::ColorSpace& target_color_space,
base::OnceCallback<void(bool)> callback) {
size_t frame_index = PaintImage::kDefaultFrameIndex;
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
@@ -49,7 +50,7 @@ void DecodedImageTracker::QueueImageDecode(
// our own.
auto image_bounds = SkIRect::MakeWH(image.width(), image.height());
DrawImage draw_image(image, image_bounds, kNone_SkFilterQuality,
- SkMatrix::I(), frame_index);
+ SkMatrix::I(), frame_index, target_color_space);
image_controller_->QueueImageDecode(
draw_image, base::BindOnce(&DecodedImageTracker::ImageDecodeFinished,
base::Unretained(this), std::move(callback),
diff --git a/chromium/cc/tiles/decoded_image_tracker.h b/chromium/cc/tiles/decoded_image_tracker.h
index a5f99abe5dd..4803dfa3a2e 100644
--- a/chromium/cc/tiles/decoded_image_tracker.h
+++ b/chromium/cc/tiles/decoded_image_tracker.h
@@ -38,6 +38,7 @@ class CC_EXPORT DecodedImageTracker {
// completion. The callback takes a bool indicating whether the decode was
// successful or not.
void QueueImageDecode(const PaintImage& image,
+ const gfx::ColorSpace& target_color_space,
base::OnceCallback<void(bool)> callback);
// Unlock all locked images - used to respond to memory pressure or
diff --git a/chromium/cc/tiles/decoded_image_tracker_unittest.cc b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
index e481894e866..8ffb4817bea 100644
--- a/chromium/cc/tiles/decoded_image_tracker_unittest.cc
+++ b/chromium/cc/tiles/decoded_image_tracker_unittest.cc
@@ -86,18 +86,44 @@ class DecodedImageTrackerTest : public testing::Test {
TEST_F(DecodedImageTrackerTest, QueueImageLocksImages) {
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
base::BindOnce([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(1u, image_controller()->num_locked_images());
}
+TEST_F(DecodedImageTrackerTest, Colorspace) {
+ bool locked = false;
+ gfx::ColorSpace decoded_color_space(
+ gfx::ColorSpace::PrimaryID::XYZ_D50,
+ gfx::ColorSpace::TransferID::IEC61966_2_1);
+ gfx::ColorSpace srgb_color_space = gfx::ColorSpace::CreateSRGB();
+ auto paint_image = CreateDiscardablePaintImage(gfx::Size(1, 1));
+ decoded_image_tracker()->QueueImageDecode(
+ paint_image, decoded_color_space,
+ base::BindOnce([](bool* locked, bool success) { *locked = true; },
+ base::Unretained(&locked)));
+
+ // Check that the decoded color space images are locked, but if the color
+ // space differs then that image is not locked. Note that we use the high
+ // filter quality here, since it shouldn't matter and the checks should
+ // succeed anyway.
+ DrawImage locked_draw_image(
+ paint_image, SkIRect::MakeWH(1, 1), kHigh_SkFilterQuality, SkMatrix::I(),
+ PaintImage::kDefaultFrameIndex, decoded_color_space);
+ EXPECT_TRUE(image_controller()->IsDrawImageLocked(locked_draw_image));
+ DrawImage srgb_draw_image(paint_image, SkIRect::MakeWH(1, 1),
+ kHigh_SkFilterQuality, SkMatrix::I(),
+ PaintImage::kDefaultFrameIndex, srgb_color_space);
+ EXPECT_FALSE(image_controller()->IsDrawImageLocked(srgb_draw_image));
+}
+
TEST_F(DecodedImageTrackerTest, ImagesTimeOut) {
// Add an image, this will start a 250ms timeout to release it.
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
base::BindOnce([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -109,7 +135,7 @@ TEST_F(DecodedImageTrackerTest, ImagesTimeOut) {
// Add an image, this will not start a new timeout, as one is pending.
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
base::BindOnce([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -130,7 +156,7 @@ TEST_F(DecodedImageTrackerTest, ImageUsedInDraw) {
bool locked = false;
auto paint_image_1 = CreateDiscardablePaintImage(gfx::Size(1, 1));
decoded_image_tracker()->QueueImageDecode(
- paint_image_1,
+ paint_image_1, gfx::ColorSpace(),
base::BindOnce([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -138,7 +164,7 @@ TEST_F(DecodedImageTrackerTest, ImageUsedInDraw) {
auto paint_image_2 = CreateDiscardablePaintImage(gfx::Size(1, 1));
decoded_image_tracker()->QueueImageDecode(
- paint_image_2,
+ paint_image_2, gfx::ColorSpace(),
base::BindOnce([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
@@ -146,9 +172,11 @@ TEST_F(DecodedImageTrackerTest, ImageUsedInDraw) {
// Create dummy draw images for each:
DrawImage draw_image_1(paint_image_1, SkIRect::MakeWH(1, 1),
- kHigh_SkFilterQuality, SkMatrix::I(), 0);
+ kHigh_SkFilterQuality, SkMatrix::I(), 0,
+ gfx::ColorSpace());
DrawImage draw_image_2(paint_image_2, SkIRect::MakeWH(1, 1),
- kHigh_SkFilterQuality, SkMatrix::I(), 0);
+ kHigh_SkFilterQuality, SkMatrix::I(), 0,
+ gfx::ColorSpace());
// Both should be in the cache:
EXPECT_TRUE(image_controller()->IsDrawImageLocked(draw_image_1));
@@ -166,13 +194,13 @@ TEST_F(DecodedImageTrackerTest, UnlockAllImages) {
// Insert two images:
bool locked = false;
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
base::BindOnce([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
EXPECT_EQ(1u, image_controller()->num_locked_images());
decoded_image_tracker()->QueueImageDecode(
- CreateDiscardablePaintImage(gfx::Size(1, 1)),
+ CreateDiscardablePaintImage(gfx::Size(1, 1)), gfx::ColorSpace(),
base::BindOnce([](bool* locked, bool success) { *locked = true; },
base::Unretained(&locked)));
EXPECT_TRUE(locked);
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index eaff9df998b..30ce3e45e4d 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -437,20 +437,24 @@ GpuImageDecodeCache::InUseCacheKey::FromDrawImage(const DrawImage& draw_image) {
GpuImageDecodeCache::InUseCacheKey::InUseCacheKey(const DrawImage& draw_image)
: frame_key(draw_image.frame_key()),
upload_scale_mip_level(CalculateUploadScaleMipLevel(draw_image)),
- filter_quality(CalculateDesiredFilterQuality(draw_image)) {}
+ filter_quality(CalculateDesiredFilterQuality(draw_image)),
+ target_color_space(draw_image.target_color_space()) {}
bool GpuImageDecodeCache::InUseCacheKey::operator==(
const InUseCacheKey& other) const {
return frame_key == other.frame_key &&
upload_scale_mip_level == other.upload_scale_mip_level &&
- filter_quality == other.filter_quality;
+ filter_quality == other.filter_quality &&
+ target_color_space == other.target_color_space;
}
size_t GpuImageDecodeCache::InUseCacheKeyHash::operator()(
const InUseCacheKey& cache_key) const {
- return base::HashInts(cache_key.frame_key.hash(),
- base::HashInts(cache_key.upload_scale_mip_level,
- cache_key.filter_quality));
+ return base::HashInts(
+ cache_key.target_color_space.GetHash(),
+ base::HashInts(cache_key.frame_key.hash(),
+ base::HashInts(cache_key.upload_scale_mip_level,
+ cache_key.filter_quality)));
}
GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(
@@ -773,17 +777,20 @@ void GpuImageDecodeCache::UploadedImageData::ReportUsageStats() const {
usage_stats_.first_lock_wasted);
}
-GpuImageDecodeCache::ImageData::ImageData(PaintImage::Id paint_image_id,
- DecodedDataMode mode,
- size_t size,
- SkFilterQuality quality,
- int upload_scale_mip_level,
- bool needs_mips,
- bool is_bitmap_backed,
- bool is_yuv_format)
+GpuImageDecodeCache::ImageData::ImageData(
+ PaintImage::Id paint_image_id,
+ DecodedDataMode mode,
+ size_t size,
+ const gfx::ColorSpace& target_color_space,
+ SkFilterQuality quality,
+ int upload_scale_mip_level,
+ bool needs_mips,
+ bool is_bitmap_backed,
+ bool is_yuv_format)
: paint_image_id(paint_image_id),
mode(mode),
size(size),
+ target_color_space(target_color_space),
quality(quality),
upload_scale_mip_level(upload_scale_mip_level),
needs_mips(needs_mips),
@@ -853,8 +860,7 @@ GpuImageDecodeCache::GpuImageDecodeCache(
SkColorType color_type,
size_t max_working_set_bytes,
int max_texture_size,
- PaintImage::GeneratorClientId generator_client_id,
- sk_sp<SkColorSpace> target_color_space)
+ PaintImage::GeneratorClientId generator_client_id)
: color_type_(color_type),
use_transfer_cache_(use_transfer_cache),
context_(context),
@@ -862,8 +868,7 @@ GpuImageDecodeCache::GpuImageDecodeCache(
generator_client_id_(generator_client_id),
persistent_cache_(PersistentCache::NO_AUTO_EVICT),
max_working_set_bytes_(max_working_set_bytes),
- max_working_set_items_(kMaxItemsInWorkingSet),
- target_color_space_(std::move(target_color_space)) {
+ max_working_set_items_(kMaxItemsInWorkingSet) {
// In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
// Don't register a dump provider in these cases.
if (base::ThreadTaskRunnerHandle::IsSet()) {
@@ -886,17 +891,6 @@ GpuImageDecodeCache::~GpuImageDecodeCache() {
// It is safe to unregister, even if we didn't register in the constructor.
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
-
- // TODO(vmpstr): If we don't have a client name, it may cause problems in
- // unittests, since most tests don't set the name but some do. The UMA system
- // expects the name to be always the same. This assertion is violated in the
- // tests that do set the name.
- if (GetClientNameForMetrics()) {
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- base::StringPrintf("Compositing.%s.CachedImagesCount.Gpu",
- GetClientNameForMetrics()),
- lifetime_max_items_in_cache_, 1, 1000, 20);
- }
}
ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRef(
@@ -1588,9 +1582,6 @@ bool GpuImageDecodeCache::EnsureCapacity(size_t required_size) {
"GpuImageDecodeCache::EnsureCapacity");
lock_.AssertAcquired();
- lifetime_max_items_in_cache_ =
- std::max(lifetime_max_items_in_cache_, persistent_cache_.size());
-
// While we are over preferred item capacity, we iterate through our set of
// cached image data in LRU order, removing unreferenced images.
for (auto it = persistent_cache_.rbegin();
@@ -1669,7 +1660,7 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image,
return;
}
- TRACE_EVENT0("cc", "GpuImageDecodeCache::DecodeImage");
+ TRACE_EVENT0("cc,benchmark", "GpuImageDecodeCache::DecodeImage");
RecordImageMipLevelUMA(image_data->upload_scale_mip_level);
image_data->decode.ResetData();
@@ -1791,7 +1782,10 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
image_data->decode.mark_used();
sk_sp<SkColorSpace> color_space =
- SupportsColorSpaceConversion() ? target_color_space_ : nullptr;
+ SupportsColorSpaceConversion() &&
+ draw_image.target_color_space().IsValid()
+ ? draw_image.target_color_space().ToSkColorSpace()
+ : nullptr;
// The value of |decoded_target_colorspace| takes into account the fact
// that we might need to ignore an embedded image color space if |color_type_|
// does not support color space conversions or that color conversion might
@@ -1874,7 +1868,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
uploaded_image = CreateImageFromYUVATexturesInternal(
uploaded_y_image.get(), uploaded_u_image.get(),
uploaded_v_image.get(), image_width, image_height, &yuva_color_space,
- decoded_target_colorspace);
+ color_space, decoded_target_colorspace);
}
// At-raster may have decoded this while we were unlocked. If so, ignore our
@@ -2032,6 +2026,7 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
return base::WrapRefCounted(new ImageData(
draw_image.paint_image().stable_id(), mode, data_size,
+ draw_image.target_color_space(),
CalculateDesiredFilterQuality(draw_image), upload_scale_mip_level,
needs_mips, is_bitmap_backed, is_yuv));
}
@@ -2112,6 +2107,7 @@ void GpuImageDecodeCache::UnlockImage(ImageData* image_data) {
images_pending_unlock_.push_back(image_data->upload.y_image().get());
images_pending_unlock_.push_back(image_data->upload.u_image().get());
images_pending_unlock_.push_back(image_data->upload.v_image().get());
+ yuv_images_pending_unlock_.push_back(image_data->upload.image());
} else {
images_pending_unlock_.push_back(image_data->upload.image().get());
}
@@ -2142,11 +2138,32 @@ void GpuImageDecodeCache::UnlockImage(ImageData* image_data) {
}
}
+// YUV images are handled slightly differently because they are not themselves
+// registered with the discardable memory system. We cannot use
+// GlIdFromSkImage on these YUV SkImages to flush pending operations because
+// doing so will flatten it to RGB.
+void GpuImageDecodeCache::FlushYUVImages(
+ std::vector<sk_sp<SkImage>>* yuv_images) {
+ CheckContextLockAcquiredIfNecessary();
+ lock_.AssertAcquired();
+ for (auto& image : *yuv_images) {
+ image->flush(context_->GrContext());
+ }
+ yuv_images->clear();
+}
+
// We always run pending operations in the following order:
-// Lock > Unlock > Delete
+// > Lock
+// > Flush YUV images that will be unlocked
+// > Unlock
+// > Flush YUV images that will be deleted
+// > Delete
// This ensures that:
// a) We never fully unlock an image that's pending lock (lock before unlock)
// b) We never delete an image that has pending locks/unlocks.
+// c) We never unlock or delete the underlying texture planes for a YUV
+// image before all operations referencing it have completed.
+//
// As this can be run at-raster, to unlock/delete an image that was just used,
// we need to call GlIdFromSkImage, which flushes pending IO on the image,
// rather than just using a cached GL ID.
@@ -2164,6 +2181,7 @@ void GpuImageDecodeCache::RunPendingContextThreadOperations() {
}
images_pending_complete_lock_.clear();
+ FlushYUVImages(&yuv_images_pending_unlock_);
for (auto* image : images_pending_unlock_) {
context_->ContextGL()->UnlockDiscardableTextureCHROMIUM(
GlIdFromSkImage(image));
@@ -2176,8 +2194,7 @@ void GpuImageDecodeCache::RunPendingContextThreadOperations() {
}
ids_pending_unlock_.clear();
- yuv_images_pending_deletion_.clear();
-
+ FlushYUVImages(&yuv_images_pending_deletion_);
for (auto& image : images_pending_deletion_) {
uint32_t texture_id = GlIdFromSkImage(image.get());
if (context_->ContextGL()->LockDiscardableTextureCHROMIUM(texture_id)) {
@@ -2322,6 +2339,10 @@ bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data,
image_data->upload_scale_mip_level;
bool quality_is_compatible =
CalculateDesiredFilterQuality(draw_image) <= image_data->quality;
+ bool color_is_compatible =
+ image_data->target_color_space == draw_image.target_color_space();
+ if (!color_is_compatible)
+ return false;
if (is_scaled && (!scale_is_compatible || !quality_is_compatible))
return false;
return true;
@@ -2423,7 +2444,7 @@ sk_sp<SkColorSpace> GpuImageDecodeCache::ColorSpaceForImageDecode(
return nullptr;
if (mode == DecodedDataMode::kCpu)
- return target_color_space_;
+ return image.target_color_space().ToSkColorSpace();
// For kGpu or kTransferCache images color conversion is handled during
// upload, so keep the original colorspace here.
@@ -2443,6 +2464,7 @@ sk_sp<SkImage> GpuImageDecodeCache::CreateImageFromYUVATexturesInternal(
const size_t image_width,
const size_t image_height,
const SkYUVColorSpace* yuva_color_space,
+ sk_sp<SkColorSpace> target_color_space,
sk_sp<SkColorSpace> decoded_color_space) const {
DCHECK(uploaded_y_image);
DCHECK(uploaded_u_image);
@@ -2460,8 +2482,6 @@ sk_sp<SkImage> GpuImageDecodeCache::CreateImageFromYUVATexturesInternal(
indices[SkYUVAIndex::kV_Index] = {2, SkColorChannel::kR};
indices[SkYUVAIndex::kA_Index] = {-1, SkColorChannel::kR};
- sk_sp<SkColorSpace> target_color_space =
- SupportsColorSpaceConversion() ? target_color_space_ : nullptr;
if (target_color_space && SkColorSpace::Equals(target_color_space.get(),
decoded_color_space.get())) {
target_color_space = nullptr;
@@ -2551,13 +2571,18 @@ void GpuImageDecodeCache::UpdateMipsIfNeeded(const DrawImage& draw_image,
SkYUVColorSpace yuva_color_space = SkYUVColorSpace::kRec601_SkYUVColorSpace;
size_t width = image_y_with_mips_owned->width();
size_t height = image_y_with_mips_owned->height();
+ sk_sp<SkColorSpace> color_space =
+ SupportsColorSpaceConversion() &&
+ draw_image.target_color_space().IsValid()
+ ? draw_image.target_color_space().ToSkColorSpace()
+ : nullptr;
sk_sp<SkColorSpace> decoded_color_space =
ColorSpaceForImageDecode(draw_image, image_data->mode);
sk_sp<SkImage> yuv_image_with_mips_owned =
CreateImageFromYUVATexturesInternal(
image_y_with_mips_owned.get(), image_u_with_mips_owned.get(),
image_v_with_mips_owned.get(), width, height, &yuva_color_space,
- decoded_color_space);
+ color_space, decoded_color_space);
// In case of lost context
if (!yuv_image_with_mips_owned) {
DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.h b/chromium/cc/tiles/gpu_image_decode_cache.h
index 3c3ff52532c..81ca6286703 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.h
+++ b/chromium/cc/tiles/gpu_image_decode_cache.h
@@ -108,8 +108,7 @@ class CC_EXPORT GpuImageDecodeCache
SkColorType color_type,
size_t max_working_set_bytes,
int max_texture_size,
- PaintImage::GeneratorClientId client_id,
- sk_sp<SkColorSpace> target_color_space);
+ PaintImage::GeneratorClientId client_id);
~GpuImageDecodeCache() override;
// Returns the GL texture ID backing the given SkImage.
@@ -443,6 +442,7 @@ class CC_EXPORT GpuImageDecodeCache
ImageData(PaintImage::Id paint_image_id,
DecodedDataMode mode,
size_t size,
+ const gfx::ColorSpace& target_color_space,
SkFilterQuality quality,
int upload_scale_mip_level,
bool needs_mips,
@@ -456,6 +456,7 @@ class CC_EXPORT GpuImageDecodeCache
const PaintImage::Id paint_image_id;
const DecodedDataMode mode;
const size_t size;
+ gfx::ColorSpace target_color_space;
SkFilterQuality quality;
int upload_scale_mip_level;
bool needs_mips = false;
@@ -501,6 +502,7 @@ class CC_EXPORT GpuImageDecodeCache
PaintImage::FrameKey frame_key;
int upload_scale_mip_level;
SkFilterQuality filter_quality;
+ gfx::ColorSpace target_color_space;
};
struct InUseCacheKeyHash {
size_t operator()(const InUseCacheKey&) const;
@@ -551,6 +553,7 @@ class CC_EXPORT GpuImageDecodeCache
const size_t image_width,
const size_t image_height,
const SkYUVColorSpace* yuva_color_space,
+ sk_sp<SkColorSpace> target_color_space,
sk_sp<SkColorSpace> decoded_color_space) const;
scoped_refptr<GpuImageDecodeCache::ImageData> CreateImageData(
@@ -590,6 +593,10 @@ class CC_EXPORT GpuImageDecodeCache
void UploadImageIfNecessary(const DrawImage& draw_image,
ImageData* image_data);
+ // Flush pending operations on context_->GrContext() for each element of
+ // |yuv_images| and then clear the vector.
+ void FlushYUVImages(std::vector<sk_sp<SkImage>>* yuv_images);
+
// Runs pending operations that required the |context_| lock to be held, but
// were queued up during a time when the |context_| lock was unavailable.
// These including deleting, unlocking, and locking textures.
@@ -657,16 +664,14 @@ class CC_EXPORT GpuImageDecodeCache
std::vector<sk_sp<SkImage>> images_pending_deletion_;
// Images that are backed by planar textures must be handled differently
// to avoid inadvertently flattening to RGB and creating additional textures.
+ // See comment in RunPendingContextThreadOperations().
std::vector<sk_sp<SkImage>> yuv_images_pending_deletion_;
+ std::vector<sk_sp<SkImage>> yuv_images_pending_unlock_;
const sk_sp<SkColorSpace> target_color_space_;
std::vector<uint32_t> ids_pending_unlock_;
std::vector<uint32_t> ids_pending_deletion_;
- // Records the maximum number of items in the cache over the lifetime of the
- // cache. This is updated anytime we are requested to reduce cache usage.
- size_t lifetime_max_items_in_cache_ = 0u;
-
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
};
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
index f7d485e215e..a3b7e86666e 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -47,20 +47,19 @@ class GpuImageDecodeCachePerfTest
kTimeCheckInterval),
context_provider_(base::MakeRefCounted<TestInProcessContextProvider>(
UseTransferCache(),
- false /* support_locking */)) {
+ false /* support_locking */)),
+ cache_(context_provider_.get(),
+ UseTransferCache(),
+ kRGBA_8888_SkColorType,
+ kCacheSize,
+ MaxTextureSize(),
+ PaintImage::kDefaultGeneratorClientId) {
// Initializing context here is ok because image decode cache does not use
// context provider in its constructor.
gpu::ContextResult result = context_provider_->BindToCurrentThread();
DCHECK_EQ(result, gpu::ContextResult::kSuccess);
}
- void CreateCache(sk_sp<SkColorSpace> color_space = nullptr) {
- cache_ = std::make_unique<GpuImageDecodeCache>(
- context_provider_.get(), UseTransferCache(), kRGBA_8888_SkColorType,
- kCacheSize, MaxTextureSize(), PaintImage::kDefaultGeneratorClientId,
- std::move(color_space));
- }
-
protected:
size_t MaxTextureSize() const {
switch (GetParam()) {
@@ -89,7 +88,7 @@ class GpuImageDecodeCachePerfTest
base::LapTimer timer_;
scoped_refptr<TestInProcessContextProvider> context_provider_;
- std::unique_ptr<GpuImageDecodeCache> cache_;
+ GpuImageDecodeCache cache_;
};
INSTANTIATE_TEST_SUITE_P(P,
@@ -99,7 +98,6 @@ INSTANTIATE_TEST_SUITE_P(P,
TestMode::kSw));
TEST_P(GpuImageDecodeCachePerfTest, DecodeWithColorConversion) {
- CreateCache(gfx::ColorSpace::CreateXYZD50().ToSkColorSpace());
timer_.Reset();
do {
DrawImage image(
@@ -108,10 +106,11 @@ TEST_P(GpuImageDecodeCachePerfTest, DecodeWithColorConversion) {
.set_image(CreateImage(1024, 2048), PaintImage::GetNextContentId())
.TakePaintImage(),
SkIRect::MakeWH(1024, 2048), kMedium_SkFilterQuality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u);
+ CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u,
+ gfx::ColorSpace::CreateXYZD50());
- DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
- cache_->DrawWithImageFinished(image, decoded_image);
+ DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
+ cache_.DrawWithImageFinished(image, decoded_image);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -132,7 +131,6 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
context_provider_->GrContext(), SkBudgeted::kNo,
SkImageInfo::MakeN32Premul(2048, 2048));
- CreateCache();
timer_.Reset();
do {
DrawImage image(
@@ -141,9 +139,9 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
.set_image(CreateImage(1024, 2048), PaintImage::GetNextContentId())
.TakePaintImage(),
SkIRect::MakeWH(1024, 2048), kMedium_SkFilterQuality,
- CreateMatrix(SkSize::Make(0.6f, 0.6f)), 0u);
+ CreateMatrix(SkSize::Make(0.6f, 0.6f)), 0u, gfx::ColorSpace());
- DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
+ DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
if (GetParam() == TestMode::kGpu) {
SkPaint paint;
@@ -154,7 +152,7 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
surface->flush();
}
- cache_->DrawWithImageFinished(image, decoded_image);
+ cache_.DrawWithImageFinished(image, decoded_image);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -164,21 +162,21 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) {
TEST_P(GpuImageDecodeCachePerfTest, AcquireExistingImages) {
timer_.Reset();
- CreateCache(gfx::ColorSpace::CreateXYZD50().ToSkColorSpace());
DrawImage image(
PaintImageBuilder::WithDefault()
.set_id(PaintImage::GetNextId())
.set_image(CreateImage(1024, 2048), PaintImage::GetNextContentId())
.TakePaintImage(),
SkIRect::MakeWH(1024, 2048), kMedium_SkFilterQuality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u);
+ CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u,
+ gfx::ColorSpace::CreateXYZD50());
- DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
- cache_->DrawWithImageFinished(image, decoded_image);
+ DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
+ cache_.DrawWithImageFinished(image, decoded_image);
do {
- DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image);
- cache_->DrawWithImageFinished(image, decoded_image);
+ DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image);
+ cache_.DrawWithImageFinished(image, decoded_image);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
index 087f8b26620..77f3210c518 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -283,15 +283,10 @@ class GpuImageDecodeCacheTest
}
std::unique_ptr<GpuImageDecodeCache> CreateCache() {
- return CreateCache(DefaultColorSpace());
- }
-
- std::unique_ptr<GpuImageDecodeCache> CreateCache(
- const gfx::ColorSpace& color_space) {
return std::make_unique<GpuImageDecodeCache>(
context_provider_.get(), use_transfer_cache_, color_type_,
kGpuMemoryLimitBytes, max_texture_size_,
- PaintImage::kDefaultGeneratorClientId, color_space.ToSkColorSpace());
+ PaintImage::kDefaultGeneratorClientId);
}
// Returns dimensions for an image that will not fit in GPU memory and hence
@@ -446,7 +441,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -455,7 +450,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage another_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -477,7 +472,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -490,7 +485,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {
DrawImage another_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
@@ -518,7 +513,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLowerQuality) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kHigh_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -526,7 +521,8 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLowerQuality) {
DrawImage another_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
+ kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+ DefaultColorSpace());
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -548,7 +544,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentImage) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -559,7 +555,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentImage) {
second_image,
SkIRect::MakeWH(second_image.width(), second_image.height()), quality,
CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -584,7 +580,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -598,7 +594,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -608,7 +604,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
DrawImage third_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
third_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(third_result.need_unref);
@@ -630,7 +626,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -639,7 +635,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -649,7 +645,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
DrawImage third_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
third_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(third_result.need_unref);
@@ -673,7 +669,8 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
+ kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+ DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -686,7 +683,8 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
+ kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+ DefaultColorSpace());
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -707,7 +705,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedAndLocked) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -749,7 +747,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedNotLocked) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -791,7 +789,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyUploaded) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -822,7 +820,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -865,7 +863,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledWhileReffedGetsNewTask) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -912,7 +910,7 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageUploadCanceledButDecodeRun) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -941,7 +939,7 @@ TEST_P(GpuImageDecodeCacheTest, NoTaskForImageAlreadyFailedDecoding) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -971,7 +969,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDraw) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1005,7 +1003,7 @@ TEST_P(GpuImageDecodeCacheTest, GetLargeDecodedImageForDraw) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1041,7 +1039,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1075,7 +1073,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1087,7 +1085,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {
DrawImage larger_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult larger_result = cache->GetTaskForImageAndRef(
larger_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(larger_result.need_unref);
@@ -1129,7 +1127,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1140,7 +1138,8 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {
DrawImage higher_quality_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
+ kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+ DefaultColorSpace());
ImageDecodeCache::TaskResult hq_result = cache->GetTaskForImageAndRef(
higher_quality_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(hq_result.need_unref);
@@ -1182,7 +1181,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawNegative) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(-0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1221,7 +1220,7 @@ TEST_P(GpuImageDecodeCacheTest, GetLargeScaledDecodedImageForDraw) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1264,7 +1263,7 @@ TEST_P(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1307,7 +1306,7 @@ TEST_P(GpuImageDecodeCacheTest,
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
@@ -1345,7 +1344,7 @@ TEST_P(GpuImageDecodeCacheTest,
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
@@ -1382,7 +1381,7 @@ TEST_P(GpuImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1410,7 +1409,7 @@ TEST_P(GpuImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {
image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1436,7 +1435,7 @@ TEST_P(GpuImageDecodeCacheTest, CanceledTasksDoNotCountAgainstBudget) {
DrawImage draw_image(
image, SkIRect::MakeXYWH(0, 0, image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1462,7 +1461,7 @@ TEST_P(GpuImageDecodeCacheTest, ShouldAggressivelyFreeResources) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
{
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
@@ -1524,7 +1523,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -1539,7 +1538,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -1572,7 +1571,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -1591,7 +1590,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -1615,9 +1614,10 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f), is_decomposable);
// Create an image with kLow_FilterQuality.
- DrawImage low_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
+ DrawImage low_draw_image(image,
+ SkIRect::MakeWH(image.width(), image.height()),
+ kLow_SkFilterQuality, matrix,
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult low_result = cache->GetTaskForImageAndRef(
low_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(low_result.need_unref);
@@ -1627,7 +1627,8 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
// should get a new task/ref.
DrawImage medium_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kMedium_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
+ kMedium_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+ DefaultColorSpace());
ImageDecodeCache::TaskResult medium_result = cache->GetTaskForImageAndRef(
medium_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(medium_result.need_unref);
@@ -1637,7 +1638,8 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
// Get the same image at kHigh_FilterQuality. We should re-use medium.
DrawImage high_quality_draw_image(
image, SkIRect::MakeWH(image.width(), image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex);
+ kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
+ DefaultColorSpace());
ImageDecodeCache::TaskResult high_quality_result =
cache->GetTaskForImageAndRef(high_quality_draw_image,
ImageDecodeCache::TracingInfo());
@@ -1666,7 +1668,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1688,7 +1690,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {
DrawImage draw_image_mips(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image_mips));
cache->DrawWithImageFinished(draw_image_mips, decoded_draw_image);
@@ -1702,7 +1704,7 @@ TEST_P(GpuImageDecodeCacheTest, OutOfRasterDecodeTask) {
SkMatrix matrix = CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable);
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetOutOfRasterDecodeTaskForImageAndRef(draw_image);
@@ -1730,7 +1732,7 @@ TEST_P(GpuImageDecodeCacheTest, ZeroCacheNormalWorkingSet) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1781,13 +1783,13 @@ TEST_P(GpuImageDecodeCacheTest, SmallCacheNormalWorkingSet) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
PaintImage image2 = CreatePaintImageInternal(GetNormalImageSize());
DrawImage draw_image2(
image2, SkIRect::MakeWH(image2.width(), image2.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// Add an image to the cache and un-ref it.
{
@@ -1864,7 +1866,7 @@ TEST_P(GpuImageDecodeCacheTest, ClearCache) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1894,7 +1896,7 @@ TEST_P(GpuImageDecodeCacheTest, ClearCacheInUse) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1919,16 +1921,64 @@ TEST_P(GpuImageDecodeCacheTest, ClearCacheInUse) {
EXPECT_EQ(cache->GetNumCacheEntriesForTesting(), 0u);
}
-TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImage) {
+TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentColorSpace) {
+ auto cache = CreateCache();
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ gfx::ColorSpace color_space_a = gfx::ColorSpace::CreateSRGB();
+ gfx::ColorSpace color_space_b = gfx::ColorSpace::CreateXYZD50();
+
+ PaintImage first_image = CreatePaintImageInternal(gfx::Size(100, 100));
+ DrawImage first_draw_image(
+ first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, color_space_a);
+ ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
+ first_draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(first_result.need_unref);
+ EXPECT_TRUE(first_result.task);
+
+ DrawImage second_draw_image(
+ first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, color_space_b);
+ ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
+ second_draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(second_result.need_unref);
+ EXPECT_TRUE(second_result.task);
+ EXPECT_TRUE(first_result.task.get() != second_result.task.get());
+
+ DrawImage third_draw_image(
+ first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, color_space_a);
+ ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
+ third_draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(third_result.need_unref);
+ EXPECT_TRUE(third_result.task.get() == first_result.task.get());
+
+ TestTileTaskRunner::ProcessTask(first_result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(first_result.task.get());
+ TestTileTaskRunner::ProcessTask(second_result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(second_result.task.get());
+
+ cache->UnrefImage(first_draw_image);
+ cache->UnrefImage(second_draw_image);
+ cache->UnrefImage(third_draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImageNonSRGBColorSpace) {
auto cache = CreateCache();
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
PaintImage image = CreateLargePaintImageForSoftwareFallback();
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, color_space);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1966,9 +2016,10 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 1u);
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ 1u, DefaultColorSpace());
auto decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -1978,7 +2029,8 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
cache->DrawWithImageFinished(draw_image, decoded_image);
// Scaled.
- DrawImage scaled_draw_image(draw_image, 0.5f, 2u);
+ DrawImage scaled_draw_image(draw_image, 0.5f, 2u,
+ draw_image.target_color_space());
decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(scaled_draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -1994,7 +2046,8 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
ASSERT_LT(subset_height, test_image_size.height());
DrawImage subset_draw_image(
image, SkIRect::MakeWH(subset_width, subset_height), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u);
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
+ DefaultColorSpace());
decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(subset_draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -2014,7 +2067,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {
DrawImage first_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -2028,7 +2081,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {
DrawImage second_draw_image(
first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -2069,7 +2122,7 @@ TEST_P(GpuImageDecodeCacheTest, AlreadyBudgetedImagesAreNotAtRaster) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
const size_t bytes_for_test_image =
GetBytesNeededForSingleImage(test_image_size);
@@ -2116,7 +2169,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// The image counts against our budget.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
@@ -2130,7 +2183,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
CreatePaintImageInternal(GetNormalImageSize()),
SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// Should be at raster.
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
@@ -2157,7 +2210,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
const size_t bytes_for_test_image =
GetBytesNeededForSingleImage(test_image_size);
@@ -2179,7 +2232,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
CreatePaintImageInternal(test_image_size),
SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// Should be at raster.
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
@@ -2198,16 +2251,16 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
TEST_P(GpuImageDecodeCacheTest,
ColorConversionDuringDecodeForLargeImageNonSRGBColorSpace) {
- gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
- auto cache = CreateCache(color_space);
+ auto cache = CreateCache();
bool is_decomposable = true;
const SkFilterQuality quality = kHigh_SkFilterQuality;
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
PaintImage image = CreateLargePaintImageForSoftwareFallback();
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, color_space);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2253,16 +2306,16 @@ TEST_P(GpuImageDecodeCacheTest,
TEST_P(GpuImageDecodeCacheTest,
ColorConversionDuringUploadForSmallImageNonSRGBColorSpace) {
- gfx::ColorSpace color_space = gfx::ColorSpace::CreateDisplayP3D65();
- auto cache = CreateCache(color_space);
+ auto cache = CreateCache();
bool is_decomposable = true;
const SkFilterQuality quality = kHigh_SkFilterQuality;
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateDisplayP3D65();
PaintImage image = CreatePaintImageInternal(gfx::Size(11, 12));
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, color_space);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2314,7 +2367,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScale) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2339,7 +2392,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskHasNoDeps) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2363,7 +2416,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskCancelled) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2380,8 +2433,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
// YUV bitmap images do not happen, so this test will always skip for YUV.
return;
}
- auto color_space = gfx::ColorSpace::CreateDisplayP3D65();
- auto cache = CreateCache(color_space);
+ auto cache = CreateCache();
const bool should_cache_sw_image =
cache->SupportsColorSpaceConversion() && !use_transfer_cache_;
@@ -2389,10 +2441,10 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage image = CreateBitmapImageInternal(GetLargeImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ DrawImage draw_image(
+ image, SkIRect::MakeWH(image.width(), image.height()), quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, gfx::ColorSpace::CreateDisplayP3D65());
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2404,8 +2456,9 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
auto sw_image = cache->GetSWImageDecodeForTesting(draw_image);
ASSERT_EQ(!!sw_image, should_cache_sw_image);
if (should_cache_sw_image) {
- EXPECT_TRUE(SkColorSpace::Equals(sw_image->colorSpace(),
- color_space.ToSkColorSpace().get()));
+ EXPECT_TRUE(SkColorSpace::Equals(
+ sw_image->colorSpace(),
+ gfx::ColorSpace::CreateDisplayP3D65().ToSkColorSpace().get()));
}
}
@@ -2422,7 +2475,7 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2447,7 +2500,7 @@ TEST_P(GpuImageDecodeCacheTest, KeepOnlyLast2ContentIds) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2504,7 +2557,7 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
const int expected_width =
@@ -2551,7 +2604,7 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -2571,16 +2624,15 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
TEST_P(GpuImageDecodeCacheTest, BasicMips) {
auto decode_and_check_mips = [this](SkFilterQuality filter_quality,
- SkSize scale,
- const gfx::ColorSpace& color_space,
+ SkSize scale, gfx::ColorSpace color_space,
bool should_have_mips) {
- auto cache = CreateCache(color_space);
+ auto cache = CreateCache();
bool is_decomposable = true;
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
filter_quality, CreateMatrix(scale, is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, color_space);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2656,7 +2708,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2701,7 +2753,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2754,7 +2806,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2792,7 +2844,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
DrawImage draw_image(
image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2873,7 +2925,7 @@ TEST_P(GpuImageDecodeCacheTest, GetBorderlineLargeDecodedImageForDraw) {
almost_too_large_image.height()),
quality,
CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
diff --git a/chromium/cc/tiles/image_controller_unittest.cc b/chromium/cc/tiles/image_controller_unittest.cc
index 05c82a46340..1c3e0d3b215 100644
--- a/chromium/cc/tiles/image_controller_unittest.cc
+++ b/chromium/cc/tiles/image_controller_unittest.cc
@@ -233,7 +233,7 @@ DrawImage CreateDiscardableDrawImage(gfx::Size size) {
return DrawImage(CreateDiscardablePaintImage(size),
SkIRect::MakeWH(size.width(), size.height()),
kNone_SkFilterQuality, SkMatrix::I(),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, gfx::ColorSpace());
}
DrawImage CreateBitmapDrawImage(gfx::Size size) {
diff --git a/chromium/cc/tiles/paint_worklet_image_cache.cc b/chromium/cc/tiles/paint_worklet_image_cache.cc
index 639bf7d19b1..d0bd702cae7 100644
--- a/chromium/cc/tiles/paint_worklet_image_cache.cc
+++ b/chromium/cc/tiles/paint_worklet_image_cache.cc
@@ -48,10 +48,7 @@ void PaintWorkletImageCache::SetPaintWorkletLayerPainter(
scoped_refptr<TileTask> PaintWorkletImageCache::GetTaskForPaintWorkletImage(
const DrawImage& image) {
- // As described in crbug.com/939192, the |painter_| could be null, and we
- // should not create any raster task.
- if (!painter_)
- return nullptr;
+ DCHECK(painter_);
DCHECK(image.paint_image().IsPaintWorklet());
return base::MakeRefCounted<PaintWorkletTaskImpl>(this, image.paint_image());
}
@@ -74,6 +71,8 @@ void PaintWorkletImageCache::PaintImageInTask(const PaintImage& paint_image) {
// matches the PaintGeneratedImage::Draw.
sk_sp<PaintRecord> record =
painter_->Paint(paint_image.paint_worklet_input());
+ if (!record)
+ return;
{
base::AutoLock hold(records_lock_);
// It is possible for two or more threads to both pass through the first
@@ -89,10 +88,7 @@ void PaintWorkletImageCache::PaintImageInTask(const PaintImage& paint_image) {
std::pair<sk_sp<PaintRecord>, base::OnceCallback<void()>>
PaintWorkletImageCache::GetPaintRecordAndRef(PaintWorkletInput* input) {
base::AutoLock hold(records_lock_);
- // If the |painter_| was null when GetTaskForPaintWorkletImage was called
- // there will be no cache entry for this input.
- if (records_.find(input) == records_.end())
- return std::make_pair(sk_make_sp<PaintOpBuffer>(), base::DoNothing::Once());
+ DCHECK(records_.find(input) != records_.end());
records_[input].used_ref_count++;
records_[input].num_of_frames_not_accessed = 0u;
// The PaintWorkletImageCache object lives as long as the LayerTreeHostImpl,
diff --git a/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc b/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc
index 6ae3c0a0036..7af4b9340c6 100644
--- a/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc
+++ b/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc
@@ -257,29 +257,5 @@ TEST(PaintWorkletImageCacheTest, CacheEntryLookup) {
}
}
-TEST(PaintWorkletImageCacheTest, TaskIsNullWhenPainterIsNull) {
- TestPaintWorkletImageCache cache;
- PaintImage paint_image = CreatePaintImage(100, 100);
- scoped_refptr<TileTask> task =
- GetTaskForPaintWorkletImage(paint_image, &cache);
- EXPECT_EQ(task, nullptr);
-}
-
-TEST(PaintWorkletImageCacheTest,
- RecordAndCallbackAreEmptyWhenInputWasntPainted) {
- TestPaintWorkletImageCache cache;
- std::unique_ptr<TestPaintWorkletLayerPainter> painter =
- std::make_unique<TestPaintWorkletLayerPainter>();
- cache.SetPaintWorkletLayerPainter(std::move(painter));
-
- // We request a record and callback without ever painting the input.
- PaintImage paint_image = CreatePaintImage(100, 100);
- std::pair<sk_sp<PaintRecord>, base::OnceCallback<void()>> result =
- cache.GetPaintRecordAndRef(paint_image.paint_worklet_input());
- EXPECT_EQ(result.first->total_op_count(), 0u);
- // This is an empty callback, running it should not crash.
- std::move(result.second).Run();
-}
-
} // namespace
} // namespace cc
diff --git a/chromium/cc/tiles/software_image_decode_cache.cc b/chromium/cc/tiles/software_image_decode_cache.cc
index c2bb32f6e81..f858a180756 100644
--- a/chromium/cc/tiles/software_image_decode_cache.cc
+++ b/chromium/cc/tiles/software_image_decode_cache.cc
@@ -16,7 +16,6 @@
#include "cc/base/histograms.h"
#include "cc/raster/tile_task.h"
#include "cc/tiles/mipmap_util.h"
-#include "ui/gfx/color_space.h"
#include "ui/gfx/skia_util.h"
using base::trace_event::MemoryAllocatorDump;
@@ -143,10 +142,8 @@ void RecordLockExistingCachedImageHistogram(TilePriority::PriorityBin bin,
SoftwareImageDecodeCache::SoftwareImageDecodeCache(
SkColorType color_type,
size_t locked_memory_limit_bytes,
- PaintImage::GeneratorClientId generator_client_id,
- sk_sp<SkColorSpace> target_color_space)
+ PaintImage::GeneratorClientId generator_client_id)
: decoded_images_(ImageMRUCache::NO_AUTO_EVICT),
- target_color_space_(std::move(target_color_space)),
locked_images_budget_(locked_memory_limit_bytes),
color_type_(color_type),
generator_client_id_(generator_client_id),
@@ -167,16 +164,6 @@ SoftwareImageDecodeCache::~SoftwareImageDecodeCache() {
// It is safe to unregister, even if we didn't register in the constructor.
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
- // TODO(vmpstr): If we don't have a client name, it may cause problems in
- // unittests, since most tests don't set the name but some do. The UMA system
- // expects the name to be always the same. This assertion is violated in the
- // tests that do set the name.
- if (GetClientNameForMetrics()) {
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- base::StringPrintf("Compositing.%s.CachedImagesCount.Software",
- GetClientNameForMetrics()),
- lifetime_max_items_in_cache_, 1, 1000, 20);
- }
}
ImageDecodeCache::TaskResult SoftwareImageDecodeCache::GetTaskForImageAndRef(
@@ -316,8 +303,8 @@ void SoftwareImageDecodeCache::UnrefImage(const CacheKey& key) {
void SoftwareImageDecodeCache::DecodeImageInTask(const CacheKey& key,
const PaintImage& paint_image,
DecodeTaskType task_type) {
- TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImageInTask", "key",
- key.ToString());
+ TRACE_EVENT1("cc,benchmark", "SoftwareImageDecodeCache::DecodeImageInTask",
+ "key", key.ToString());
base::AutoLock lock(lock_);
auto image_it = decoded_images_.Peek(key);
@@ -367,9 +354,8 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
// If we can use the original decode, we'll definitely need a decode.
if (key.type() == CacheKey::kOriginal) {
base::AutoUnlock release(lock_);
- local_cache_entry =
- Utils::DoDecodeImage(key, paint_image, color_type_, target_color_space_,
- generator_client_id_);
+ local_cache_entry = Utils::DoDecodeImage(key, paint_image, color_type_,
+ generator_client_id_);
} else {
// Attempt to find a cached decode to generate a scaled/subrected decode
// from.
@@ -396,9 +382,8 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
DCHECK(!should_decode_to_scale || !key.is_nearest_neighbor());
if (should_decode_to_scale) {
base::AutoUnlock release(lock_);
- local_cache_entry =
- Utils::DoDecodeImage(key, paint_image, color_type_,
- target_color_space_, generator_client_id_);
+ local_cache_entry = Utils::DoDecodeImage(key, paint_image, color_type_,
+ generator_client_id_);
}
// Couldn't decode to scale or find a cached candidate. Create the
@@ -423,9 +408,9 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
key.type() == CacheKey::kSubrectOriginal
? SkIRect::MakeWH(paint_image.width(), paint_image.height())
: gfx::RectToSkIRect(key.src_rect());
- DrawImage candidate_draw_image(paint_image, src_rect,
- kNone_SkFilterQuality, SkMatrix::I(),
- key.frame_key().frame_index());
+ DrawImage candidate_draw_image(
+ paint_image, src_rect, kNone_SkFilterQuality, SkMatrix::I(),
+ key.frame_key().frame_index(), key.target_color_space());
candidate_key.emplace(
CacheKey::FromDrawImage(candidate_draw_image, color_type_));
}
@@ -526,7 +511,9 @@ bool SoftwareImageDecodeCache::UseCacheForDrawImage(
// Cache images that need to be converted to a non-sRGB color space.
// TODO(ccameron): Consider caching when any color conversion is required.
// https://crbug.com/791828
- if (target_color_space_ && !target_color_space_->isSRGB()) {
+ const gfx::ColorSpace& dst_color_space = draw_image.target_color_space();
+ if (dst_color_space.IsValid() &&
+ dst_color_space != gfx::ColorSpace::CreateSRGB()) {
return true;
}
@@ -587,8 +574,6 @@ void SoftwareImageDecodeCache::DrawWithImageFinished(
void SoftwareImageDecodeCache::ReduceCacheUsageUntilWithinLimit(size_t limit) {
TRACE_EVENT0("cc",
"SoftwareImageDecodeCache::ReduceCacheUsageUntilWithinLimit");
- lifetime_max_items_in_cache_ =
- std::max(lifetime_max_items_in_cache_, decoded_images_.size());
for (auto it = decoded_images_.rbegin();
decoded_images_.size() > limit && it != decoded_images_.rend();) {
if (it->second->ref_count != 0) {
diff --git a/chromium/cc/tiles/software_image_decode_cache.h b/chromium/cc/tiles/software_image_decode_cache.h
index eb7cc161f1d..c3b7c03303d 100644
--- a/chromium/cc/tiles/software_image_decode_cache.h
+++ b/chromium/cc/tiles/software_image_decode_cache.h
@@ -34,8 +34,7 @@ class CC_EXPORT SoftwareImageDecodeCache
SoftwareImageDecodeCache(SkColorType color_type,
size_t locked_memory_limit_bytes,
- PaintImage::GeneratorClientId generator_client_id,
- sk_sp<SkColorSpace> target_color_space);
+ PaintImage::GeneratorClientId generator_client_id);
~SoftwareImageDecodeCache() override;
// ImageDecodeCache overrides.
@@ -151,16 +150,12 @@ class CC_EXPORT SoftwareImageDecodeCache
PaintImage::FrameKeyHash>
frame_key_to_image_keys_;
- const sk_sp<SkColorSpace> target_color_space_;
MemoryBudget locked_images_budget_;
const SkColorType color_type_;
const PaintImage::GeneratorClientId generator_client_id_;
size_t max_items_in_cache_;
- // Records the maximum number of items in the cache over the lifetime of the
- // cache. This is updated anytime we are requested to reduce cache usage.
- size_t lifetime_max_items_in_cache_ = 0u;
};
} // namespace cc
diff --git a/chromium/cc/tiles/software_image_decode_cache_perftest.cc b/chromium/cc/tiles/software_image_decode_cache_perftest.cc
index f873c9774bb..fb99fb7c3f6 100644
--- a/chromium/cc/tiles/software_image_decode_cache_perftest.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_perftest.cc
@@ -63,7 +63,8 @@ class SoftwareImageDecodeCachePerfTest : public testing::Test {
PaintImage::GetNextContentId())
.TakePaintImage(),
subrect, quality,
- CreateMatrix(SkSize::Make(scale.first, scale.second)), 0u);
+ CreateMatrix(SkSize::Make(scale.first, scale.second)), 0u,
+ gfx::ColorSpace());
}
}
}
diff --git a/chromium/cc/tiles/software_image_decode_cache_unittest.cc b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
index 18f6d88444b..3e31e7a9a4b 100644
--- a/chromium/cc/tiles/software_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_unittest.cc
@@ -23,13 +23,9 @@ size_t kLockedMemoryLimitBytes = 128 * 1024 * 1024;
class TestSoftwareImageDecodeCache : public SoftwareImageDecodeCache {
public:
TestSoftwareImageDecodeCache()
- : TestSoftwareImageDecodeCache(DefaultColorSpace()) {}
-
- explicit TestSoftwareImageDecodeCache(const gfx::ColorSpace& color_space)
: SoftwareImageDecodeCache(kN32_SkColorType,
kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId,
- color_space.ToSkColorSpace()) {}
+ PaintImage::kDefaultGeneratorClientId) {}
};
SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
@@ -58,7 +54,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyNoneQuality) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kNone_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -80,7 +76,7 @@ TEST(SoftwareImageDecodeCacheTest,
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -98,7 +94,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropsToLowIfMipLevel0) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kMedium_SkFilterQuality,
CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -117,7 +113,7 @@ TEST(SoftwareImageDecodeCacheTest, LowUnscalableFormatStaysLow) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kARGB_4444_SkColorType);
@@ -136,7 +132,7 @@ TEST(SoftwareImageDecodeCacheTest, HighUnscalableFormatBecomesLow) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kHigh_SkFilterQuality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kARGB_4444_SkColorType);
@@ -155,7 +151,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyLowQualityKeptLowIfUpscale) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kLow_SkFilterQuality,
CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -175,7 +171,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.4f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -194,7 +190,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropToLowIfEnlarging) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -214,7 +210,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropToLowIfIdentity) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -235,7 +231,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -256,7 +252,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -277,7 +273,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -298,7 +294,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt1_5Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -318,7 +314,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt1_0cale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -338,7 +334,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyLowQualityAt0_75Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -358,7 +354,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_5Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -377,7 +373,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_49Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -396,7 +392,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_1Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -415,7 +411,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_01Scale) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -435,7 +431,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.2f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -454,7 +450,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyUpscaleIsLowQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(2.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -477,7 +473,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyHighQualityDropToMediumIfTooLarge) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.45f, 0.45f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -497,7 +493,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -517,7 +513,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyHighQualityDropToLowIfIdentity) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -538,7 +534,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -559,7 +555,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -594,7 +590,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageKeyDownscaleMipLevelWithRounding) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kMedium_SkFilterQuality,
CreateMatrix(SkSize::Make(0.2f, 0.2f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -614,7 +610,7 @@ TEST(SoftwareImageDecodeCacheTest, OriginalDecodesAreEqual) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -628,7 +624,7 @@ TEST(SoftwareImageDecodeCacheTest, OriginalDecodesAreEqual) {
DrawImage another_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto another_key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
another_draw_image, kN32_SkColorType);
@@ -651,7 +647,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageRectDoesNotContainSrcRect) {
paint_image,
SkIRect::MakeXYWH(25, 35, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -672,7 +668,7 @@ TEST(SoftwareImageDecodeCacheTest, ImageRectDoesNotContainSrcRectWithScale) {
paint_image,
SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
draw_image, kN32_SkColorType);
@@ -693,7 +689,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -702,7 +698,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImage) {
DrawImage another_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult another_result = cache.GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -723,7 +719,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageProcessUnrefCancel) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -753,7 +749,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentQuality) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kHigh_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult high_quality_result =
cache.GetTaskForImageAndRef(high_quality_draw_image,
ImageDecodeCache::TracingInfo());
@@ -764,7 +760,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentQuality) {
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
kNone_SkFilterQuality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult none_quality_result =
cache.GetTaskForImageAndRef(none_quality_draw_image,
ImageDecodeCache::TracingInfo());
@@ -788,7 +784,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentSize) {
DrawImage half_size_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult half_size_result = cache.GetTaskForImageAndRef(
half_size_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(half_size_result.need_unref);
@@ -797,7 +793,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentSize) {
DrawImage quarter_size_draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult quarter_size_result =
cache.GetTaskForImageAndRef(quarter_size_draw_image,
ImageDecodeCache::TracingInfo());
@@ -822,7 +818,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageDifferentImage) {
first_paint_image,
SkIRect::MakeWH(first_paint_image.width(), first_paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -833,18 +829,75 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageDifferentImage) {
second_paint_image,
SkIRect::MakeWH(second_paint_image.width(), second_paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
+ second_draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(second_result.need_unref);
+ EXPECT_TRUE(second_result.task);
+ EXPECT_TRUE(first_result.task.get() != second_result.task.get());
+
+ TestTileTaskRunner::ProcessTask(first_result.task.get());
+ TestTileTaskRunner::ProcessTask(second_result.task.get());
+
+ cache.UnrefImage(first_draw_image);
+ cache.UnrefImage(second_draw_image);
+}
+
+// crbug.com/709341
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_GetTaskForImageDifferentColorSpace \
+ DISABLED_GetTaskForImageDifferentColorSpace
+#else
+#define MAYBE_GetTaskForImageDifferentColorSpace \
+ GetTaskForImageDifferentColorSpace
+#endif
+TEST(SoftwareImageDecodeCacheTest, MAYBE_GetTaskForImageDifferentColorSpace) {
+ TestSoftwareImageDecodeCache cache;
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ gfx::ColorSpace color_space_a(gfx::ColorSpace::PrimaryID::XYZ_D50,
+ gfx::ColorSpace::TransferID::IEC61966_2_1);
+ gfx::ColorSpace color_space_b(gfx::ColorSpace::PrimaryID::SMPTE170M,
+ gfx::ColorSpace::TransferID::IEC61966_2_1);
+ gfx::ColorSpace color_space_c = gfx::ColorSpace::CreateSRGB();
+
+ PaintImage paint_image = CreatePaintImage(100, 100, color_space_a);
+ DrawImage first_draw_image(
+ paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, color_space_b);
+ ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
+ first_draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(first_result.need_unref);
+ EXPECT_TRUE(first_result.task);
+
+ DrawImage second_draw_image(
+ paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, color_space_c);
ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
EXPECT_TRUE(second_result.task);
EXPECT_TRUE(first_result.task.get() != second_result.task.get());
+ DrawImage third_draw_image(
+ paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ PaintImage::kDefaultFrameIndex, color_space_b);
+ ImageDecodeCache::TaskResult third_result = cache.GetTaskForImageAndRef(
+ third_draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(third_result.need_unref);
+ EXPECT_TRUE(third_result.task);
+ EXPECT_TRUE(first_result.task.get() == third_result.task.get());
+
TestTileTaskRunner::ProcessTask(first_result.task.get());
TestTileTaskRunner::ProcessTask(second_result.task.get());
cache.UnrefImage(first_draw_image);
cache.UnrefImage(second_draw_image);
+ cache.UnrefImage(third_draw_image);
}
TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyDecoded) {
@@ -856,7 +909,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyDecoded) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -885,7 +938,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyPrerolled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -920,7 +973,7 @@ TEST(SoftwareImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -961,7 +1014,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1001,7 +1054,7 @@ TEST(SoftwareImageDecodeCacheTest, GetDecodedImageForDraw) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1034,7 +1087,7 @@ TEST(SoftwareImageDecodeCacheTest,
paint_image,
SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1065,7 +1118,7 @@ TEST(SoftwareImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
@@ -1090,7 +1143,7 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
@@ -1120,7 +1173,7 @@ TEST(SoftwareImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1144,7 +1197,7 @@ TEST(SoftwareImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {
paint_image,
SkIRect::MakeXYWH(150, 150, paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1167,7 +1220,7 @@ TEST(SoftwareImageDecodeCacheTest, LowQualityFilterIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1195,7 +1248,7 @@ TEST(SoftwareImageDecodeCacheTest, LowQualityScaledSubrectIsHandled) {
PaintImage paint_image = CreatePaintImage(100, 100);
DrawImage draw_image(paint_image, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1228,7 +1281,7 @@ TEST(SoftwareImageDecodeCacheTest, NoneQualityScaledSubrectIsHandled) {
PaintImage paint_image = CreatePaintImage(100, 100);
DrawImage draw_image(paint_image, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1259,7 +1312,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt01_5ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1290,7 +1343,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt1_0ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1321,7 +1374,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_75ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1352,7 +1405,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_5ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1383,7 +1436,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_49ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1414,7 +1467,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_1ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1445,7 +1498,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_01ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1476,7 +1529,7 @@ TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_001ScaleIsHandled) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.001f, 0.001f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1500,11 +1553,11 @@ TEST(SoftwareImageDecodeCacheTest,
DrawImage draw_image_50(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DrawImage draw_image_49(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result_50 = cache.GetTaskForImageAndRef(
draw_image_50, ImageDecodeCache::TracingInfo());
@@ -1551,7 +1604,7 @@ TEST(SoftwareImageDecodeCacheTest, ClearCache) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1586,9 +1639,10 @@ TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 1u);
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ 1u, DefaultColorSpace());
auto decoded_image = cache.GetDecodedImageForDraw(draw_image);
ASSERT_TRUE(decoded_image.image());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
@@ -1597,7 +1651,8 @@ TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
cache.DrawWithImageFinished(draw_image, decoded_image);
// Scaled.
- DrawImage scaled_draw_image(draw_image, 0.5f, 2u);
+ DrawImage scaled_draw_image(draw_image, 0.5f, 2u,
+ draw_image.target_color_space());
decoded_image = cache.GetDecodedImageForDraw(scaled_draw_image);
ASSERT_TRUE(decoded_image.image());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
@@ -1608,7 +1663,8 @@ TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
// Subset.
DrawImage subset_draw_image(
image, SkIRect::MakeWH(5, 5), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u);
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
+ DefaultColorSpace());
decoded_image = cache.GetDecodedImageForDraw(subset_draw_image);
ASSERT_TRUE(decoded_image.image());
ASSERT_EQ(generator->frames_decoded().size(), 1u);
@@ -1628,7 +1684,7 @@ TEST(SoftwareImageDecodeCacheTest, SizeSubrectingIsHandled) {
DefaultColorSpace().ToSkColorSpace(), false);
DrawImage draw_image(paint_image, SkIRect::MakeXYWH(0, 0, 10, 10), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1661,7 +1717,7 @@ TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
gfx::Size(100, 100), DefaultColorSpace().ToSkColorSpace());
DrawImage draw_image(paint_image, SkIRect::MakeWH(100, 100), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
EXPECT_TRUE(decoded_draw_image.image());
@@ -1671,7 +1727,7 @@ TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
DrawImage empty_draw_image(
paint_image, SkIRect::MakeEmpty(), quality,
CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage empty_decoded_draw_image =
cache.GetDecodedImageForDraw(empty_draw_image);
EXPECT_FALSE(empty_decoded_draw_image.image());
@@ -1679,16 +1735,16 @@ TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
}
TEST(SoftwareImageDecodeCacheTest, BitmapImageColorConverted) {
- gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateDisplayP3D65();
- TestSoftwareImageDecodeCache cache(target_color_space);
+ TestSoftwareImageDecodeCache cache;
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
+ gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateDisplayP3D65();
PaintImage paint_image = CreateBitmapImage(gfx::Size(100, 100));
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, target_color_space);
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
@@ -1712,7 +1768,7 @@ TEST(SoftwareImageDecodeCacheTest, BitmapImageNotColorConverted) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// The cache should not support this image.
EXPECT_FALSE(cache.UseCacheForDrawImage(draw_image));
@@ -1738,7 +1794,7 @@ TEST(SoftwareImageDecodeCacheTest, DISABLED_ContentIdCaching) {
paint_image,
SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
CreateMatrix(SkSize::Make(scale, scale), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_draw_image =
cache.GetDecodedImageForDraw(draw_image);
EXPECT_TRUE(decoded_draw_image.image());
@@ -1777,7 +1833,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScale) {
DrawImage draw_image1(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_image1 = cache.GetDecodedImageForDraw(draw_image1);
ASSERT_TRUE(decoded_image1.image());
EXPECT_EQ(decoded_image1.image()->width(), 50);
@@ -1794,7 +1850,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScale) {
DrawImage draw_image2(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.25, 0.25), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_image2 = cache.GetDecodedImageForDraw(draw_image2);
ASSERT_TRUE(decoded_image2.image());
EXPECT_EQ(decoded_image2.image()->width(), 25);
@@ -1834,7 +1890,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScaleSubrect) {
// subrect vetoes decode to scale.
DrawImage draw_image(paint_image, SkIRect::MakeWH(50, 50), quality,
CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
ASSERT_TRUE(decoded_image.image());
EXPECT_EQ(decoded_image.image()->width(), 25);
@@ -1870,7 +1926,7 @@ TEST(SoftwareImageDecodeCacheTest, DecodeToScaleNoneQuality) {
DrawImage draw_image(
paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
ASSERT_TRUE(decoded_image.image());
EXPECT_EQ(decoded_image.image()->width(), 100);
diff --git a/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc b/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
index 03d3e09e2f5..5052a2a5d21 100644
--- a/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_unittest_combinations.cc
@@ -50,7 +50,7 @@ class BaseTest : public testing::Test {
? SkIRect::MakeWH(paint_image().width(), paint_image().height())
: src_rect,
kMedium_SkFilterQuality, CreateMatrix(SkSize::Make(scale, scale), true),
- PaintImage::kDefaultFrameIndex);
+ PaintImage::kDefaultFrameIndex, GetColorSpace());
}
SoftwareImageDecodeCache& cache() { return *cache_; }
@@ -80,8 +80,7 @@ class N32Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kN32_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId,
- GetColorSpace().ToSkColorSpace());
+ PaintImage::kDefaultGeneratorClientId);
}
};
@@ -90,8 +89,7 @@ class RGBA4444Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kARGB_4444_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId,
- GetColorSpace().ToSkColorSpace());
+ PaintImage::kDefaultGeneratorClientId);
}
};
@@ -100,8 +98,7 @@ class RGBA_F16Cache : public virtual BaseTest {
std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
return std::make_unique<SoftwareImageDecodeCache>(
kRGBA_F16_SkColorType, kLockedMemoryLimitBytes,
- PaintImage::kDefaultGeneratorClientId,
- GetColorSpace().ToSkColorSpace());
+ PaintImage::kDefaultGeneratorClientId);
}
};
@@ -138,6 +135,9 @@ class Predecode : public virtual BaseTest {
const DrawImage& draw_image,
const gfx::Size& expected_size) override {
auto decoded = cache().GetDecodedImageForDraw(draw_image);
+ EXPECT_TRUE(SkColorSpace::Equals(
+ decoded.image()->colorSpace(),
+ draw_image.target_color_space().ToSkColorSpace().get()));
SCOPED_TRACE(base::StringPrintf("Failure from line %d", line));
EXPECT_EQ(decoded.image()->width(), expected_size.width());
EXPECT_EQ(decoded.image()->height(), expected_size.height());
diff --git a/chromium/cc/tiles/software_image_decode_cache_utils.cc b/chromium/cc/tiles/software_image_decode_cache_utils.cc
index fac25c22ae6..b3dae159e5d 100644
--- a/chromium/cc/tiles/software_image_decode_cache_utils.cc
+++ b/chromium/cc/tiles/software_image_decode_cache_utils.cc
@@ -59,7 +59,6 @@ SoftwareImageDecodeCacheUtils::DoDecodeImage(
const CacheKey& key,
const PaintImage& paint_image,
SkColorType color_type,
- sk_sp<SkColorSpace> color_space,
PaintImage::GeneratorClientId client_id) {
SkISize target_size =
SkISize::Make(key.target_size().width(), key.target_size().height());
@@ -75,7 +74,7 @@ SoftwareImageDecodeCacheUtils::DoDecodeImage(
"SoftwareImageDecodeCacheUtils::DoDecodeImage - "
"decode");
bool result = paint_image.Decode(target_pixels->data(), &target_info,
- std::move(color_space),
+ key.target_color_space().ToSkColorSpace(),
key.frame_key().frame_index(), client_id);
if (!result) {
target_pixels->Unlock();
@@ -181,7 +180,7 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
// the filter quality doesn't matter. Early out instead.
if (target_size.IsEmpty()) {
return CacheKey(frame_key, stable_id, kSubrectAndScale, false, src_rect,
- target_size);
+ target_size, image.target_color_space());
}
ProcessingType type = kOriginal;
@@ -234,7 +233,7 @@ SoftwareImageDecodeCacheUtils::CacheKey::FromDrawImage(const DrawImage& image,
}
return CacheKey(frame_key, stable_id, type, is_nearest_neighbor, src_rect,
- target_size);
+ target_size, image.target_color_space());
}
SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(
@@ -243,13 +242,15 @@ SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(
ProcessingType type,
bool is_nearest_neighbor,
const gfx::Rect& src_rect,
- const gfx::Size& target_size)
+ const gfx::Size& target_size,
+ const gfx::ColorSpace& target_color_space)
: frame_key_(frame_key),
stable_id_(stable_id),
type_(type),
is_nearest_neighbor_(is_nearest_neighbor),
src_rect_(src_rect),
- target_size_(target_size) {
+ target_size_(target_size),
+ target_color_space_(target_color_space) {
if (type == kOriginal) {
hash_ = frame_key_.hash();
} else {
@@ -266,6 +267,8 @@ SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(
hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash),
frame_key_.hash());
}
+ // Include the target color space in the hash regardless of scaling.
+ hash_ = base::HashInts(hash_, target_color_space.GetHash());
}
SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(const CacheKey& other) =
@@ -287,6 +290,7 @@ std::string SoftwareImageDecodeCacheUtils::CacheKey::ToString() const {
}
str << "]\nis_nearest_neightbor[" << is_nearest_neighbor_ << "]\nsrc_rect["
<< src_rect_.ToString() << "]\ntarget_size[" << target_size_.ToString()
+ << "]\ntarget_color_space[" << target_color_space_.ToString()
<< "]\nhash[" << hash_ << "]";
return str.str();
}
diff --git a/chromium/cc/tiles/software_image_decode_cache_utils.h b/chromium/cc/tiles/software_image_decode_cache_utils.h
index 42d7b0205ce..835d68c8492 100644
--- a/chromium/cc/tiles/software_image_decode_cache_utils.h
+++ b/chromium/cc/tiles/software_image_decode_cache_utils.h
@@ -16,6 +16,7 @@
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSize.h"
+#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -56,6 +57,7 @@ class SoftwareImageDecodeCacheUtils {
// image.
DCHECK(!is_nearest_neighbor_ || type_ == kOriginal);
return frame_key_ == other.frame_key_ && type_ == other.type_ &&
+ target_color_space_ == other.target_color_space_ &&
(type_ == kOriginal || (src_rect_ == other.src_rect_ &&
target_size_ == other.target_size_));
}
@@ -68,6 +70,9 @@ class SoftwareImageDecodeCacheUtils {
bool is_nearest_neighbor() const { return is_nearest_neighbor_; }
gfx::Rect src_rect() const { return src_rect_; }
gfx::Size target_size() const { return target_size_; }
+ const gfx::ColorSpace& target_color_space() const {
+ return target_color_space_;
+ }
size_t get_hash() const { return hash_; }
@@ -89,7 +94,8 @@ class SoftwareImageDecodeCacheUtils {
ProcessingType type,
bool is_nearest_neighbor,
const gfx::Rect& src_rect,
- const gfx::Size& size);
+ const gfx::Size& size,
+ const gfx::ColorSpace& target_color_space);
PaintImage::FrameKey frame_key_;
// The stable id is does not factor into the cache key's value for hashing
@@ -100,6 +106,7 @@ class SoftwareImageDecodeCacheUtils {
bool is_nearest_neighbor_;
gfx::Rect src_rect_;
gfx::Size target_size_;
+ gfx::ColorSpace target_color_space_;
size_t hash_;
};
@@ -179,7 +186,6 @@ class SoftwareImageDecodeCacheUtils {
const CacheKey& key,
const PaintImage& image,
SkColorType color_type,
- sk_sp<SkColorSpace> color_space,
PaintImage::GeneratorClientId client_id);
static std::unique_ptr<CacheEntry> GenerateCacheEntryFromCandidate(
const CacheKey& key,
diff --git a/chromium/cc/tiles/tile_draw_info.cc b/chromium/cc/tiles/tile_draw_info.cc
index 0c09fa281d7..f5c3138851a 100644
--- a/chromium/cc/tiles/tile_draw_info.cc
+++ b/chromium/cc/tiles/tile_draw_info.cc
@@ -22,7 +22,6 @@ void TileDrawInfo::AsValueInto(base::trace_event::TracedValue* state) const {
void TileDrawInfo::SetResource(ResourcePool::InUsePoolResource resource,
bool resource_is_checker_imaged,
- bool contents_swizzled,
bool is_premultiplied) {
DCHECK(!resource_);
DCHECK(resource);
@@ -30,7 +29,6 @@ void TileDrawInfo::SetResource(ResourcePool::InUsePoolResource resource,
mode_ = RESOURCE_MODE;
is_resource_ready_to_draw_ = false;
resource_is_checker_imaged_ = resource_is_checker_imaged;
- contents_swizzled_ = contents_swizzled;
is_premultiplied_ = is_premultiplied;
resource_ = std::move(resource);
}
@@ -46,7 +44,6 @@ ResourcePool::InUsePoolResource TileDrawInfo::TakeResource() {
DCHECK(resource_);
is_resource_ready_to_draw_ = false;
resource_is_checker_imaged_ = false;
- contents_swizzled_ = false;
is_premultiplied_ = false;
return std::move(resource_);
}
diff --git a/chromium/cc/tiles/tile_draw_info.h b/chromium/cc/tiles/tile_draw_info.h
index 993fcdc1c30..c38cc45a3bd 100644
--- a/chromium/cc/tiles/tile_draw_info.h
+++ b/chromium/cc/tiles/tile_draw_info.h
@@ -72,7 +72,6 @@ class CC_EXPORT TileDrawInfo {
return solid_color_;
}
- bool contents_swizzled() const { return contents_swizzled_; }
bool is_premultiplied() const { return is_premultiplied_; }
bool requires_resource() const {
@@ -98,7 +97,6 @@ class CC_EXPORT TileDrawInfo {
void SetResource(ResourcePool::InUsePoolResource resource,
bool resource_is_checker_imaged,
- bool contents_swizzled,
bool is_premultiplied);
ResourcePool::InUsePoolResource TakeResource();
@@ -117,7 +115,6 @@ class CC_EXPORT TileDrawInfo {
Mode mode_ = RESOURCE_MODE;
SkColor solid_color_ = SK_ColorWHITE;
ResourcePool::InUsePoolResource resource_;
- bool contents_swizzled_ = false;
bool is_premultiplied_ = false;
bool is_resource_ready_to_draw_ = false;
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index e797e6db4a4..165bb015145 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -40,37 +40,6 @@ namespace {
// a tile is of solid color.
const bool kUseColorEstimator = true;
-DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
- ScopedSoftwareRasterTaskTimer,
- "Compositing.%s.RasterTask.RasterUs.Software",
- "Compositing.%s.RasterTask.RasterPixelsPerMs2.Software")
-
-DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
- ScopedGpuRasterTaskTimer,
- "Compositing.%s.RasterTask.RasterUs.Gpu",
- "Compositing.%s.RasterTask.RasterPixelsPerMs2.Gpu")
-
-class ScopedRasterTaskTimer {
- public:
- explicit ScopedRasterTaskTimer(bool use_gpu_rasterization) {
- if (use_gpu_rasterization)
- gpu_timer_.emplace();
- else
- software_timer_.emplace();
- }
-
- void SetArea(int area) {
- if (software_timer_)
- software_timer_->SetArea(area);
- if (gpu_timer_)
- gpu_timer_->SetArea(area);
- }
-
- private:
- base::Optional<ScopedSoftwareRasterTaskTimer> software_timer_;
- base::Optional<ScopedGpuRasterTaskTimer> gpu_timer_;
-};
-
// This class is wrapper for both ImageProvider and PaintWorkletImageProvider,
// which is used in RasterSource::PlaybackSettings. It looks at the draw image
// and decides which one of the two providers to dispatch the request to.
@@ -132,7 +101,6 @@ class RasterTaskImpl : public TileTask {
tile_tracing_id_(static_cast<void*>(tile)),
new_content_id_(tile->id()),
source_frame_number_(tile->source_frame_number()),
- is_gpu_rasterization_(is_gpu_rasterization),
raster_buffer_(std::move(raster_buffer)),
image_provider_(std::move(image_provider)),
url_(std::move(url)) {
@@ -152,8 +120,6 @@ class RasterTaskImpl : public TileTask {
frame_viewer_instrumentation::ScopedRasterTask raster_task(
tile_tracing_id_, tile_resolution_, source_frame_number_, layer_id_);
- ScopedRasterTaskTimer timer(is_gpu_rasterization_);
- timer.SetArea(content_rect_.size().GetArea());
DCHECK(raster_source_);
@@ -203,7 +169,6 @@ class RasterTaskImpl : public TileTask {
void* tile_tracing_id_;
uint64_t new_content_id_;
int source_frame_number_;
- bool is_gpu_rasterization_;
std::unique_ptr<RasterBuffer> raster_buffer_;
DispatchingImageProvider image_provider_;
GURL url_;
@@ -717,6 +682,8 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(),
resource_pool_->resource_count());
+ gfx::ColorSpace raster_color_space = client_->GetRasterColorSpace();
+
std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue(
client_->BuildRasterQueue(global_state_.tree_priority,
RasterTilePriorityQueue::Type::ALL));
@@ -769,7 +736,8 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
DCHECK(prioritized_tile.should_decode_checkered_images_for_tile());
AddCheckeredImagesToDecodeQueue(
- prioritized_tile, CheckerImageTracker::DecodeType::kRaster,
+ prioritized_tile, raster_color_space,
+ CheckerImageTracker::DecodeType::kRaster,
&work_to_schedule.checker_image_decode_queue);
continue;
}
@@ -825,13 +793,15 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
if (tile->raster_task_scheduled_with_checker_images() &&
prioritized_tile.should_decode_checkered_images_for_tile()) {
AddCheckeredImagesToDecodeQueue(
- prioritized_tile, CheckerImageTracker::DecodeType::kRaster,
+ prioritized_tile, raster_color_space,
+ CheckerImageTracker::DecodeType::kRaster,
&work_to_schedule.checker_image_decode_queue);
}
} else {
// Creating the raster task here will acquire resources, but
// this resource usage has already been accounted for above.
- auto raster_task = CreateRasterTask(prioritized_tile, &work_to_schedule);
+ auto raster_task = CreateRasterTask(
+ prioritized_tile, client_->GetRasterColorSpace(), &work_to_schedule);
if (!raster_task) {
continue;
}
@@ -871,7 +841,8 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
if (tile->draw_info().is_checker_imaged() ||
tile->raster_task_scheduled_with_checker_images()) {
AddCheckeredImagesToDecodeQueue(
- prioritized_tile, CheckerImageTracker::DecodeType::kRaster,
+ prioritized_tile, raster_color_space,
+ CheckerImageTracker::DecodeType::kRaster,
&work_to_schedule.checker_image_decode_queue);
}
}
@@ -928,6 +899,7 @@ void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
void TileManager::PartitionImagesForCheckering(
const PrioritizedTile& prioritized_tile,
+ const gfx::ColorSpace& raster_color_space,
std::vector<DrawImage>* sync_decoded_images,
std::vector<PaintImage>* checkered_images,
const gfx::Rect* invalidated_rect,
@@ -950,7 +922,7 @@ void TileManager::PartitionImagesForCheckering(
(*image_to_frame_index)[image.stable_id()] = frame_index;
DrawImage draw_image(*original_draw_image, tile->raster_transform().scale(),
- frame_index);
+ frame_index, raster_color_space);
if (checker_image_tracker_.ShouldCheckerImage(draw_image, tree))
checkered_images->push_back(draw_image.paint_image());
else
@@ -960,6 +932,7 @@ void TileManager::PartitionImagesForCheckering(
void TileManager::AddCheckeredImagesToDecodeQueue(
const PrioritizedTile& prioritized_tile,
+ const gfx::ColorSpace& raster_color_space,
CheckerImageTracker::DecodeType decode_type,
CheckerImageTracker::ImageDecodeQueue* image_decode_queue) {
Tile* tile = prioritized_tile.tile();
@@ -972,7 +945,7 @@ void TileManager::AddCheckeredImagesToDecodeQueue(
size_t frame_index = client_->GetFrameIndexForImage(
original_draw_image->paint_image(), tree);
DrawImage draw_image(*original_draw_image, tile->raster_transform().scale(),
- frame_index);
+ frame_index, raster_color_space);
if (checker_image_tracker_.ShouldCheckerImage(draw_image, tree)) {
image_decode_queue->emplace_back(draw_image.paint_image(), decode_type);
}
@@ -1008,6 +981,8 @@ void TileManager::ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule) {
graph_.Reset();
+ gfx::ColorSpace raster_color_space = client_->GetRasterColorSpace();
+
scoped_refptr<TileTask> required_for_activation_done_task =
CreateTaskSetFinishedTask(
&TileManager::DidFinishRunningTileTasksRequiredForActivation);
@@ -1063,8 +1038,9 @@ void TileManager::ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule) {
for (const PrioritizedTile& prioritized_tile : tiles_to_process_for_images) {
std::vector<DrawImage> sync_decoded_images;
std::vector<PaintImage> checkered_images;
- PartitionImagesForCheckering(prioritized_tile, &sync_decoded_images,
- &checkered_images, nullptr);
+ PartitionImagesForCheckering(prioritized_tile, raster_color_space,
+ &sync_decoded_images, &checkered_images,
+ nullptr);
// Add the sync decoded images to |new_locked_images| so they can be added
// to the task graph.
@@ -1156,6 +1132,7 @@ void TileManager::ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule) {
scoped_refptr<TileTask> TileManager::CreateRasterTask(
const PrioritizedTile& prioritized_tile,
+ const gfx::ColorSpace& raster_color_space,
PrioritizedWorkToSchedule* work_to_schedule) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"TileManager::CreateRasterTask");
@@ -1172,7 +1149,7 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
tile->id(), tile->invalidated_content_rect(), tile->invalidated_id(),
&invalidated_rect);
}
- const gfx::ColorSpace& raster_color_space = client_->GetRasterColorSpace();
+
bool partial_tile_decode = false;
if (resource) {
resource_content_id = tile->invalidated_id();
@@ -1203,8 +1180,8 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
base::flat_map<PaintImage::Id, size_t> image_id_to_current_frame_index;
if (!skip_images) {
PartitionImagesForCheckering(
- prioritized_tile, &sync_decoded_images, &checkered_images,
- partial_tile_decode ? &invalidated_rect : nullptr,
+ prioritized_tile, raster_color_space, &sync_decoded_images,
+ &checkered_images, partial_tile_decode ? &invalidated_rect : nullptr,
&image_id_to_current_frame_index);
}
@@ -1268,7 +1245,7 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
}
PlaybackImageProvider image_provider(image_controller_.cache(),
- std::move(settings));
+ raster_color_space, std::move(settings));
PaintWorkletImageProvider paint_worklet_image_provider(
image_controller_.paint_worklet_image_cache());
DispatchingImageProvider dispatching_image_provider(
@@ -1340,11 +1317,10 @@ void TileManager::OnRasterTaskCompleted(
TileDrawInfo& draw_info = tile->draw_info();
if (exported) {
- bool needs_swizzle = raster_buffer_provider_->IsResourceSwizzleRequired();
bool is_premultiplied = raster_buffer_provider_->IsResourcePremultiplied();
draw_info.SetResource(std::move(resource),
raster_task_was_scheduled_with_checker_images,
- needs_swizzle, is_premultiplied);
+ is_premultiplied);
} else {
resource_pool_->ReleaseResource(std::move(resource));
draw_info.set_oom();
diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h
index 30d55902837..015ce53e837 100644
--- a/chromium/cc/tiles/tile_manager.h
+++ b/chromium/cc/tiles/tile_manager.h
@@ -212,7 +212,7 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
}
bool exported = resource_pool_->PrepareForExport(resource);
DCHECK(exported);
- draw_info.SetResource(std::move(resource), false, false, false);
+ draw_info.SetResource(std::move(resource), false, false);
draw_info.set_resource_ready_for_draw();
}
}
@@ -355,6 +355,7 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile);
scoped_refptr<TileTask> CreateRasterTask(
const PrioritizedTile& prioritized_tile,
+ const gfx::ColorSpace& raster_color_space,
PrioritizedWorkToSchedule* work_to_schedule);
std::unique_ptr<EvictionTilePriorityQueue>
@@ -387,12 +388,14 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
void PartitionImagesForCheckering(
const PrioritizedTile& prioritized_tile,
+ const gfx::ColorSpace& raster_color_space,
std::vector<DrawImage>* sync_decoded_images,
std::vector<PaintImage>* checkered_images,
const gfx::Rect* invalidated_rect,
base::flat_map<PaintImage::Id, size_t>* image_to_frame_index = nullptr);
void AddCheckeredImagesToDecodeQueue(
const PrioritizedTile& prioritized_tile,
+ const gfx::ColorSpace& raster_color_space,
CheckerImageTracker::DecodeType decode_type,
CheckerImageTracker::ImageDecodeQueue* image_decode_queue);
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index 43f7f2a354f..9c6d1e0516b 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -1540,6 +1540,9 @@ class TestSoftwareBacking : public ResourcePool::SoftwareBacking {
// into the pixels in the array.
class TestSoftwareRasterBufferProvider : public FakeRasterBufferProviderImpl {
public:
+ static constexpr bool kIsGpuCompositing = true;
+ static constexpr viz::ResourceFormat kResourceFormat = viz::RGBA_8888;
+
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
@@ -1549,7 +1552,7 @@ class TestSoftwareRasterBufferProvider : public FakeRasterBufferProviderImpl {
backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
backing->pixels = std::make_unique<uint32_t[]>(
viz::ResourceSizes::CheckedSizeInBytes<size_t>(resource.size(),
- viz::RGBA_8888));
+ kResourceFormat));
resource.set_software_backing(std::move(backing));
}
auto* backing =
@@ -1572,9 +1575,9 @@ class TestSoftwareRasterBufferProvider : public FakeRasterBufferProviderImpl {
const RasterSource::PlaybackSettings& playback_settings,
const GURL& url) override {
RasterBufferProvider::PlaybackToMemory(
- pixels_, viz::RGBA_8888, size_, /*stride=*/0, raster_source,
+ pixels_, kResourceFormat, size_, /*stride=*/0, raster_source,
raster_full_rect, /*playback_rect=*/raster_full_rect, transform,
- gfx::ColorSpace(), /*gpu_compositing=*/true, playback_settings);
+ gfx::ColorSpace(), kIsGpuCompositing, playback_settings);
}
private:
@@ -1805,8 +1808,11 @@ TEST_F(PixelInspectTileManagerTest, LowResHasNoImage) {
EXPECT_TRUE(tile->draw_info().IsReadyToDraw());
gfx::Size resource_size = tile->draw_info().resource_size();
- auto info = SkImageInfo::MakeN32Premul(resource_size.width(),
- resource_size.height());
+ SkColorType ct = ResourceFormatToClosestSkColorType(
+ TestSoftwareRasterBufferProvider::kIsGpuCompositing,
+ TestSoftwareRasterBufferProvider::kResourceFormat);
+ auto info = SkImageInfo::Make(resource_size.width(), resource_size.height(),
+ ct, kPremul_SkAlphaType);
// CreateLayerTreeFrameSink() sets up a software compositing, so the
// tile resource will be a bitmap.
auto* backing = static_cast<TestSoftwareBacking*>(
@@ -3363,9 +3369,9 @@ TEST_F(DecodedImageTrackerTileManagerTest, DecodedImageTrackerDropsLocksOnUse) {
// Add the images to our decoded_image_tracker.
host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
- image1, base::DoNothing());
+ image1, gfx::ColorSpace(), base::DoNothing());
host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
- image2, base::DoNothing());
+ image2, gfx::ColorSpace(), base::DoNothing());
EXPECT_EQ(0u, host_impl()
->tile_manager()
->decoded_image_tracker()
diff --git a/chromium/cc/trees/animation_effect_timings.h b/chromium/cc/trees/animation_effect_timings.h
new file mode 100644
index 00000000000..c66ab652de0
--- /dev/null
+++ b/chromium/cc/trees/animation_effect_timings.h
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_ANIMATION_EFFECT_TIMINGS_H_
+#define CC_TREES_ANIMATION_EFFECT_TIMINGS_H_
+
+#include <memory>
+
+#include "cc/cc_export.h"
+
+namespace cc {
+
+// This class acts as opaque handle in cc while the actual implementation lives
+// in blink. It is meant to facilitate plumbing the effect timings from blink
+// main thread to worklet thread via cc animations machinery.
+class CC_EXPORT AnimationEffectTimings {
+ public:
+ virtual ~AnimationEffectTimings() = default;
+ virtual std::unique_ptr<AnimationEffectTimings> Clone() const = 0;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_ANIMATION_EFFECT_TIMINGS_H_
diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc
index 1fb0255a0cc..07e6bd172b0 100644
--- a/chromium/cc/trees/debug_rect_history.cc
+++ b/chromium/cc/trees/debug_rect_history.cc
@@ -8,6 +8,7 @@
#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"
#include "cc/layers/layer_list_iterator.h"
#include "cc/layers/render_surface_impl.h"
@@ -30,7 +31,7 @@ DebugRectHistory::~DebugRectHistory() = default;
void DebugRectHistory::SaveDebugRectsForCurrentFrame(
LayerTreeImpl* tree_impl,
- LayerImpl* hud_layer,
+ HeadsUpDisplayLayerImpl* hud_layer,
const RenderSurfaceList& render_surface_list,
const LayerTreeDebugState& debug_state) {
// For now, clear all rects from previous frames. In the future we may want to
@@ -49,6 +50,9 @@ void DebugRectHistory::SaveDebugRectsForCurrentFrame(
if (debug_state.show_non_fast_scrollable_rects)
SaveNonFastScrollableRects(tree_impl);
+ if (debug_state.show_layout_shift_regions)
+ SaveLayoutShiftRects(hud_layer);
+
if (debug_state.show_paint_rects)
SavePaintRects(tree_impl);
@@ -62,6 +66,14 @@ void DebugRectHistory::SaveDebugRectsForCurrentFrame(
SaveScreenSpaceRects(render_surface_list);
}
+void DebugRectHistory::SaveLayoutShiftRects(HeadsUpDisplayLayerImpl* hud) {
+ for (gfx::Rect rect : hud->LayoutShiftRects()) {
+ debug_rects_.push_back(DebugRect(
+ LAYOUT_SHIFT_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(hud->ScreenSpaceTransform(), rect)));
+ }
+}
+
void DebugRectHistory::SavePaintRects(LayerTreeImpl* tree_impl) {
// We would like to visualize where any layer's paint rect (update rect) has
// changed, regardless of whether this layer is skipped for actual drawing or
diff --git a/chromium/cc/trees/debug_rect_history.h b/chromium/cc/trees/debug_rect_history.h
index 94d1ee95c0e..d9b6da071b9 100644
--- a/chromium/cc/trees/debug_rect_history.h
+++ b/chromium/cc/trees/debug_rect_history.h
@@ -17,8 +17,9 @@ namespace cc {
class LayerImpl;
class LayerTreeDebugState;
class LayerTreeImpl;
+class HeadsUpDisplayLayerImpl;
-// There are currently six types of debug rects:
+// There are various types of debug rects:
//
// - Paint rects (update rects): regions of a layer that needed to be
// re-uploaded to the texture resource; in most cases implying that they had to
@@ -33,6 +34,9 @@ class LayerTreeImpl;
// paint rects, (2) property- changed rects, and (3) newly exposed areas.
//
// - Screen space rects: this is the region the contents occupy in screen space.
+//
+// - Layout shift rects: regions of an animation frame that were shifted while
+// the page is loading content.
enum DebugRectType {
PAINT_RECT_TYPE,
PROPERTY_CHANGED_RECT_TYPE,
@@ -43,6 +47,7 @@ enum DebugRectType {
SCROLL_EVENT_HANDLER_RECT_TYPE,
NON_FAST_SCROLLABLE_RECT_TYPE,
ANIMATION_BOUNDS_RECT_TYPE,
+ LAYOUT_SHIFT_RECT_TYPE,
};
struct DebugRect {
@@ -79,7 +84,7 @@ class DebugRectHistory {
// reset.
void SaveDebugRectsForCurrentFrame(
LayerTreeImpl* tree_impl,
- LayerImpl* hud_layer,
+ HeadsUpDisplayLayerImpl* hud_layer,
const RenderSurfaceList& render_surface_list,
const LayerTreeDebugState& debug_state);
@@ -88,6 +93,7 @@ class DebugRectHistory {
private:
DebugRectHistory();
+ void SaveLayoutShiftRects(HeadsUpDisplayLayerImpl* hud);
void SavePaintRects(LayerTreeImpl* tree_impl);
void SavePropertyChangedRects(LayerTreeImpl* tree_impl, LayerImpl* hud_layer);
void SaveSurfaceDamageRects(const RenderSurfaceList& render_surface_list);
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index e32fa24aa1c..9c1bec65c92 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -49,7 +49,7 @@ static void PostConcatSurfaceContentsScale(const EffectNode* effect_node,
// doesn't set effect ids on clip nodes.
return;
}
- DCHECK(effect_node->has_render_surface);
+ DCHECK(effect_node->HasRenderSurface());
transform->matrix().postScale(effect_node->surface_contents_scale.x(),
effect_node->surface_contents_scale.y(), 1.f);
}
@@ -458,7 +458,7 @@ static inline bool LayerShouldBeSkippedInternal(
const TransformTree& transform_tree,
const EffectTree& effect_tree) {
const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index());
- if (effect_node->has_render_surface && effect_node->subtree_has_copy_request)
+ if (effect_node->HasRenderSurface() && effect_node->subtree_has_copy_request)
return false;
// If the layer transform is not invertible, it should be skipped. In case the
@@ -509,7 +509,7 @@ static void SetSurfaceDrawOpacity(const EffectTree& tree,
// (included) and its target surface (excluded).
const EffectNode* node = tree.Node(render_surface->EffectTreeIndex());
float draw_opacity = tree.EffectiveOpacity(node);
- for (node = tree.parent(node); node && !node->has_render_surface;
+ for (node = tree.parent(node); node && !node->HasRenderSurface();
node = tree.parent(node)) {
draw_opacity *= tree.EffectiveOpacity(node);
}
@@ -656,7 +656,7 @@ static ConditionalClip LayerClipRect(PropertyTrees* property_trees,
const EffectTree* effect_tree = &property_trees->effect_tree;
const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index());
const EffectNode* target_node =
- effect_node->has_render_surface
+ effect_node->HasRenderSurface()
? effect_node
: effect_tree->Node(effect_node->target_id);
bool include_expanding_clips = false;
@@ -676,7 +676,7 @@ static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect(
// Return empty rrect if this node has a render surface but the function call
// was made for a non render surface.
- if (effect_node->has_render_surface && !for_render_surface)
+ if (effect_node->HasRenderSurface() && !for_render_surface)
return kEmptyRoundedCornerInfo;
// Traverse the parent chain up to the render target to find a node which has
@@ -691,7 +691,7 @@ static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect(
// Simply break if we reached a node that has a render surface or is the
// render target.
- if (node->has_render_surface || node->id == target_id)
+ if (node->HasRenderSurface() || node->id == target_id)
break;
node = effect_tree->parent(node);
@@ -723,7 +723,7 @@ static void UpdateRenderTarget(EffectTree* effect_tree) {
if (i == EffectTree::kContentsRootNodeId) {
// Render target of the node corresponding to root is itself.
node->target_id = EffectTree::kContentsRootNodeId;
- } else if (effect_tree->parent(node)->has_render_surface) {
+ } else if (effect_tree->parent(node)->HasRenderSurface()) {
node->target_id = node->parent_id;
} else {
node->target_id = effect_tree->parent(node)->target_id;
@@ -765,7 +765,7 @@ static void ComputeClips(PropertyTrees* property_trees) {
void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node,
gfx::Transform* transform) {
- DCHECK(effect_node->has_render_surface);
+ DCHECK(effect_node->HasRenderSurface());
if (effect_node->surface_contents_scale.x() != 0.0 &&
effect_node->surface_contents_scale.y() != 0.0)
transform->Scale(1.0 / effect_node->surface_contents_scale.x(),
diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc
index 3701e4c41f2..8c7a016eee4 100644
--- a/chromium/cc/trees/effect_node.cc
+++ b/chromium/cc/trees/effect_node.cc
@@ -17,7 +17,6 @@ EffectNode::EffectNode()
screen_space_opacity(1.f),
backdrop_filter_quality(1.f),
blend_mode(SkBlendMode::kSrcOver),
- has_render_surface(false),
cache_render_surface(false),
has_copy_request(false),
hidden_by_backface_visibility(false),
@@ -26,14 +25,17 @@ EffectNode::EffectNode()
is_drawn(true),
subtree_hidden(false),
has_potential_filter_animation(false),
+ has_potential_backdrop_filter_animation(false),
has_potential_opacity_animation(false),
is_currently_animating_filter(false),
+ is_currently_animating_backdrop_filter(false),
is_currently_animating_opacity(false),
has_masking_child(false),
is_masked(false),
effect_changed(false),
subtree_has_copy_request(false),
is_fast_rounded_corner(false),
+ render_surface_reason(RenderSurfaceReason::kNone),
transform_id(0),
clip_id(0),
target_id(1),
@@ -43,12 +45,13 @@ EffectNode::EffectNode()
EffectNode::EffectNode(const EffectNode& other) = default;
+EffectNode::~EffectNode() = default;
+
bool EffectNode::operator==(const EffectNode& other) const {
return id == other.id && parent_id == other.parent_id &&
stable_id == other.stable_id && opacity == other.opacity &&
screen_space_opacity == other.screen_space_opacity &&
backdrop_filter_quality == other.backdrop_filter_quality &&
- has_render_surface == other.has_render_surface &&
cache_render_surface == other.cache_render_surface &&
has_copy_request == other.has_copy_request &&
filters == other.filters &&
@@ -57,6 +60,9 @@ bool EffectNode::operator==(const EffectNode& other) const {
filters_origin == other.filters_origin &&
rounded_corner_bounds == other.rounded_corner_bounds &&
is_fast_rounded_corner == other.is_fast_rounded_corner &&
+ // The specific reason is just for tracing/testing/debugging, so just
+ // check whether a render surface is needed.
+ HasRenderSurface() == other.HasRenderSurface() &&
blend_mode == other.blend_mode &&
surface_contents_scale == other.surface_contents_scale &&
unscaled_mask_target_size == other.unscaled_mask_target_size &&
@@ -66,9 +72,13 @@ bool EffectNode::operator==(const EffectNode& other) const {
is_drawn == other.is_drawn && subtree_hidden == other.subtree_hidden &&
has_potential_filter_animation ==
other.has_potential_filter_animation &&
+ has_potential_backdrop_filter_animation ==
+ other.has_potential_backdrop_filter_animation &&
has_potential_opacity_animation ==
other.has_potential_opacity_animation &&
is_currently_animating_filter == other.is_currently_animating_filter &&
+ is_currently_animating_backdrop_filter ==
+ other.is_currently_animating_backdrop_filter &&
is_currently_animating_opacity ==
other.is_currently_animating_opacity &&
has_masking_child == other.has_masking_child &&
@@ -83,6 +93,54 @@ bool EffectNode::operator==(const EffectNode& other) const {
other.closest_ancestor_with_copy_request_id;
}
+const char* RenderSurfaceReasonToString(RenderSurfaceReason reason) {
+ switch (reason) {
+ case RenderSurfaceReason::kNone:
+ return "none";
+ case RenderSurfaceReason::kRoot:
+ return "root";
+ case RenderSurfaceReason::k3dTransformFlattening:
+ return "3d transform flattening";
+ case RenderSurfaceReason::kBlendMode:
+ return "blend mode";
+ case RenderSurfaceReason::kBlendModeDstIn:
+ return "blend mode kDstIn";
+ case RenderSurfaceReason::kOpacity:
+ return "opacity";
+ case RenderSurfaceReason::kOpacityAnimation:
+ return "opacity animation";
+ case RenderSurfaceReason::kFilter:
+ return "filter";
+ case RenderSurfaceReason::kFilterAnimation:
+ return "filter animation";
+ case RenderSurfaceReason::kBackdropFilter:
+ return "backdrop filter";
+ case RenderSurfaceReason::kBackdropFilterAnimation:
+ return "backdrop filter animation";
+ case RenderSurfaceReason::kRoundedCorner:
+ return "rounded corner";
+ case RenderSurfaceReason::kClipPath:
+ return "clip path";
+ case RenderSurfaceReason::kClipAxisAlignment:
+ return "clip axis alignment";
+ case RenderSurfaceReason::kMask:
+ return "mask";
+ case RenderSurfaceReason::kRootOrIsolatedGroup:
+ return "root or isolated group";
+ case RenderSurfaceReason::kTrilinearFiltering:
+ return "trilinear filtering";
+ case RenderSurfaceReason::kCache:
+ return "cache";
+ case RenderSurfaceReason::kCopyRequest:
+ return "copy request";
+ case RenderSurfaceReason::kTest:
+ return "test";
+ default:
+ NOTREACHED() << static_cast<int>(reason);
+ return "";
+ }
+}
+
void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const {
value->SetInteger("id", id);
value->SetInteger("parent_id", parent_id);
@@ -90,8 +148,11 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const {
value->SetDouble("opacity", opacity);
value->SetDouble("backdrop_filter_quality", backdrop_filter_quality);
value->SetBoolean("is_fast_rounded_corner", is_fast_rounded_corner);
+ if (!rounded_corner_bounds.IsEmpty()) {
+ MathUtil::AddToTracedValue("rounded_corner_bounds", rounded_corner_bounds,
+ value);
+ }
value->SetString("blend_mode", SkBlendMode_Name(blend_mode));
- value->SetBoolean("has_render_surface", has_render_surface);
value->SetBoolean("cache_render_surface", cache_render_surface);
value->SetBoolean("has_copy_request", has_copy_request);
value->SetBoolean("double_sided", double_sided);
@@ -99,12 +160,16 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const {
value->SetBoolean("is_drawn", is_drawn);
value->SetBoolean("has_potential_filter_animation",
has_potential_filter_animation);
+ value->SetBoolean("has_potential_backdrop_filter_animation",
+ has_potential_backdrop_filter_animation);
value->SetBoolean("has_potential_opacity_animation",
has_potential_opacity_animation);
value->SetBoolean("has_masking_child", has_masking_child);
value->SetBoolean("is_masked", is_masked);
value->SetBoolean("effect_changed", effect_changed);
- value->SetInteger("subtree_has_copy_request", subtree_has_copy_request);
+ value->SetBoolean("subtree_has_copy_request", subtree_has_copy_request);
+ value->SetString("render_surface_reason",
+ RenderSurfaceReasonToString(render_surface_reason));
value->SetInteger("transform_id", transform_id);
value->SetInteger("clip_id", clip_id);
value->SetInteger("target_id", target_id);
diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h
index f9ad97132ad..340305e9355 100644
--- a/chromium/cc/trees/effect_node.h
+++ b/chromium/cc/trees/effect_node.h
@@ -20,9 +20,37 @@ class TracedValue;
namespace cc {
+enum class RenderSurfaceReason : uint8_t {
+ kNone,
+ kRoot,
+ k3dTransformFlattening,
+ kBlendMode,
+ kBlendModeDstIn,
+ kOpacity,
+ kOpacityAnimation,
+ kFilter,
+ kFilterAnimation,
+ kBackdropFilter,
+ kBackdropFilterAnimation,
+ kRoundedCorner,
+ kClipPath,
+ kClipAxisAlignment,
+ kMask,
+ kRootOrIsolatedGroup,
+ kTrilinearFiltering,
+ kCache,
+ kCopyRequest,
+ // This must be the last value because it's used in tracing code to know the
+ // number of reasons.
+ kTest,
+};
+
+CC_EXPORT const char* RenderSurfaceReasonToString(RenderSurfaceReason);
+
struct CC_EXPORT EffectNode {
EffectNode();
EffectNode(const EffectNode& other);
+ ~EffectNode();
enum StableIdLabels { INVALID_STABLE_ID = 0 };
@@ -41,7 +69,7 @@ struct CC_EXPORT EffectNode {
FilterOperations filters;
FilterOperations backdrop_filters;
- gfx::RRectF backdrop_filter_bounds;
+ base::Optional<gfx::RRectF> backdrop_filter_bounds;
float backdrop_filter_quality;
gfx::PointF filters_origin;
@@ -55,7 +83,6 @@ struct CC_EXPORT EffectNode {
gfx::Size unscaled_mask_target_size;
- bool has_render_surface : 1;
bool cache_render_surface : 1;
bool has_copy_request : 1;
bool hidden_by_backface_visibility : 1;
@@ -69,10 +96,15 @@ struct CC_EXPORT EffectNode {
// of exact timeline) filter animation.
bool has_potential_filter_animation : 1;
// Whether this node has a potentially running (i.e., irrespective
+ // of exact timeline) backdrop-filter animation.
+ bool has_potential_backdrop_filter_animation : 1;
+ // Whether this node has a potentially running (i.e., irrespective
// of exact timeline) opacity animation.
bool has_potential_opacity_animation : 1;
// Whether this node has a currently running filter animation.
bool is_currently_animating_filter : 1;
+ // Whether this node has a currently running backdrop-filter animation.
+ bool is_currently_animating_backdrop_filter : 1;
// Whether this node has a currently running opacity animation.
bool is_currently_animating_opacity : 1;
// Whether this node has a child node with kDstIn blend mode.
@@ -85,7 +117,10 @@ struct CC_EXPORT EffectNode {
bool subtree_has_copy_request : 1;
// If set, the effect node tries to not trigger a render surface due to it
// having a rounded corner.
- bool is_fast_rounded_corner;
+ bool is_fast_rounded_corner : 1;
+ // RenderSurfaceReason::kNone if this effect node should not create a render
+ // surface, or the reason that this effect node should create one.
+ RenderSurfaceReason render_surface_reason;
// The transform node index of the transform to apply to this effect
// node's content when rendering to a surface.
int transform_id;
@@ -102,6 +137,10 @@ struct CC_EXPORT EffectNode {
int closest_ancestor_with_cached_render_surface_id;
int closest_ancestor_with_copy_request_id;
+ bool HasRenderSurface() const {
+ return render_surface_reason != RenderSurfaceReason::kNone;
+ }
+
bool operator==(const EffectNode& other) const;
void AsValueInto(base::trace_event::TracedValue* value) const;
diff --git a/chromium/cc/trees/latency_info_swap_promise.cc b/chromium/cc/trees/latency_info_swap_promise.cc
index 208582c6e3e..3d808aec191 100644
--- a/chromium/cc/trees/latency_info_swap_promise.cc
+++ b/chromium/cc/trees/latency_info_swap_promise.cc
@@ -23,11 +23,13 @@ void LatencyInfoSwapPromise::WillSwap(viz::CompositorFrameMetadata* metadata) {
void LatencyInfoSwapPromise::DidSwap() {}
-void LatencyInfoSwapPromise::DidNotSwap(DidNotSwapReason reason) {
+SwapPromise::DidNotSwapAction LatencyInfoSwapPromise::DidNotSwap(
+ DidNotSwapReason reason) {
latency_.Terminate();
// TODO(miletus): Turn this back on once per-event LatencyInfo tracking
// is enabled in GPU side.
// DCHECK(latency_.terminated);
+ return DidNotSwapAction::BREAK_PROMISE;
}
int64_t LatencyInfoSwapPromise::TraceId() const {
diff --git a/chromium/cc/trees/latency_info_swap_promise.h b/chromium/cc/trees/latency_info_swap_promise.h
index ecdd381fe14..5891dfeceba 100644
--- a/chromium/cc/trees/latency_info_swap_promise.h
+++ b/chromium/cc/trees/latency_info_swap_promise.h
@@ -27,7 +27,7 @@ class CC_EXPORT LatencyInfoSwapPromise : public SwapPromise {
void DidActivate() override {}
void WillSwap(viz::CompositorFrameMetadata* metadata) override;
void DidSwap() override;
- void DidNotSwap(DidNotSwapReason reason) override;
+ DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override;
void OnCommit() override;
int64_t TraceId() const override;
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index cf7a0bc85ef..4e9a9393289 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -371,6 +371,10 @@ void LayerTreeHost::FinishCommitOnImplThread(
DCHECK(host_impl->mutator_host());
mutator_host_->PushPropertiesTo(host_impl->mutator_host());
+ // Updating elements affects whether animations are in effect based on their
+ // properties so run after pushing updated animation properties.
+ host_impl->UpdateElements(ElementListType::PENDING);
+
sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kNotSyncing);
}
@@ -564,8 +568,8 @@ void LayerTreeHost::StartDeferringCommits(base::TimeDelta timeout) {
proxy_->StartDeferringCommits(timeout);
}
-void LayerTreeHost::StopDeferringCommits() {
- proxy_->StopDeferringCommits();
+void LayerTreeHost::StopDeferringCommits(PaintHoldingCommitTrigger trigger) {
+ proxy_->StopDeferringCommits(trigger);
}
DISABLE_CFI_PERF
@@ -719,11 +723,6 @@ void LayerTreeHost::DidPresentCompositorFrame(
client_->DidPresentCompositorFrame(frame_token, feedback);
}
-void LayerTreeHost::DidGenerateLocalSurfaceIdAllocation(
- const viz::LocalSurfaceIdAllocation& allocation) {
- client_->DidGenerateLocalSurfaceIdAllocation(allocation);
-}
-
void LayerTreeHost::DidCompletePageScaleAnimation() {
did_complete_scale_animation_ = true;
}
@@ -1395,31 +1394,16 @@ void LayerTreeHost::SetLocalSurfaceIdAllocationFromParent(
// parent agreed upon these without needing to further advance its sequence
// number. When this occurs the child is already up-to-date and a commit here
// is simply redundant.
- //
- // If |generated_child_surface_sequence_number_| is set, it means a child
- // sequence number was generated and needs to be compared against.
if (AreEmbedTokensEqual(current_local_surface_id_from_parent,
local_surface_id_from_parent) &&
AreParentSequencesEqual(current_local_surface_id_from_parent,
- local_surface_id_from_parent) &&
- (!generated_child_surface_sequence_number_ ||
- local_surface_id_from_parent.child_sequence_number() <
- *generated_child_surface_sequence_number_)) {
+ local_surface_id_from_parent)) {
return;
}
- generated_child_surface_sequence_number_.reset();
-
UpdateDeferMainFrameUpdateInternal();
SetNeedsCommit();
}
-uint32_t LayerTreeHost::GenerateChildSurfaceSequenceNumberSync() {
- DCHECK(proxy_);
- generated_child_surface_sequence_number_ =
- proxy_->GenerateChildSurfaceSequenceNumberSync();
- return *generated_child_surface_sequence_number_;
-}
-
void LayerTreeHost::RequestNewLocalSurfaceId() {
// If surface synchronization is enabled, then we can still request a new
// viz::LocalSurfaceId but that request will be deferred until we have a valid
@@ -1443,8 +1427,8 @@ void LayerTreeHost::RegisterLayer(Layer* layer) {
DCHECK(!in_paint_layer_contents_);
layer_id_map_[layer->id()] = layer;
if (!IsUsingLayerLists() && layer->element_id()) {
- mutator_host_->RegisterElement(layer->element_id(),
- ElementListType::ACTIVE);
+ mutator_host_->RegisterElementId(layer->element_id(),
+ ElementListType::ACTIVE);
}
}
@@ -1452,8 +1436,8 @@ void LayerTreeHost::UnregisterLayer(Layer* layer) {
DCHECK(LayerById(layer->id()));
DCHECK(!in_paint_layer_contents_);
if (!IsUsingLayerLists() && layer->element_id()) {
- mutator_host_->UnregisterElement(layer->element_id(),
- ElementListType::ACTIVE);
+ mutator_host_->UnregisterElementId(layer->element_id(),
+ ElementListType::ACTIVE);
}
layers_that_should_push_properties_.erase(layer);
layer_id_map_.erase(layer->id());
@@ -1683,7 +1667,7 @@ void LayerTreeHost::RegisterElement(ElementId element_id,
// Animation ElementIds are unregistered by |SetActiveRegisteredElementIds|
// when using layer lists.
if (!IsUsingLayerLists())
- mutator_host_->RegisterElement(element_id, list_type);
+ mutator_host_->RegisterElementId(element_id, list_type);
}
void LayerTreeHost::UnregisterElement(ElementId element_id,
@@ -1691,31 +1675,14 @@ void LayerTreeHost::UnregisterElement(ElementId element_id,
// Animation ElementIds are unregistered by |SetActiveRegisteredElementIds|
// when using layer lists.
if (!IsUsingLayerLists())
- mutator_host_->UnregisterElement(element_id, list_type);
+ mutator_host_->UnregisterElementId(element_id, list_type);
element_layers_map_.erase(element_id);
}
-void LayerTreeHost::SetActiveRegisteredElementIds(const ElementIdSet& ids) {
+void LayerTreeHost::UpdateActiveElements() {
DCHECK(IsUsingLayerLists());
-
- // Unregister ids that should no longer be registered.
- for (auto id_iter = elements_in_property_trees_.begin();
- id_iter != elements_in_property_trees_.end();) {
- const auto& id = *(id_iter++);
- if (!ids.count(id)) {
- mutator_host_->UnregisterElement(id, ElementListType::ACTIVE);
- elements_in_property_trees_.erase(id);
- }
- }
-
- // Register new ids that were not already registered.
- for (const auto& id : ids) {
- if (!elements_in_property_trees_.count(id)) {
- elements_in_property_trees_.insert(id);
- mutator_host_->RegisterElement(id, ElementListType::ACTIVE);
- }
- }
+ mutator_host_->UpdateRegisteredElementIds(ElementListType::ACTIVE);
}
static void SetElementIdForTesting(Layer* layer) {
@@ -1735,11 +1702,11 @@ void LayerTreeHost::BuildPropertyTreesForTesting() {
gfx::Rect(device_viewport_size()), identity_transform, property_trees());
}
-bool LayerTreeHost::IsElementInList(ElementId element_id,
- ElementListType list_type) const {
+bool LayerTreeHost::IsElementInPropertyTrees(ElementId element_id,
+ ElementListType list_type) const {
if (IsUsingLayerLists()) {
return list_type == ElementListType::ACTIVE &&
- elements_in_property_trees_.count(element_id);
+ property_trees()->HasElement(element_id);
}
return list_type == ElementListType::ACTIVE && LayerByElementId(element_id);
}
@@ -1767,6 +1734,23 @@ void LayerTreeHost::SetElementFilterMutated(ElementId element_id,
layer->OnFilterAnimated(filters);
}
+void LayerTreeHost::SetElementBackdropFilterMutated(
+ ElementId element_id,
+ ElementListType list_type,
+ const FilterOperations& backdrop_filters) {
+ if (IsUsingLayerLists()) {
+ // In BlinkGenPropertyTrees/CompositeAfterPaint we always have property
+ // tree nodes and can set the backdrop_filter directly on the effect node.
+ property_trees_.effect_tree.OnBackdropFilterAnimated(element_id,
+ backdrop_filters);
+ return;
+ }
+
+ Layer* layer = LayerByElementId(element_id);
+ DCHECK(layer);
+ layer->OnBackdropFilterAnimated(backdrop_filters);
+}
+
void LayerTreeHost::SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) {
@@ -1897,8 +1881,8 @@ void LayerTreeHost::RequestBeginMainFrameNotExpected(bool new_state) {
proxy_->RequestBeginMainFrameNotExpected(new_state);
}
-void LayerTreeHost::SetURLForUkm(const GURL& url) {
- proxy_->SetURLForUkm(url);
+void LayerTreeHost::SetSourceURL(ukm::SourceId source_id, const GURL& url) {
+ proxy_->SetSourceURL(source_id, url);
}
void LayerTreeHost::SetRenderFrameObserver(
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index 9d7d39f86b1..b7cf9d9af7d 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -21,7 +21,6 @@
#include "base/containers/flat_set.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
#include "cc/benchmarks/micro_benchmark.h"
@@ -248,7 +247,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void StartDeferringCommits(base::TimeDelta timeout);
// Stop deferring commits immediately.
- void StopDeferringCommits();
+ void StopDeferringCommits(PaintHoldingCommitTrigger);
// Returns whether there are any outstanding ScopedDeferMainFrameUpdate,
// though commits may be deferred also when the local_surface_id_from_parent()
@@ -451,11 +450,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
return local_surface_id_allocation_from_parent_;
}
- // Generates a new child surface sequence number (from a LocalSurfaceId). This
- // results in disabling drawing until the LocalSurfaceIdAllocation is received
- // via the active tree. This only works in single threaded mode.
- uint32_t GenerateChildSurfaceSequenceNumberSync();
-
// Requests the allocation of a new LocalSurfaceId on the compositor thread.
void RequestNewLocalSurfaceId();
@@ -548,9 +542,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void PushPropertyTreesTo(LayerTreeImpl* tree_impl);
void PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl);
- // TODO(flackr): This list should be on the property trees and pushed
- // as part of PushPropertyTreesTo.
- void PushRegisteredElementIdsTo(LayerTreeImpl* tree_impl);
void PushSurfaceRangesTo(LayerTreeImpl* tree_impl);
void PushLayerTreeHostPropertiesTo(LayerTreeHostImpl* host_impl);
@@ -564,15 +555,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
Layer* layer);
void UnregisterElement(ElementId element_id, ElementListType list_type);
- // Registers the new active element ids, updating |registered_element_ids_|,
- // and unregisters any element ids that were previously registered. This is
- // similar to |RegisterElement| and |UnregisterElement| but for layer lists
- // where we do not have a unique element id to layer mapping.
- using ElementIdSet = std::unordered_set<ElementId, ElementIdHash>;
- void SetActiveRegisteredElementIds(const ElementIdSet&);
- const ElementIdSet& elements_in_property_trees() {
- return elements_in_property_trees_;
- }
+ void UpdateActiveElements();
void SetElementIdsForTesting();
@@ -610,8 +593,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback);
- void DidGenerateLocalSurfaceIdAllocation(
- const viz::LocalSurfaceIdAllocation& allocation);
// Called when the compositor completed page scale animation.
void DidCompletePageScaleAnimation();
void ApplyScrollAndScale(ScrollAndScaleSet* info);
@@ -643,13 +624,17 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
bool IsUsingLayerLists() const;
// MutatorHostClient implementation.
- bool IsElementInList(ElementId element_id,
- ElementListType list_type) const override;
+ bool IsElementInPropertyTrees(ElementId element_id,
+ ElementListType list_type) const override;
void SetMutatorsNeedCommit() override;
void SetMutatorsNeedRebuildPropertyTrees() override;
void SetElementFilterMutated(ElementId element_id,
ElementListType list_type,
const FilterOperations& filters) override;
+ void SetElementBackdropFilterMutated(
+ ElementId element_id,
+ ElementListType list_type,
+ const FilterOperations& backdrop_filters) override;
void SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) override;
@@ -685,7 +670,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
float recording_scale_factor() const { return recording_scale_factor_; }
- void SetURLForUkm(const GURL& url);
+ void SetSourceURL(ukm::SourceId source_id, const GURL& url);
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer);
@@ -829,10 +814,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
bool new_local_surface_id_request_ = false;
uint32_t defer_main_frame_update_count_ = 0;
- // Last value returned from GenerateChildSurfaceSequenceNumberSync(). This is
- // reset once a LocalSurfaceId is submitted with a higher id.
- base::Optional<uint32_t> generated_child_surface_sequence_number_;
-
SkColor background_color_ = SK_ColorWHITE;
LayerSelection selection_;
@@ -874,10 +855,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// In layer-list mode, this map is only used for scrollable layers.
std::unordered_map<ElementId, Layer*, ElementIdHash> element_layers_map_;
- // The set of registered element ids when using layer list mode. In non-layer-
- // list mode, |element_layers_map_| is used.
- ElementIdSet elements_in_property_trees_;
-
bool in_paint_layer_contents_ = false;
// This is true if atleast one layer in the layer tree has a copy request. We
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index b54c5c1a35b..5ddc975a950 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -18,7 +18,6 @@ struct PresentationFeedback;
}
namespace viz {
-class LocalSurfaceIdAllocation;
struct BeginFrameArgs;
}
@@ -136,8 +135,6 @@ class LayerTreeHostClient {
// the time from the start of BeginMainFrame to the Commit, or early out.
virtual void RecordStartOfFrameMetrics() = 0;
virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) = 0;
- virtual void DidGenerateLocalSurfaceIdAllocation(
- const viz::LocalSurfaceIdAllocation& allocation) = 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 cd56fec1beb..6eb7ec07102 100644
--- a/chromium/cc/trees/layer_tree_host_common.cc
+++ b/chromium/cc/trees/layer_tree_host_common.cc
@@ -326,23 +326,17 @@ static bool SkipForInvertibility(const LayerImpl* layer,
bool non_root_copy_request =
effect_node->closest_ancestor_with_copy_request_id >
EffectTree::kContentsRootNodeId;
+ gfx::Transform from_target;
// If there is a copy request, we check the invertibility of the transform
// between the node corresponding to the layer and the node corresponding to
// the copy request. Otherwise, we are interested in the invertibility of
// screen space transform which is already cached on the transform node.
- if (non_root_copy_request) {
- // Null check is a temporary fix for crasher: https://crbug.com/939342
- if (effect_node == nullptr)
- return false;
- gfx::Transform from_target;
- return !property_trees->GetFromTarget(
- layer->transform_tree_index(),
- effect_node->closest_ancestor_with_copy_request_id, &from_target);
- }
- // Null check is a temporary fix for crasher: https://crbug.com/939342
- if (transform_node == nullptr)
- return false;
- return !transform_node->ancestors_are_invertible;
+ return non_root_copy_request
+ ? !property_trees->GetFromTarget(
+ layer->transform_tree_index(),
+ effect_node->closest_ancestor_with_copy_request_id,
+ &from_target)
+ : !transform_node->ancestors_are_invertible;
}
static void ComputeInitialRenderSurfaceList(
@@ -495,6 +489,38 @@ static void CalculateRenderSurfaceLayerList(
render_surface_list);
}
+static void RecordRenderSurfaceReasonsForTracing(
+ const PropertyTrees* property_trees,
+ const RenderSurfaceList* render_surface_list) {
+ static const auto* tracing_enabled =
+ TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("cc");
+ if (!*tracing_enabled ||
+ // Don't output single root render surface.
+ render_surface_list->size() <= 1)
+ return;
+
+ TRACE_EVENT_INSTANT1("cc", "RenderSurfaceReasonCount",
+ TRACE_EVENT_SCOPE_THREAD, "total",
+ render_surface_list->size());
+
+ // kTest is the last value which is not included for tracing.
+ constexpr auto kNumReasons = static_cast<size_t>(RenderSurfaceReason::kTest);
+ int reason_counts[kNumReasons] = {0};
+ for (const auto* render_surface : *render_surface_list) {
+ const auto* effect_node =
+ property_trees->effect_tree.Node(render_surface->EffectTreeIndex());
+ reason_counts[static_cast<size_t>(effect_node->render_surface_reason)]++;
+ }
+ for (size_t i = 0; i < kNumReasons; i++) {
+ if (!reason_counts[i])
+ continue;
+ TRACE_EVENT_INSTANT1(
+ "cc", "RenderSurfaceReasonCount", TRACE_EVENT_SCOPE_THREAD,
+ RenderSurfaceReasonToString(static_cast<RenderSurfaceReason>(i)),
+ reason_counts[i]);
+ }
+}
+
void CalculateDrawPropertiesInternal(
LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs,
PropertyTreeOption property_tree_option) {
@@ -610,6 +636,8 @@ void CalculateDrawPropertiesInternal(
inputs->root_layer->layer_tree_impl(), inputs->property_trees,
inputs->render_surface_list, inputs->max_texture_size);
}
+ RecordRenderSurfaceReasonsForTracing(inputs->property_trees,
+ inputs->render_surface_list);
// A root layer render_surface should always exist after
// CalculateDrawProperties.
diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc
index 37d6f1c7bb0..93750755adb 100644
--- a/chromium/cc/trees/layer_tree_host_common_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc
@@ -1329,7 +1329,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForNonAxisAlignedClipping) {
EffectTree& effect_tree =
root->layer_tree_impl()->property_trees()->effect_tree;
EffectNode* node = effect_tree.Node(clips_subtree->effect_tree_index());
- EXPECT_TRUE(node->has_render_surface);
+ EXPECT_TRUE(node->HasRenderSurface());
}
TEST_F(LayerTreeHostCommonTest, EffectNodesForNonAxisAlignedClips) {
@@ -3852,7 +3852,7 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) {
EXPECT_EQ(GetRenderSurface(front_facing_child), GetRenderSurface(root));
EXPECT_EQ(GetRenderSurface(back_facing_child), GetRenderSurface(root));
EXPECT_NE(GetRenderSurface(front_facing_surface), GetRenderSurface(root));
- // We expect that a has_render_surface was created but not used.
+ // We expect that a render surface was created but not used.
EXPECT_NE(GetRenderSurface(back_facing_surface), GetRenderSurface(root));
EXPECT_NE(GetRenderSurface(back_facing_surface),
GetRenderSurface(front_facing_surface));
@@ -10696,7 +10696,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) {
const EffectNode* effect_node =
effect_tree.Node(rounded_corner_layer_1->effect_tree_index());
gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
EXPECT_EQ(rounded_corner_bounds_1.rect(),
@@ -10706,7 +10706,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) {
// surface. It also has 2 descendants that draw.
effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index());
gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
EXPECT_EQ(rounded_corner_bounds_2.rect(),
@@ -10716,7 +10716,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) {
// the creation of a render surface.
effect_node = effect_tree.Node(rounded_corner_layer_3->effect_tree_index());
gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
kRoundedCorner3Radius);
EXPECT_EQ(rounded_corner_bounds_3.rect(),
@@ -10726,7 +10726,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) {
// rounded corner, it does not need a render surface.
effect_node = effect_tree.Node(rounded_corner_layer_4->effect_tree_index());
gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
kRoundedCorner4Radius);
EXPECT_EQ(rounded_corner_bounds_4.rect(),
@@ -10891,7 +10891,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsInterveningRenderTarget) {
const EffectNode* effect_node =
effect_tree.Node(rounded_corner_layer_1->effect_tree_index());
gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
EXPECT_EQ(rounded_corner_bounds_1.rect(),
@@ -10901,7 +10901,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsInterveningRenderTarget) {
// has a rounded corner, it does not need a render surface.
effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index());
gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
EXPECT_EQ(rounded_corner_bounds_2.rect(),
@@ -11018,7 +11018,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsSiblingRenderTarget) {
const EffectNode* effect_node =
effect_tree.Node(rounded_corner_layer_1->effect_tree_index());
gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
EXPECT_EQ(rounded_corner_bounds_1.rect(),
@@ -11028,7 +11028,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsSiblingRenderTarget) {
// has a rounded corner, it does not need a render surface.
effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index());
gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
EXPECT_EQ(rounded_corner_bounds_2.rect(),
@@ -11169,7 +11169,7 @@ TEST_F(LayerTreeHostCommonTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
const EffectNode* effect_node =
effect_tree.Node(fast_rounded_corner_layer->effect_tree_index());
gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_TRUE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
@@ -11179,7 +11179,7 @@ TEST_F(LayerTreeHostCommonTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
// Since this node has 2 descendants that draw, it will have a rounded corner.
effect_node = effect_tree.Node(rounded_corner_layer->effect_tree_index());
gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
@@ -11346,7 +11346,7 @@ TEST_F(LayerTreeHostCommonTest,
const EffectNode* effect_node =
effect_tree.Node(rounded_corner_layer_1->effect_tree_index());
gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
@@ -11358,7 +11358,7 @@ TEST_F(LayerTreeHostCommonTest,
effect_node =
effect_tree.Node(fast_rounded_corner_layer_2->effect_tree_index());
gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_TRUE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
@@ -11369,7 +11369,7 @@ TEST_F(LayerTreeHostCommonTest,
// render surface.
effect_node = effect_tree.Node(rounded_corner_layer_3->effect_tree_index());
gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
kRoundedCorner3Radius);
@@ -11379,7 +11379,7 @@ TEST_F(LayerTreeHostCommonTest,
// Since this layer no descendants, it would no thave a render pass.
effect_node = effect_tree.Node(rounded_corner_layer_4->effect_tree_index());
gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
kRoundedCorner4Radius);
@@ -11554,7 +11554,7 @@ TEST_F(LayerTreeHostCommonTest,
const EffectNode* effect_node =
effect_tree.Node(fast_rounded_corner_layer_1->effect_tree_index());
gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_TRUE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
@@ -11565,7 +11565,7 @@ TEST_F(LayerTreeHostCommonTest,
// not have a render surface.
effect_node = effect_tree.Node(rounded_corner_layer_1->effect_tree_index());
gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
@@ -11576,7 +11576,7 @@ TEST_F(LayerTreeHostCommonTest,
// render surface.
effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index());
gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
- EXPECT_TRUE(effect_node->has_render_surface);
+ EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
kRoundedCorner3Radius);
@@ -11586,7 +11586,7 @@ TEST_F(LayerTreeHostCommonTest,
// Since this layer has no descendant, it does not need a render surface.
effect_node = effect_tree.Node(rounded_corner_layer_3->effect_tree_index());
gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
- EXPECT_FALSE(effect_node->has_render_surface);
+ EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
kRoundedCorner4Radius);
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index cb2dbe413f0..e2921219d25 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -9,18 +9,18 @@
#include <algorithm>
#include <limits>
-#include <map>
-#include <set>
-#include <unordered_map>
-#include <utility>
+#include <list>
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/containers/adapters.h"
#include "base/containers/flat_map.h"
+#include "base/debug/crash_logging.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
+#include "base/memory/read_only_shared_memory_region.h"
#include "base/metrics/histogram.h"
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
@@ -79,6 +79,7 @@
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/mutator_host.h"
+#include "cc/trees/presentation_time_callback_buffer.h"
#include "cc/trees/render_frame_metadata.h"
#include "cc/trees/render_frame_metadata_observer.h"
#include "cc/trees/scroll_node.h"
@@ -260,6 +261,24 @@ ui::FrameMetricsSettings LTHI_FrameMetricsSettings(
return ui::FrameMetricsSettings(source, source_thread, compile_target);
}
+class ScopedPostAnimationEventsToMainThread {
+ public:
+ ScopedPostAnimationEventsToMainThread(MutatorHost* animation_host,
+ LayerTreeHostImplClient* client)
+ : events_(animation_host->CreateEvents()), client_(client) {}
+
+ ~ScopedPostAnimationEventsToMainThread() {
+ if (!events_->IsEmpty())
+ client_->PostAnimationEventsToMainThreadOnImplThread(std::move(events_));
+ }
+
+ MutatorEvents* events() { return events_.get(); }
+
+ private:
+ std::unique_ptr<MutatorEvents> events_;
+ LayerTreeHostImplClient* client_;
+};
+
} // namespace
DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeDurationHistogramTimer,
@@ -339,7 +358,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
is_animating_for_snap_(false),
paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()),
scrollbar_controller_(std::make_unique<ScrollbarController>(this)),
- scroll_gesture_did_end_(false) {
+ scroll_gesture_did_end_(false),
+ weak_factory_(this) {
DCHECK(mutator_host_);
mutator_host_->SetMutatorHostClient(this);
@@ -442,6 +462,10 @@ void LayerTreeHostImpl::CommitComplete() {
if (CommitToActiveTree()) {
active_tree_->HandleScrollbarShowRequestsFromMain();
+ // Property tree nodes have been updated by the commit. Update elements
+ // available on active tree to start/stop ticking animations.
+ UpdateElements(ElementListType::ACTIVE);
+
// We have to activate animations here or "IsActive()" is true on the layers
// but the animations aren't activated yet so they get ignored by
// UpdateDrawProperties.
@@ -464,7 +488,7 @@ void LayerTreeHostImpl::CommitComplete() {
void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
// LayerTreeHost may have changed the GPU rasterization flags state, which
// may require an update of the tree resources.
- UpdateTreeResourcesIfNeeded();
+ UpdateTreeResourcesForGpuRasterizationIfNeeded();
sync_tree()->set_needs_update_draw_properties();
// We need an update immediately post-commit to have the opportunity to create
@@ -546,9 +570,6 @@ bool LayerTreeHostImpl::CanDraw() const {
return false;
}
- if (waiting_for_local_surface_id_)
- return false;
-
if (resourceless_software_draw_)
return true;
@@ -635,6 +656,19 @@ void LayerTreeHostImpl::StartPageScaleAnimation(
bool anchor_point,
float page_scale,
base::TimeDelta duration) {
+ // Temporary crash logging for https://crbug.com/845097.
+ static bool has_dumped_without_crashing = false;
+ if (settings().is_layer_tree_for_subframe && !has_dumped_without_crashing) {
+ has_dumped_without_crashing = true;
+ static auto* psf_oopif_animation_error =
+ base::debug::AllocateCrashKeyString("psf_oopif_animation_error",
+ base::debug::CrashKeySize::Size32);
+ base::debug::SetCrashKeyString(
+ psf_oopif_animation_error,
+ base::StringPrintf("%p", InnerViewportScrollNode()));
+ base::debug::DumpWithoutCrashing();
+ }
+
if (!InnerViewportScrollNode())
return;
@@ -1261,6 +1295,10 @@ void LayerTreeHostImpl::SetViewportDamage(const gfx::Rect& damage_rect) {
viewport_damage_rect_.Union(damage_rect);
}
+void LayerTreeHostImpl::UpdateElements(ElementListType changed_list) {
+ mutator_host()->UpdateRegisteredElementIds(changed_list);
+}
+
void LayerTreeHostImpl::InvalidateContentOnImplSide() {
DCHECK(!pending_tree_);
// Invalidation should never be ran outside the impl frame for non
@@ -1389,7 +1427,7 @@ void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) {
// Remove orphan viz::RenderPassDrawQuads.
for (auto it = pass->quad_list.begin(); it != pass->quad_list.end();) {
- if (it->material != viz::DrawQuad::RENDER_PASS) {
+ if (it->material != viz::DrawQuad::Material::kRenderPass) {
++it;
continue;
}
@@ -1437,7 +1475,7 @@ void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) {
continue;
for (auto it = pass->quad_list.begin(); it != pass->quad_list.end(); ++it) {
- if (it->material != viz::DrawQuad::RENDER_PASS)
+ if (it->material != viz::DrawQuad::Material::kRenderPass)
continue;
const viz::RenderPassDrawQuad* quad =
viz::RenderPassDrawQuad::MaterialCast(*it);
@@ -1759,38 +1797,22 @@ void LayerTreeHostImpl::DidReceiveCompositorFrameAck() {
client_->DidReceiveCompositorFrameAckOnImplThread();
}
-LayerTreeHostImpl::FrameTokenInfo::FrameTokenInfo(
- uint32_t token,
- base::TimeTicks cc_frame_time,
- std::vector<LayerTreeHost::PresentationTimeCallback> callbacks)
- : token(token),
- cc_frame_time(cc_frame_time),
- callbacks(std::move(callbacks)) {}
-
-LayerTreeHostImpl::FrameTokenInfo::FrameTokenInfo(FrameTokenInfo&&) = default;
-LayerTreeHostImpl::FrameTokenInfo::~FrameTokenInfo() = default;
-
void LayerTreeHostImpl::DidPresentCompositorFrame(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) {
- std::vector<LayerTreeHost::PresentationTimeCallback> all_callbacks;
- while (!frame_token_infos_.empty()) {
- auto info = frame_token_infos_.begin();
- if (viz::FrameTokenGT(info->token, frame_token))
- break;
-
- // Update compositor frame latency and smoothness stats only for frames
- // that caused on-screen damage.
- if (info->token == frame_token)
- frame_metrics_.AddFrameDisplayed(info->cc_frame_time, feedback.timestamp);
+ PresentationTimeCallbackBuffer::PendingCallbacks activated =
+ presentation_time_callbacks_.PopPendingCallbacks(frame_token);
- std::copy(std::make_move_iterator(info->callbacks.begin()),
- std::make_move_iterator(info->callbacks.end()),
- std::back_inserter(all_callbacks));
- frame_token_infos_.erase(info);
+ // Update compositor frame latency and smoothness stats only for frames
+ // that caused on-screen damage.
+ if (!activated.frame_time.is_null()) {
+ frame_metrics_.AddFrameDisplayed(activated.frame_time, feedback.timestamp);
}
+
+ // Send all the main-thread callbacks to the client in one batch. The client
+ // is in charge of posting them to the main thread.
client_->DidPresentCompositorFrameOnImplThread(
- frame_token, std::move(all_callbacks), feedback);
+ frame_token, std::move(activated.main_thread_callbacks), feedback);
}
void LayerTreeHostImpl::DidNotNeedBeginFrame() {
@@ -1890,11 +1912,10 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
metadata.content_source_id = active_tree_->content_source_id();
if (active_tree_->has_presentation_callbacks()) {
- frame_token_infos_.emplace_back(metadata.frame_token,
- CurrentBeginFrameArgs().frame_time,
- active_tree_->TakePresentationCallbacks());
-
- DCHECK_LE(frame_token_infos_.size(), 25u);
+ presentation_time_callbacks_.RegisterMainThreadPresentationCallbacks(
+ metadata.frame_token, active_tree_->TakePresentationCallbacks());
+ presentation_time_callbacks_.RegisterFrameTime(
+ metadata.frame_token, CurrentBeginFrameArgs().frame_time);
}
if (GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
@@ -2386,16 +2407,8 @@ bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() {
return true;
}
-void LayerTreeHostImpl::UpdateTreeResourcesIfNeeded() {
- // For simplicity, clobber all resources when the color space changes.
- // This is mostly to clear the image decode caches, which don't handle
- // multiple color space at once.
- int color_space_id = -1;
- GetRasterColorSpaceAndId(&color_space_id);
- bool color_space_changed = last_color_space_id_ != color_space_id;
- last_color_space_id_ = color_space_id;
-
- if (!UpdateGpuRasterizationStatus() && !color_space_changed)
+void LayerTreeHostImpl::UpdateTreeResourcesForGpuRasterizationIfNeeded() {
+ if (!UpdateGpuRasterizationStatus())
return;
// Clean up and replace existing tile manager with another one that uses
@@ -2867,6 +2880,7 @@ void LayerTreeHostImpl::ActivateSyncTree() {
LayerTreeLifecycle::kSyncedPropertyTrees);
TreeSynchronizer::PushLayerProperties(pending_tree(), active_tree());
+
active_tree_->lifecycle().AdvanceTo(
LayerTreeLifecycle::kSyncedLayerProperties);
@@ -2874,6 +2888,10 @@ void LayerTreeHostImpl::ActivateSyncTree() {
if (!pending_tree_->LayerListIsEmpty())
pending_tree_->property_trees()->ResetAllChangeTracking();
+ // Property tree nodes have been updated by PushLayerProperties. Update
+ // elements available on active tree to start/stop ticking animations.
+ UpdateElements(ElementListType::ACTIVE);
+
active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kNotSyncing);
// Now that we've synced everything from the pending tree to the active
@@ -3098,15 +3116,13 @@ void LayerTreeHostImpl::CreateTileManagerResources() {
viz::ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true,
tile_format),
settings_.decoded_image_working_set_budget_bytes, max_texture_size_,
- paint_image_generator_client_id_,
- GetRasterColorSpace().ToSkColorSpace());
+ paint_image_generator_client_id_);
} else {
bool gpu_compositing = !!layer_tree_frame_sink_->context_provider();
image_decode_cache_ = std::make_unique<SoftwareImageDecodeCache>(
viz::ResourceFormatToClosestSkColorType(gpu_compositing, tile_format),
settings_.decoded_image_working_set_budget_bytes,
- paint_image_generator_client_id_,
- GetRasterColorSpace().ToSkColorSpace());
+ paint_image_generator_client_id_);
}
// Pass the single-threaded synchronous task graph runner to the worker pool
@@ -3211,8 +3227,9 @@ void LayerTreeHostImpl::QueueImageDecode(int request_id,
// Optimistically specify the current raster color space, since we assume that
// it won't change.
tile_manager_.decoded_image_tracker().QueueImageDecode(
- image, base::BindOnce(&LayerTreeHostImpl::ImageDecodeFinished,
- base::Unretained(this), request_id));
+ image, GetRasterColorSpace(),
+ base::BindOnce(&LayerTreeHostImpl::ImageDecodeFinished,
+ weak_factory_.GetWeakPtr(), request_id));
tile_manager_.checker_image_tracker().DisallowCheckeringForImage(image);
}
@@ -4599,17 +4616,27 @@ void LayerTreeHostImpl::RequestUpdateForSynchronousInputHandler() {
UpdateRootLayerStateForSynchronousInputHandler();
}
+static gfx::Vector2dF ContentToPhysical(const gfx::Vector2dF& content_delta,
+ float page_scale_factor) {
+ gfx::Vector2dF physical_delta = content_delta;
+ physical_delta.Scale(page_scale_factor);
+ return physical_delta;
+}
+
void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset(
- const gfx::ScrollOffset& root_offset) {
- TRACE_EVENT2("cc",
- "LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset",
- "offset_x", root_offset.x(), "offset_y", root_offset.y());
+ const gfx::ScrollOffset& root_content_offset) {
+ TRACE_EVENT2(
+ "cc", "LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset",
+ "offset_x", root_content_offset.x(), "offset_y", root_content_offset.y());
+
+ gfx::Vector2dF physical_delta = ContentToPhysical(
+ root_content_offset.DeltaFrom(viewport()->TotalScrollOffset()),
+ active_tree()->page_scale_factor_for_scroll());
- gfx::Vector2dF delta = root_offset.DeltaFrom(viewport()->TotalScrollOffset());
bool changed = !viewport()
- ->ScrollBy(delta,
+ ->ScrollBy(physical_delta,
/*viewport_point=*/gfx::Point(),
- /*is_wheel_scroll=*/false,
+ /*is_direct_manipulation=*/false,
/*affect_browser_controls=*/false,
/*scroll_outer_viewport=*/true)
.consumed_delta.IsZero();
@@ -4788,11 +4815,17 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseUp(
return result;
}
-void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) {
+InputHandlerPointerResult LayerTreeHostImpl::MouseMoveAt(
+ const gfx::Point& viewport_point) {
+ InputHandlerPointerResult result;
+ if (settings().compositor_threaded_scrollbar_scrolling)
+ result =
+ scrollbar_controller_->HandleMouseMove(gfx::PointF(viewport_point));
+
// Early out if there are no animation controllers and avoid the hit test.
// This happens on platforms without animated scrollbars.
if (scrollbar_animation_controllers_.empty())
- return;
+ return result;
gfx::PointF device_viewport_point = gfx::ScalePoint(
gfx::PointF(viewport_point), active_tree_->device_scale_factor());
@@ -4839,9 +4872,11 @@ void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) {
}
if (!new_animation_controller)
- return;
+ return result;
new_animation_controller->DidMouseMove(device_viewport_point);
+
+ return result;
}
void LayerTreeHostImpl::MouseLeave() {
@@ -5065,20 +5100,21 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
}
void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
- std::unique_ptr<MutatorEvents> events = mutator_host_->CreateEvents();
+ ScopedPostAnimationEventsToMainThread event_poster(mutator_host_.get(),
+ client_);
- const bool has_active_animations =
- mutator_host_->UpdateAnimationState(start_ready_animations, events.get());
-
- if (!events->IsEmpty())
- client_->PostAnimationEventsToMainThreadOnImplThread(std::move(events));
+ const bool has_active_animations = mutator_host_->UpdateAnimationState(
+ start_ready_animations, event_poster.events());
if (has_active_animations)
SetNeedsOneBeginImplFrame();
}
void LayerTreeHostImpl::ActivateAnimations() {
- const bool activated = mutator_host_->ActivateAnimations();
+ ScopedPostAnimationEventsToMainThread event_poster(mutator_host_.get(),
+ client_);
+ const bool activated =
+ mutator_host_->ActivateAnimations(event_poster.events());
if (activated) {
// Activating an animation changes layer draw properties, such as
// screen_space_transform_is_animating. So when we see a new animation get
@@ -5335,7 +5371,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
GLenum texture_target = GL_TEXTURE_2D;
// For software compositing, shared memory will be allocated and the
// UIResource will be copied into it.
- std::unique_ptr<base::SharedMemory> shared_memory;
+ base::MappedReadOnlyRegion mapped_region;
viz::SharedBitmapId shared_bitmap_id;
bool overlay_candidate = false;
@@ -5353,8 +5389,8 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
BufferFormat(format), caps);
}
} else {
- shared_memory =
- viz::bitmap_allocation::AllocateMappedBitmap(upload_size, format);
+ mapped_region =
+ viz::bitmap_allocation::AllocateSharedBitmap(upload_size, format);
shared_bitmap_id = viz::SharedBitmap::GenerateId();
}
@@ -5379,7 +5415,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(
- dst_info, shared_memory->memory(), dst_info.minRowBytes());
+ dst_info, mapped_region.mapping.memory(), dst_info.minRowBytes());
surface->getCanvas()->writePixels(
src_info, const_cast<uint8_t*>(bitmap.GetPixels()),
src_info.minRowBytes(), 0, 0);
@@ -5415,7 +5451,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
SkImageInfo dst_info =
SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
scaled_surface = SkSurface::MakeRasterDirect(
- dst_info, shared_memory->memory(), dst_info.minRowBytes());
+ dst_info, mapped_region.mapping.memory(), dst_info.minRowBytes());
}
SkCanvas* scaled_canvas = scaled_surface->getCanvas();
scaled_canvas->scale(canvas_scale_x, canvas_scale_y);
@@ -5453,16 +5489,14 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
->SharedImageInterface()
->GenUnverifiedSyncToken();
- transferable = viz::TransferableResource::MakeGLOverlay(
+ transferable = viz::TransferableResource::MakeGL(
mailbox, GL_LINEAR, texture_target, sync_token, upload_size,
overlay_candidate);
transferable.format = format;
} else {
- mojo::ScopedSharedBufferHandle memory_handle =
- viz::bitmap_allocation::DuplicateAndCloseMappedBitmap(
- shared_memory.get(), upload_size, format);
- layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(memory_handle),
- shared_bitmap_id);
+ layer_tree_frame_sink_->DidAllocateSharedBitmap(
+ viz::bitmap_allocation::ToMojoHandle(std::move(mapped_region.region)),
+ shared_bitmap_id);
transferable = viz::TransferableResource::MakeSoftware(shared_bitmap_id,
upload_size, format);
}
@@ -5480,7 +5514,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
data.opaque = bitmap.GetOpaque();
data.format = format;
data.shared_bitmap_id = shared_bitmap_id;
- data.shared_memory = std::move(shared_memory);
+ data.shared_mapping = std::move(mapped_region.mapping);
data.mailbox = mailbox;
data.resource_id_for_export = id;
ui_resource_map_[uid] = std::move(data);
@@ -5510,8 +5544,8 @@ void LayerTreeHostImpl::DeleteUIResourceBacking(
UIResourceData data,
const gpu::SyncToken& sync_token) {
// Resources are either software or gpu backed, not both.
- DCHECK(!(data.shared_memory && !data.mailbox.IsZero()));
- if (data.shared_memory)
+ DCHECK(!(data.shared_mapping.IsValid() && !data.mailbox.IsZero()));
+ if (data.shared_mapping.IsValid())
layer_tree_frame_sink_->DidDeleteSharedBitmap(data.shared_bitmap_id);
if (!data.mailbox.IsZero()) {
auto* sii =
@@ -5661,8 +5695,9 @@ bool LayerTreeHostImpl::ScrollAnimationUpdateTarget(
return animation_updated;
}
-bool LayerTreeHostImpl::IsElementInList(ElementId element_id,
- ElementListType list_type) const {
+bool LayerTreeHostImpl::IsElementInPropertyTrees(
+ ElementId element_id,
+ ElementListType list_type) const {
if (list_type == ElementListType::ACTIVE)
return active_tree() && active_tree()->IsElementInPropertyTree(element_id);
@@ -5710,6 +5745,20 @@ void LayerTreeHostImpl::SetElementFilterMutated(
}
}
+void LayerTreeHostImpl::SetElementBackdropFilterMutated(
+ ElementId element_id,
+ ElementListType list_type,
+ const FilterOperations& backdrop_filters) {
+ if (list_type == ElementListType::ACTIVE) {
+ active_tree()->SetBackdropFilterMutated(element_id, backdrop_filters);
+ } else {
+ if (pending_tree())
+ pending_tree()->SetBackdropFilterMutated(element_id, backdrop_filters);
+ if (recycle_tree())
+ recycle_tree()->SetBackdropFilterMutated(element_id, backdrop_filters);
+ }
+}
+
void LayerTreeHostImpl::SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) {
@@ -5892,7 +5941,7 @@ void LayerTreeHostImpl::InitializeUkm(
ukm_manager_ = std::make_unique<UkmManager>(std::move(recorder));
}
-void LayerTreeHostImpl::SetActiveURL(const GURL& url) {
+void LayerTreeHostImpl::SetActiveURL(const GURL& url, ukm::SourceId source_id) {
tile_manager_.set_active_url(url);
// The active tree might still be from content for the previous page when the
@@ -5901,48 +5950,14 @@ void LayerTreeHostImpl::SetActiveURL(const GURL& url) {
// case. Also, since checkerboard stats are only recorded with user
// interaction, it must be in progress when the navigation commits for this
// case to occur.
- if (ukm_manager_)
- ukm_manager_->SetSourceURL(url);
-}
-
-void LayerTreeHostImpl::OnLayerTreeLocalSurfaceIdAllocationChanged() {
- if (!waiting_for_local_surface_id_)
- return;
-
- const viz::LocalSurfaceId& current_id =
- child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
- .local_surface_id();
- const viz::LocalSurfaceId& new_id =
- active_tree()
- ->local_surface_id_allocation_from_parent()
- .local_surface_id();
- if ((current_id.embed_token() != new_id.embed_token()) ||
- (new_id.parent_sequence_number() > current_id.parent_sequence_number()) ||
- ((new_id.parent_sequence_number() ==
- current_id.parent_sequence_number()) &&
- (new_id.child_sequence_number() >=
- current_id.child_sequence_number()))) {
- waiting_for_local_surface_id_ = false;
- client_->OnCanDrawStateChanged(CanDraw());
+ if (ukm_manager_) {
+ // The source id has already been associated to the URL.
+ ukm_manager_->SetSourceId(source_id);
}
}
-uint32_t LayerTreeHostImpl::GenerateChildSurfaceSequenceNumberSync() {
- waiting_for_local_surface_id_ = true;
- child_local_surface_id_allocator_.GenerateIdOrIncrementChild();
- client_->OnCanDrawStateChanged(CanDraw());
- return child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
- .local_surface_id()
- .child_sequence_number();
-}
-
void LayerTreeHostImpl::AllocateLocalSurfaceId() {
- if (!settings_.automatically_allocate_surface_ids)
- return;
-
child_local_surface_id_allocator_.GenerateId();
- client_->DidGenerateLocalSurfaceIdAllocationOnImplThread(
- child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation());
}
void LayerTreeHostImpl::RequestBeginFrameForAnimatedImages() {
@@ -5958,4 +5973,8 @@ void LayerTreeHostImpl::RequestInvalidationForAnimatedImages() {
client_->NeedsImplSideInvalidation(needs_first_draw_on_activation);
}
+base::WeakPtr<LayerTreeHostImpl> LayerTreeHostImpl::AsWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index 18ccfb6763d..bb89bc998a4 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -7,17 +7,16 @@
#include <stddef.h>
-#include <bitset>
#include <memory>
#include <set>
-#include <string>
#include <unordered_map>
+#include <utility>
#include <vector>
#include "base/callback.h"
-#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h"
#include "base/memory/memory_pressure_listener.h"
+#include "base/memory/shared_memory_mapping.h"
#include "base/sequenced_task_runner.h"
#include "base/time/time.h"
#include "cc/base/synced_property.h"
@@ -42,6 +41,7 @@
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/managed_memory_policy.h"
#include "cc/trees/mutator_host_client.h"
+#include "cc/trees/presentation_time_callback_buffer.h"
#include "cc/trees/render_frame_metadata.h"
#include "cc/trees/task_runner_provider.h"
#include "cc/trees/ukm_manager.h"
@@ -156,9 +156,6 @@ class LayerTreeHostImplClient {
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) = 0;
- virtual void DidGenerateLocalSurfaceIdAllocationOnImplThread(
- const viz::LocalSurfaceIdAllocation& allocation) = 0;
-
virtual void NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType tree_type) = 0;
@@ -169,16 +166,14 @@ class LayerTreeHostImplClient {
// LayerTreeHostImpl owns the LayerImpl trees as well as associated rendering
// state.
-class CC_EXPORT LayerTreeHostImpl
- : public InputHandler,
- public TileManagerClient,
- public LayerTreeFrameSinkClient,
- public BrowserControlsOffsetManagerClient,
- public ScrollbarAnimationControllerClient,
- public VideoFrameControllerClient,
- public MutatorHostClient,
- public ImageAnimationController::Client,
- public base::SupportsWeakPtr<LayerTreeHostImpl> {
+class CC_EXPORT LayerTreeHostImpl : public InputHandler,
+ public TileManagerClient,
+ public LayerTreeFrameSinkClient,
+ public BrowserControlsOffsetManagerClient,
+ public ScrollbarAnimationControllerClient,
+ public VideoFrameControllerClient,
+ public MutatorHostClient,
+ public ImageAnimationController::Client {
public:
// This structure is used to build all the state required for producing a
// single CompositorFrame. The |render_passes| list becomes the set of
@@ -219,7 +214,7 @@ class CC_EXPORT LayerTreeHostImpl
// Backing for software compositing.
viz::SharedBitmapId shared_bitmap_id;
- std::unique_ptr<base::SharedMemory> shared_memory;
+ base::WritableSharedMemoryMapping shared_mapping;
// Backing for gpu compositing.
gpu::Mailbox mailbox;
@@ -259,13 +254,14 @@ class CC_EXPORT LayerTreeHostImpl
InputHandlerScrollResult ScrollBy(ScrollState* scroll_state) override;
void RequestUpdateForSynchronousInputHandler() override;
void SetSynchronousInputHandlerRootScrollOffset(
- const gfx::ScrollOffset& root_offset) override;
+ const gfx::ScrollOffset& root_content_offset) override;
void ScrollEnd(ScrollState* scroll_state, bool should_snap = false) override;
InputHandlerPointerResult MouseDown(
const gfx::PointF& viewport_point) override;
InputHandlerPointerResult MouseUp(const gfx::PointF& viewport_point) override;
- void MouseMoveAt(const gfx::Point& viewport_point) override;
+ InputHandlerPointerResult MouseMoveAt(
+ const gfx::Point& viewport_point) override;
void MouseLeave() override;
void PinchGestureBegin() override;
@@ -311,6 +307,8 @@ class CC_EXPORT LayerTreeHostImpl
void RequestBeginFrameForAnimatedImages() override;
void RequestInvalidationForAnimatedImages() override;
+ base::WeakPtr<LayerTreeHostImpl> AsWeakPtr();
+
void UpdateViewportContainerSizes();
void set_resourceless_software_draw_for_testing() {
@@ -338,6 +336,10 @@ class CC_EXPORT LayerTreeHostImpl
void SetFullViewportDamage();
void SetViewportDamage(const gfx::Rect& damage_rect);
+ // Updates registered ElementIds present in |changed_list|. Call this after
+ // changing the property trees for the |changed_list| trees.
+ void UpdateElements(ElementListType changed_list);
+
// Analogous to a commit, this function is used to create a sync tree and
// add impl-side invalidations to it.
// virtual for testing.
@@ -353,13 +355,17 @@ class CC_EXPORT LayerTreeHostImpl
}
// MutatorHostClient implementation.
- bool IsElementInList(ElementId element_id,
- ElementListType list_type) const override;
+ bool IsElementInPropertyTrees(ElementId element_id,
+ ElementListType list_type) const override;
void SetMutatorsNeedCommit() override;
void SetMutatorsNeedRebuildPropertyTrees() override;
void SetElementFilterMutated(ElementId element_id,
ElementListType list_type,
const FilterOperations& filters) override;
+ void SetElementBackdropFilterMutated(
+ ElementId element_id,
+ ElementListType list_type,
+ const FilterOperations& backdrop_filters) override;
void SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) override;
@@ -746,13 +752,7 @@ class CC_EXPORT LayerTreeHostImpl
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer);
- void SetActiveURL(const GURL& url);
-
- // Called when LayerTreeImpl's LocalSurfaceIdAllocation changes.
- void OnLayerTreeLocalSurfaceIdAllocationChanged();
-
- // See SyncSurfaceIdAllocator for details.
- uint32_t GenerateChildSurfaceSequenceNumberSync();
+ void SetActiveURL(const GURL& url, ukm::SourceId source_id);
CompositorFrameReportingController* compositor_frame_reporting_controller()
const {
@@ -826,7 +826,7 @@ class CC_EXPORT LayerTreeHostImpl
// Returns true if status changed.
bool UpdateGpuRasterizationStatus();
- void UpdateTreeResourcesIfNeeded();
+ void UpdateTreeResourcesForGpuRasterizationIfNeeded();
Viewport* viewport() const { return viewport_.get(); }
@@ -1160,39 +1160,11 @@ class CC_EXPORT LayerTreeHostImpl
base::Optional<RenderFrameMetadata> last_draw_render_frame_metadata_;
viz::ChildLocalSurfaceIdAllocator child_local_surface_id_allocator_;
- // Set to true if waiting to receive a LocalSurfaceIdAllocation that matches
- // that of |child_local_surface_id_allocator_|.
- bool waiting_for_local_surface_id_ = false;
-
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
- // Stores information needed once we get a response for a particular
- // presentation token.
- struct FrameTokenInfo {
- FrameTokenInfo(
- uint32_t token,
- base::TimeTicks cc_frame_time,
- std::vector<LayerTreeHost::PresentationTimeCallback> callbacks);
- FrameTokenInfo(const FrameTokenInfo&) = delete;
- FrameTokenInfo(FrameTokenInfo&&);
- ~FrameTokenInfo();
-
- FrameTokenInfo& operator=(const FrameTokenInfo&) = delete;
- FrameTokenInfo& operator=(FrameTokenInfo&&) = default;
-
- uint32_t token;
-
- // The compositor frame time used to produce the frame.
- base::TimeTicks cc_frame_time;
-
- // The callbacks to send back to the main thread.
- std::vector<LayerTreeHost::PresentationTimeCallback> callbacks;
- };
-
- base::circular_deque<FrameTokenInfo> frame_token_infos_;
+ PresentationTimeCallbackBuffer presentation_time_callbacks_;
ui::FrameMetrics frame_metrics_;
ui::SkippedFrameTracker skipped_frame_tracker_;
- int last_color_space_id_ = -1;
bool is_animating_for_snap_;
const PaintImage::GeneratorClientId paint_image_generator_client_id_;
@@ -1214,6 +1186,10 @@ class CC_EXPORT LayerTreeHostImpl
// animation completion. ScrollEnd will get called with this deferred state
// once the animation is over.
base::Optional<ScrollState> deferred_scroll_end_state_;
+
+ // Must be the last member to ensure this is destroyed first in the
+ // destruction order and invalidates all weak pointers.
+ base::WeakPtrFactory<LayerTreeHostImpl> weak_factory_;
};
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index 13a8b429571..80d1f14a001 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -76,11 +76,11 @@
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
-#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/service/display/gl_renderer.h"
#include "components/viz/service/display/skia_output_surface.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
+#include "components/viz/test/fake_skia_output_surface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "media/base/media.h"
@@ -196,14 +196,11 @@ class LayerTreeHostImplTest : public testing::Test,
requested_animation_delay_ = delay;
}
void DidActivateSyncTree() override {
- if (set_local_surface_id_on_activate_) {
- // Make sure the active tree always has a valid LocalSurfaceId.
- host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
- viz::LocalSurfaceIdAllocation(
- viz::LocalSurfaceId(1,
- base::UnguessableToken::Deserialize(2u, 3u)),
- base::TimeTicks::Now()));
- }
+ // Make sure the active tree always has a valid LocalSurfaceId.
+ host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
+ viz::LocalSurfaceIdAllocation(
+ viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)),
+ base::TimeTicks::Now()));
}
void WillPrepareTiles() override {}
void DidPrepareTiles() override {}
@@ -230,11 +227,6 @@ class LayerTreeHostImplTest : public testing::Test,
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) override {}
- void DidGenerateLocalSurfaceIdAllocationOnImplThread(
- const viz::LocalSurfaceIdAllocation& allocation) override {
- last_generated_local_surface_id_ = allocation;
- did_generate_local_surface_id_ = true;
- }
void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,
ElementListType tree_type) override {}
@@ -471,13 +463,14 @@ class LayerTreeHostImplTest : public testing::Test,
scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
scroll->SetDrawsContent(true);
- std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
- SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10,
- 0, false, true);
+ std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar =
+ PaintedScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, false,
+ true);
scrollbar->SetBounds(scrollbar_size);
scrollbar->test_properties()->position = gfx::PointF(345, 0);
scrollbar->SetScrollElementId(scroll->element_id());
scrollbar->SetDrawsContent(true);
+ scrollbar->SetHitTestable(true);
scrollbar->test_properties()->opacity = 1.f;
std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5);
@@ -812,9 +805,6 @@ class LayerTreeHostImplTest : public testing::Test,
viz::RenderPassList last_on_draw_render_passes_;
scoped_refptr<AnimationTimeline> timeline_;
std::unique_ptr<base::Thread> image_worker_;
- viz::LocalSurfaceIdAllocation last_generated_local_surface_id_;
- bool did_generate_local_surface_id_ = false;
- bool set_local_surface_id_on_activate_ = true;
};
class CommitToPendingTreeLayerTreeHostImplTest : public LayerTreeHostImplTest {
@@ -944,52 +934,6 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
EXPECT_TRUE(host_impl_->CanDraw());
EXPECT_TRUE(on_can_draw_state_changed_called_);
on_can_draw_state_changed_called_ = false;
-
- viz::ParentLocalSurfaceIdAllocator parent_allocator;
- parent_allocator.GenerateId();
- const uint32_t child_sequence_number1 =
- host_impl_->GenerateChildSurfaceSequenceNumberSync();
- EXPECT_NE(child_sequence_number1, viz::kInitialChildSequenceNumber);
- EXPECT_FALSE(host_impl_->CanDraw());
- EXPECT_TRUE(on_can_draw_state_changed_called_);
- on_can_draw_state_changed_called_ = false;
-
- host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
- parent_allocator.GetCurrentLocalSurfaceIdAllocation());
- EXPECT_TRUE(host_impl_->CanDraw());
- EXPECT_TRUE(on_can_draw_state_changed_called_);
- on_can_draw_state_changed_called_ = false;
-
- // Without this SetLocalSurfaceIdAllocationFromParent() is called from
- // DidActivateSyncTree().
- set_local_surface_id_on_activate_ = false;
- // Necessary to set LocalSurfaceIdAllocation in
- // |LayerTreeHostImpl::child_local_surface_id_allocator_|.
- host_impl_->ActivateSyncTree();
-
- const uint32_t child_sequence_number2 =
- host_impl_->GenerateChildSurfaceSequenceNumberSync();
- EXPECT_NE(child_sequence_number2, child_sequence_number1);
- EXPECT_FALSE(host_impl_->CanDraw());
- EXPECT_TRUE(on_can_draw_state_changed_called_);
- on_can_draw_state_changed_called_ = false;
-
- host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
- parent_allocator.GetCurrentLocalSurfaceIdAllocation());
- EXPECT_FALSE(host_impl_->CanDraw());
- EXPECT_FALSE(on_can_draw_state_changed_called_);
-
- auto id_from_parent =
- parent_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
- viz::LocalSurfaceIdAllocation(
- viz::LocalSurfaceId(id_from_parent.parent_sequence_number(),
- child_sequence_number2,
- id_from_parent.embed_token()),
- base::TimeTicks::Now()));
- EXPECT_TRUE(host_impl_->CanDraw());
- EXPECT_TRUE(on_can_draw_state_changed_called_);
- on_can_draw_state_changed_called_ = false;
}
TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) {
@@ -1373,9 +1317,9 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) {
scroll->SetDrawsContent(true);
scroll->SetHitTestable(true);
- std::unique_ptr<SolidColorScrollbarLayerImpl> drawn_scrollbar =
- SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, 0,
- false, true);
+ std::unique_ptr<PaintedScrollbarLayerImpl> drawn_scrollbar =
+ PaintedScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, false,
+ true);
drawn_scrollbar->SetBounds(scrollbar_size);
drawn_scrollbar->test_properties()->position = gfx::PointF(345, 0);
drawn_scrollbar->SetScrollElementId(scroll->element_id());
@@ -2287,8 +2231,22 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) {
// Destroy layer, unregister animation target (element).
child->test_properties()->parent = nullptr;
root->test_properties()->RemoveChild(child);
+
+ // Calling LayerImplTestProperties::RemoveChild above does not actually
+ // remove the property tree nodes for the removed layer. In the real code,
+ // you cannot remove a child on LayerImpl, but a child removed on Layer
+ // will force a full tree sync which will rebuild property trees without that
+ // child's property tree nodes. Call BuildPropertyTrees to simulate the
+ // rebuild that would happen during the commit.
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
child = nullptr;
+ // On updating state, we will send an animation event and request one last
+ // frame.
+ host_impl_->UpdateAnimationState(true);
+ EXPECT_TRUE(did_request_next_frame_);
+ did_request_next_frame_ = false;
+
// Doing Animate() doesn't request another frame after the current one.
host_impl_->Animate();
EXPECT_FALSE(did_request_next_frame_);
@@ -2410,8 +2368,8 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollbarGeometry) {
// size.
const gfx::Size outer_viewport_size = content_size;
- SolidColorScrollbarLayerImpl* v_scrollbar;
- SolidColorScrollbarLayerImpl* h_scrollbar;
+ PaintedScrollbarLayerImpl* v_scrollbar;
+ PaintedScrollbarLayerImpl* h_scrollbar;
// Setup
{
@@ -2434,12 +2392,12 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollbarGeometry) {
// Add scrollbars. They will always exist - even if unscrollable - but their
// visibility will be determined by whether the content can be scrolled.
{
- std::unique_ptr<SolidColorScrollbarLayerImpl> v_scrollbar_unique =
- SolidColorScrollbarLayerImpl::Create(active_tree, 400, VERTICAL, 10,
- 0, false, true);
- std::unique_ptr<SolidColorScrollbarLayerImpl> h_scrollbar_unique =
- SolidColorScrollbarLayerImpl::Create(active_tree, 401, HORIZONTAL, 10,
- 0, false, true);
+ std::unique_ptr<PaintedScrollbarLayerImpl> v_scrollbar_unique =
+ PaintedScrollbarLayerImpl::Create(active_tree, 400, VERTICAL, false,
+ true);
+ std::unique_ptr<PaintedScrollbarLayerImpl> h_scrollbar_unique =
+ PaintedScrollbarLayerImpl::Create(active_tree, 401, HORIZONTAL, false,
+ true);
v_scrollbar = v_scrollbar_unique.get();
h_scrollbar = h_scrollbar_unique.get();
@@ -4031,7 +3989,6 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest {
scrollbar_1_ = scrollbar_1.get();
scrollbar_1->SetScrollElementId(root_scroll->element_id());
scrollbar_1->SetDrawsContent(true);
- scrollbar_1->SetHitTestable(true);
scrollbar_1->SetBounds(scrollbar_size_1);
TouchActionRegion touch_action_region;
touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1));
@@ -4062,7 +4019,6 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest {
scrollbar_2->SetScrollElementId(child_element_id);
scrollbar_2->SetDrawsContent(true);
- scrollbar_2->SetHitTestable(true);
scrollbar_2->SetBounds(scrollbar_size_2);
scrollbar_2->SetCurrentPos(0);
scrollbar_2->test_properties()->position = gfx::PointF(0, 0);
@@ -4155,13 +4111,79 @@ TEST_F(LayerTreeHostImplTestMultiScrollable, ScrollbarFlashWhenMouseEnter) {
EXPECT_FALSE(animation_task_.is_null());
}
-TEST_F(LayerTreeHostImplTestMultiScrollable, ScrollHitTestOnScrollbar) {
+TEST_F(LayerTreeHostImplTest, ScrollHitTestOnScrollbar) {
LayerTreeSettings settings = DefaultSettings();
settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(500);
settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300);
settings.scrollbar_animator = LayerTreeSettings::NO_ANIMATOR;
- SetUpLayers(settings);
+ gfx::Size viewport_size(300, 200);
+ gfx::Size content_size(1000, 1000);
+ gfx::Size child_layer_size(250, 150);
+ gfx::Size scrollbar_size_1(gfx::Size(15, viewport_size.height()));
+ gfx::Size scrollbar_size_2(gfx::Size(15, child_layer_size.height()));
+
+ const int scrollbar_1_id = 10;
+ const int scrollbar_2_id = 11;
+ const int child_scroll_id = 13;
+
+ CreateHostImpl(settings, CreateLayerTreeFrameSink());
+ host_impl_->active_tree()->SetDeviceScaleFactor(1);
+ host_impl_->active_tree()->SetDeviceViewportSize(viewport_size);
+ CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
+ host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
+ viewport_size);
+ LayerImpl* root_scroll =
+ host_impl_->active_tree()->OuterViewportScrollLayer();
+
+ // scrollbar_1 on root scroll.
+ std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar_1 =
+ PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(),
+ scrollbar_1_id, VERTICAL, true, true);
+ scrollbar_1->SetScrollElementId(root_scroll->element_id());
+ scrollbar_1->SetDrawsContent(true);
+ scrollbar_1->SetHitTestable(true);
+ scrollbar_1->SetBounds(scrollbar_size_1);
+ TouchActionRegion touch_action_region;
+ touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1));
+ scrollbar_1->SetTouchActionRegion(touch_action_region);
+ scrollbar_1->SetCurrentPos(0);
+ scrollbar_1->test_properties()->position = gfx::PointF(0, 0);
+ scrollbar_1->test_properties()->opacity = 0.f;
+ host_impl_->active_tree()
+ ->InnerViewportContainerLayer()
+ ->test_properties()
+ ->AddChild(std::move(scrollbar_1));
+
+ // scrollbar_2 on child.
+ std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar_2 =
+ PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(),
+ scrollbar_2_id, VERTICAL, true, true);
+ std::unique_ptr<LayerImpl> child =
+ LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
+ child->test_properties()->position = gfx::PointF(50, 50);
+ child->SetBounds(child_layer_size);
+ child->SetDrawsContent(true);
+ child->SetHitTestable(true);
+ child->SetScrollable(gfx::Size(100, 100));
+ child->SetHitTestable(true);
+ child->SetElementId(LayerIdToElementIdForTesting(child->id()));
+ ElementId child_element_id = child->element_id();
+
+ scrollbar_2->SetScrollElementId(child_element_id);
+ scrollbar_2->SetDrawsContent(true);
+ scrollbar_2->SetHitTestable(true);
+ scrollbar_2->SetBounds(scrollbar_size_2);
+ scrollbar_2->SetCurrentPos(0);
+ scrollbar_2->test_properties()->position = gfx::PointF(0, 0);
+ scrollbar_2->test_properties()->opacity = 0.f;
+
+ child->test_properties()->AddChild(std::move(scrollbar_2));
+ root_scroll->test_properties()->AddChild(std::move(child));
+
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+ host_impl_->active_tree()->UpdateScrollbarGeometries();
+ host_impl_->active_tree()->DidBecomeActive();
// Wheel scroll on root scrollbar should process on impl thread.
{
@@ -4294,9 +4316,9 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) {
outer_viewport_size);
LayerImpl* root_scroll =
host_impl_->active_tree()->OuterViewportScrollLayer();
- std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_scrollbar =
- SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), horiz_id,
- HORIZONTAL, 5, 5, true, true);
+ std::unique_ptr<PaintedScrollbarLayerImpl> horiz_scrollbar =
+ PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), horiz_id,
+ HORIZONTAL, true, true);
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
child->SetBounds(content_size);
@@ -7891,6 +7913,9 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
host_impl_->active_tree()->BuildPropertyTreesForTesting();
DrawFrame();
+ // Ensure that the scroll offset is interpreted as a content offset so it
+ // should be unaffected by the page scale factor. See
+ // https://crbug.com/973771.
float page_scale_factor = 2.f;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, page_scale_factor, page_scale_factor);
@@ -7906,7 +7931,6 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
scroll_tree.current_scroll_offset(inner_element_id));
- scroll_offset.Scale(1.f / page_scale_factor);
EXPECT_VECTOR_EQ(scroll_offset,
scroll_tree.current_scroll_offset(outer_element_id));
EXPECT_TRUE(did_request_redraw_);
@@ -8962,7 +8986,7 @@ class BlendStateCheckLayer : public LayerImpl {
test_blending_draw_quad->SetNew(
shared_quad_state, quad_rect_, visible_quad_rect, needs_blending,
resource_id_, gfx::RectF(0.f, 0.f, 1.f, 1.f), gfx::Size(1, 1), false,
- false, false, false);
+ false, false);
EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
EXPECT_EQ(has_render_surface_,
@@ -9304,7 +9328,7 @@ TEST_F(LayerTreeHostImplTest, MayContainVideo) {
class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
protected:
LayerTreeHostImplViewportCoveredTest()
- : gutter_quad_material_(viz::DrawQuad::SOLID_COLOR),
+ : gutter_quad_material_(viz::DrawQuad::Material::kSolidColor),
child_(nullptr),
did_activate_pending_tree_(false) {}
@@ -9498,7 +9522,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
// Make sure that the texture coordinates match their expectations.
void ValidateTextureDrawQuads(const viz::QuadList& quad_list) {
for (auto* quad : quad_list) {
- if (quad->material != viz::DrawQuad::TEXTURE_CONTENT)
+ if (quad->material != viz::DrawQuad::Material::kTextureContent)
continue;
const viz::TextureDrawQuad* texture_quad =
viz::TextureDrawQuad::MaterialCast(quad);
@@ -9814,7 +9838,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
{
const auto& root_pass = frame.render_passes.back();
ASSERT_EQ(1u, root_pass->quad_list.size());
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
root_pass->quad_list.front()->material);
}
host_impl_->DrawLayers(&frame);
@@ -10233,11 +10257,6 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) {
// RequiresHighResToDraw is set when new output surface is used.
EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
- // The first commit will also set RequiresHighResToDraw due to the
- // raster color space changing.
- host_impl_->ResetRequiresHighResToDraw();
- host_impl_->CommitComplete();
- EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
host_impl_->ResetRequiresHighResToDraw();
host_impl_->SetContentHasSlowPaths(false);
@@ -10399,8 +10418,8 @@ class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface()
override {
- NOTIMPLEMENTED();
- return nullptr;
+ return viz::FakeSkiaOutputSurface::Create3d(
+ std::move(display_context_provider_));
}
std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
@@ -10422,7 +10441,20 @@ class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
scoped_refptr<viz::ContextProvider> display_context_provider_;
};
-TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
+enum RendererType { RENDERER_GL, RENDERER_SKIA };
+
+class LayerTreeHostImplTestWithRenderer
+ : public LayerTreeHostImplTest,
+ public ::testing::WithParamInterface<RendererType> {
+ protected:
+ RendererType renderer_type() const { return GetParam(); }
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostImplTestWithRenderer,
+ ::testing::Values(RENDERER_GL, RENDERER_SKIA));
+
+TEST_P(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) {
scoped_refptr<viz::TestContextProvider> context_provider =
viz::TestContextProvider::Create();
FrameSinkClient test_client(context_provider);
@@ -10430,9 +10462,11 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
constexpr bool synchronous_composite = true;
constexpr bool disable_display_vsync = false;
constexpr double refresh_rate = 60.0;
+ viz::RendererSettings renderer_settings = viz::RendererSettings();
+ renderer_settings.use_skia_renderer = renderer_type() == RENDERER_SKIA;
auto layer_tree_frame_sink = std::make_unique<viz::TestLayerTreeFrameSink>(
context_provider, viz::TestContextProvider::CreateWorker(), nullptr,
- viz::RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(),
+ renderer_settings, base::ThreadTaskRunnerHandle::Get().get(),
synchronous_composite, disable_display_vsync, refresh_rate);
layer_tree_frame_sink->SetClient(&test_client);
@@ -12962,15 +12996,15 @@ TEST_F(LayerTreeHostImplTest, RemoveUnreferencedRenderPass) {
// Add a quad to each pass so they aren't empty.
auto* color_quad = pass1->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- color_quad->material = viz::DrawQuad::SOLID_COLOR;
+ color_quad->material = viz::DrawQuad::Material::kSolidColor;
color_quad = pass2->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- color_quad->material = viz::DrawQuad::SOLID_COLOR;
+ color_quad->material = viz::DrawQuad::Material::kSolidColor;
color_quad = pass3->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- color_quad->material = viz::DrawQuad::SOLID_COLOR;
+ color_quad->material = viz::DrawQuad::Material::kSolidColor;
// pass3 is referenced by pass2.
auto* rpdq = pass2->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- rpdq->material = viz::DrawQuad::RENDER_PASS;
+ rpdq->material = viz::DrawQuad::Material::kRenderPass;
rpdq->render_pass_id = pass3->id;
// But pass2 is not referenced by pass1. So pass2 and pass3 should be culled.
@@ -12997,16 +13031,16 @@ TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) {
// pass1 is not empty, but pass2 and pass3 are.
auto* color_quad = pass1->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- color_quad->material = viz::DrawQuad::SOLID_COLOR;
+ color_quad->material = viz::DrawQuad::Material::kSolidColor;
// pass3 is referenced by pass2.
auto* rpdq = pass2->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- rpdq->material = viz::DrawQuad::RENDER_PASS;
+ rpdq->material = viz::DrawQuad::Material::kRenderPass;
rpdq->render_pass_id = pass3->id;
// pass2 is referenced by pass1.
rpdq = pass1->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- rpdq->material = viz::DrawQuad::RENDER_PASS;
+ rpdq->material = viz::DrawQuad::Material::kRenderPass;
rpdq->render_pass_id = pass2->id;
// Since pass3 is empty it should be removed. Then pass2 is empty too, and
@@ -13019,7 +13053,7 @@ TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) {
EXPECT_EQ(1u, frame.render_passes[0]->id);
// The viz::RenderPassDrawQuad should be removed from pass1.
EXPECT_EQ(1u, pass1->quad_list.size());
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
pass1->quad_list.ElementAt(0)->material);
}
@@ -13038,12 +13072,12 @@ TEST_F(LayerTreeHostImplTest, DoNotRemoveEmptyRootRenderPass) {
// pass3 is referenced by pass2.
auto* rpdq = pass2->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- rpdq->material = viz::DrawQuad::RENDER_PASS;
+ rpdq->material = viz::DrawQuad::Material::kRenderPass;
rpdq->render_pass_id = pass3->id;
// pass2 is referenced by pass1.
rpdq = pass1->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>();
- rpdq->material = viz::DrawQuad::RENDER_PASS;
+ rpdq->material = viz::DrawQuad::Material::kRenderPass;
rpdq->render_pass_id = pass2->id;
// Since pass3 is empty it should be removed. Then pass2 is empty too, and
@@ -14760,5 +14794,50 @@ TEST_F(LayerTreeHostImplTest, SkipOnDrawDoesNotUpdateDrawParams) {
EXPECT_EQ(viewport, host_impl_->active_tree()->GetDeviceViewport());
}
+// Test that a touch scroll over a SolidColorScrollbarLayer, the scrollbar used
+// on Android, does not register as a scrollbar scroll and result in main
+// threaded scrolling.
+TEST_F(LayerTreeHostImplTest, TouchScrollOnAndroidScrollbar) {
+ LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
+ gfx::Size viewport_size = gfx::Size(360, 600);
+ gfx::Size scroll_content_size = gfx::Size(360, 3800);
+ gfx::Size scrollbar_size = gfx::Size(15, 600);
+
+ host_impl_->active_tree()->SetDeviceViewportSize(viewport_size);
+ std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
+ root->SetBounds(viewport_size);
+ root->test_properties()->position = gfx::PointF();
+
+ std::unique_ptr<LayerImpl> content = LayerImpl::Create(layer_tree_impl, 2);
+ content->SetBounds(scroll_content_size);
+ content->SetScrollable(viewport_size);
+ content->SetHitTestable(true);
+ content->SetElementId(LayerIdToElementIdForTesting(content->id()));
+ content->SetDrawsContent(true);
+
+ std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
+ SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 3, VERTICAL, 10, 0,
+ false, true);
+ scrollbar->SetBounds(scrollbar_size);
+ scrollbar->test_properties()->position = gfx::PointF(345, 0);
+ scrollbar->SetScrollElementId(content->element_id());
+ scrollbar->SetDrawsContent(true);
+ scrollbar->test_properties()->opacity = 1.f;
+
+ root->test_properties()->AddChild(std::move(content));
+ root->test_properties()->AddChild(std::move(scrollbar));
+
+ layer_tree_impl->SetRootLayerForTesting(std::move(root));
+ layer_tree_impl->BuildPropertyTreesForTesting();
+ layer_tree_impl->DidBecomeActive();
+
+ // Do a scroll over the scrollbar layer as well as the content layer, which
+ // should result in scrolling the scroll layer on the impl thread as the
+ // scrollbar should not be hit.
+ InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(350, 50)).get(), InputHandler::TOUCHSCREEN);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index 35953305fc8..92fd3570952 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -330,8 +330,11 @@ class BrowserCompositorInvalidateLayerTreePerfTest
gpu::CommandBufferId::FromUnsafeValue(1),
next_fence_sync_);
next_sync_token.SetVerifyFlush();
+
+ constexpr gfx::Size size(64, 64);
viz::TransferableResource resource = viz::TransferableResource::MakeGL(
- gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, next_sync_token);
+ gpu_mailbox, GL_LINEAR, GL_TEXTURE_2D, next_sync_token, size,
+ false /* is_overlay_candidate */);
next_fence_sync_++;
tab_contents_->SetTransferableResource(resource, std::move(callback));
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
index 4819bbe2825..3f0c28b4311 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -213,10 +213,10 @@ class LayerTreeHostBlendingPixelTest
InitializeFromTestCase(resource_type());
// Force shaders only applies to gl renderer.
- if (test_type_ != PIXEL_TEST_GL && flags & kForceShaders)
+ if (renderer_type_ != RENDERER_GL && flags & kForceShaders)
return;
- SCOPED_TRACE(TestTypeToString(test_type_));
+ SCOPED_TRACE(TestTypeToString(renderer_type_));
SCOPED_TRACE(SkBlendMode_Name(current_blend_mode()));
scoped_refptr<SolidColorLayer> root = CreateSolidColorLayer(
@@ -232,7 +232,7 @@ class LayerTreeHostBlendingPixelTest
this->force_antialiasing_ = (flags & kUseAntialiasing);
this->force_blending_with_shaders_ = (flags & kForceShaders);
- if ((flags & kUseAntialiasing) && (test_type_ == PIXEL_TEST_GL)) {
+ if ((flags & kUseAntialiasing) && (renderer_type_ == RENDERER_GL)) {
// Blending results might differ with one pixel.
// Don't allow large errors here, only off by ones.
// However, large error still has to be specified to satisfy
@@ -262,8 +262,17 @@ class LayerTreeHostBlendingPixelTest
SkColor misc_opaque_color_ = 0xffc86464;
};
+INSTANTIATE_TEST_SUITE_P(
+ B,
+ LayerTreeHostBlendingPixelTest,
+ ::testing::Combine(::testing::Values(SOFTWARE, ZERO_COPY, SKIA_GL),
+ ::testing::ValuesIn(kBlendModes)));
+
+using LayerTreeHostBlendingPixelTestNonSkia = LayerTreeHostBlendingPixelTest;
+
+// TODO(crbug.com/948128): Enable these tests for Skia.
INSTANTIATE_TEST_SUITE_P(B,
- LayerTreeHostBlendingPixelTest,
+ LayerTreeHostBlendingPixelTestNonSkia,
::testing::Combine(::testing::Values(SOFTWARE,
ZERO_COPY),
::testing::ValuesIn(kBlendModes)));
@@ -295,7 +304,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRoot) {
RunPixelResourceTest(background, expected);
}
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackdropFilter) {
+TEST_P(LayerTreeHostBlendingPixelTestNonSkia, BlendingWithBackdropFilter) {
const int kRootWidth = 2;
const int kRootHeight = 2;
InitializeFromTestCase(resource_type());
@@ -311,9 +320,8 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackdropFilter) {
background->AddChild(green_lane);
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
- gfx::RRectF backdrop_filter_bounds;
green_lane->SetBackdropFilters(filters);
- green_lane->SetBackdropFilterBounds(backdrop_filter_bounds);
+ green_lane->ClearBackdropFilterBounds();
green_lane->SetBlendMode(current_blend_mode());
SkBitmap expected;
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index 32c04b5e286..165f1d8879c 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -19,7 +19,7 @@ namespace {
class LayerTreeHostFiltersPixelTest
: public LayerTreePixelTest,
- public ::testing::WithParamInterface<LayerTreePixelTest::PixelTestType> {
+ public ::testing::WithParamInterface<LayerTreeTest::RendererType> {
protected:
void InitializeSettings(LayerTreeSettings* settings) override {
LayerTreePixelTest::InitializeSettings(settings);
@@ -29,17 +29,17 @@ class LayerTreeHostFiltersPixelTest
layer_transforms_should_scale_layer_contents_;
}
- LayerTreePixelTest::PixelTestType GetPixelTestType() { return GetParam(); }
+ RendererType renderer_type() { return GetParam(); }
// Text string for graphics backend of the RendererType. Suitable for
// generating separate base line file paths.
const char* GetRendererSuffix() {
- switch (GetPixelTestType()) {
- case LayerTreePixelTest::PIXEL_TEST_GL:
+ switch (renderer_type()) {
+ case RENDERER_GL:
return "gl";
- case LayerTreePixelTest::PIXEL_TEST_SKIA_GL:
+ case RENDERER_SKIA_GL:
return "skia";
- case LayerTreePixelTest::PIXEL_TEST_SOFTWARE:
+ case RENDERER_SOFTWARE:
return "sw";
}
}
@@ -54,17 +54,17 @@ class LayerTreeHostFiltersPixelTest
// This matrix swaps the red and green channels, and has a slight
// translation in the alpha component, so that it affects transparent
// pixels.
- SkScalar matrix[20] = {
+ float matrix[20] = {
0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 20.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 20 / 255.0f,
};
FilterOperations filters;
SkImageFilter::CropRect cropRect(
SkRect::MakeXYWH(-40000, -40000, 80000, 80000));
filters.Append(FilterOperation::CreateReferenceFilter(
- sk_make_sp<ColorFilterPaintFilter>(
- SkColorFilters::MatrixRowMajor255(matrix), nullptr, &cropRect)));
+ sk_make_sp<ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix),
+ nullptr, &cropRect)));
filter_layer->SetFilters(filters);
background->SetMasksToBounds(masks_to_bounds);
background->AddChild(filter_layer);
@@ -75,20 +75,33 @@ class LayerTreeHostFiltersPixelTest
bool layer_transforms_should_scale_layer_contents_ = true;
};
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostFiltersPixelTest,
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+ LayerTreeTest::RENDERER_SOFTWARE));
+
+using LayerTreeHostFiltersPixelTestNonSkia = LayerTreeHostFiltersPixelTest;
+
// TODO(crbug.com/948128): Enable these tests for Skia.
-INSTANTIATE_TEST_SUITE_P(
- ,
- LayerTreeHostFiltersPixelTest,
- ::testing::Values(LayerTreePixelTest::PIXEL_TEST_GL,
- LayerTreePixelTest::PIXEL_TEST_SOFTWARE));
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostFiltersPixelTestNonSkia,
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SOFTWARE));
-class LayerTreeHostFiltersPixelTestGPU : public LayerTreeHostFiltersPixelTest {
-};
+using LayerTreeHostFiltersPixelTestGL = LayerTreeHostFiltersPixelTest;
// TODO(crbug.com/948128): Enable these tests for Skia.
INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostFiltersPixelTestGL,
+ ::testing::Values(LayerTreeTest::RENDERER_GL));
+
+using LayerTreeHostFiltersPixelTestGPU = LayerTreeHostFiltersPixelTest;
+
+INSTANTIATE_TEST_SUITE_P(,
LayerTreeHostFiltersPixelTestGPU,
- ::testing::Values(LayerTreePixelTest::PIXEL_TEST_GL));
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL));
TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurRect) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
@@ -126,7 +139,7 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurRect) {
small_error_allowed));
#endif
- RunPixelTest(GetPixelTestType(), background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur.png")));
}
@@ -163,22 +176,30 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurRounded) {
percentage_pixels_large_error, percentage_pixels_small_error,
average_error_allowed_in_bad_pixels, large_error_allowed,
small_error_allowed));
+#else
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false);
#endif
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_rounded.png")));
}
TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOutsets) {
+ if (renderer_type() == RENDERER_SKIA_GL
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ || renderer_type() == RENDERER_SKIA_VK
+#endif
+ ) {
+ // TODO(973696): Implement bounds clipping in skia_renderer.
+ return;
+ }
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
- // The green border is outside the layer with backdrop blur, but the
- // backdrop blur should use pixels from outside its layer borders, up to the
- // radius of the blur effect. So the border should be blurred underneath the
- // top layer causing the green to bleed under the transparent layer, but not
- // in the 1px region between the transparent layer and the green border.
+ // The green border is outside the layer with backdrop blur, so the backdrop
+ // blur should not include pixels from outside its layer borders. So the
+ // interior region of the transparent layer should be perfectly white.
scoped_refptr<SolidColorLayer> green_border = CreateSolidColorLayerWithBorder(
gfx::Rect(1, 1, 198, 198), SK_ColorWHITE, 10, kCSSGreen);
scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer(
@@ -215,11 +236,11 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOutsets) {
#endif
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_outsets.png")));
}
-TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) {
+TEST_P(LayerTreeHostFiltersPixelTestGL, BackdropFilterBlurOffAxis) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT);
@@ -258,8 +279,12 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) {
filters.Append(FilterOperation::CreateBlurFilter(
2.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackdropFilters(filters);
- // TODO(916311): Fix clipping for 3D transformed elements.
- blur->SetBackdropFilterBounds(gfx::RRectF());
+ // TODO(916311): We should be able to set the bounds like this, but the
+ // resulting output is clipped incorrectly.
+ // gfx::RRectF
+ // backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())),0);
+ // blur->SetBackdropFilterBounds(backdrop_filter_bounds);
+ blur->ClearBackdropFilterBounds();
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
@@ -283,10 +308,38 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) {
#endif
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_off_axis.png")));
}
+TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBoundsWithChildren) {
+ scoped_refptr<SolidColorLayer> background =
+ CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
+ scoped_refptr<SolidColorLayer> green =
+ CreateSolidColorLayer(gfx::Rect(50, 50, 100, 100), kCSSGreen);
+ scoped_refptr<SolidColorLayer> invert =
+ CreateSolidColorLayer(gfx::Rect(30, 30, 140, 40), SK_ColorTRANSPARENT);
+ scoped_refptr<SolidColorLayer> invert_child1 =
+ CreateSolidColorLayer(gfx::Rect(50, -20, 40, 20), kCSSOrange);
+ scoped_refptr<SolidColorLayer> invert_child2 =
+ CreateSolidColorLayer(gfx::Rect(50, 40, 40, 20), kCSSOrange);
+ background->AddChild(green);
+ background->AddChild(invert);
+ invert->AddChild(invert_child1);
+ invert->AddChild(invert_child2);
+
+ FilterOperations filters;
+ filters.Append(FilterOperation::CreateInvertFilter(1.f));
+ invert->SetBackdropFilters(filters);
+ gfx::RRectF backdrop_filter_bounds(gfx::RectF(gfx::SizeF(invert->bounds())),
+ 0);
+ invert->SetBackdropFilterBounds(backdrop_filter_bounds);
+
+ RunPixelTest(renderer_type(), background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "backdrop_filter_bounds_with_children.png")));
+}
+
class LayerTreeHostFiltersScaledPixelTest
: public LayerTreeHostFiltersPixelTest {
void SetupTree() override {
@@ -318,19 +371,18 @@ class LayerTreeHostFiltersScaledPixelTest
device_scale_factor_ = device_scale_factor;
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
float device_scale_factor_;
};
-// TODO(crbug.com/948128): Enable these tests for Skia.
-INSTANTIATE_TEST_SUITE_P(
- ,
- LayerTreeHostFiltersScaledPixelTest,
- ::testing::Values(LayerTreePixelTest::PIXEL_TEST_GL,
- LayerTreePixelTest::PIXEL_TEST_SOFTWARE));
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostFiltersScaledPixelTest,
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+ LayerTreeTest::RENDERER_SOFTWARE));
TEST_P(LayerTreeHostFiltersScaledPixelTest, StandardDpi) {
RunPixelTestType(100, 1.f);
@@ -350,7 +402,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, NullFilter) {
filters.Append(FilterOperation::CreateReferenceFilter(nullptr));
foreground->SetFilters(filters);
- RunPixelTest(GetPixelTestType(), foreground,
+ RunPixelTest(renderer_type(), foreground,
base::FilePath(FILE_PATH_LITERAL("green.png")));
}
@@ -369,7 +421,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, CroppedFilter) {
filters.Append(FilterOperation::CreateReferenceFilter(offset));
foreground->SetFilters(filters);
- RunPixelTest(GetPixelTestType(), foreground,
+ RunPixelTest(renderer_type(), foreground,
base::FilePath(FILE_PATH_LITERAL("white.png")));
}
@@ -381,16 +433,16 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterClipped) {
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorRED);
background->AddChild(foreground);
- SkScalar matrix[20];
+ float matrix[20];
memset(matrix, 0, 20 * sizeof(matrix[0]));
// This filter does a red-blue swap, so the foreground becomes blue.
- matrix[2] = matrix[6] = matrix[10] = matrix[18] = SK_Scalar1;
+ matrix[2] = matrix[6] = matrix[10] = matrix[18] = 1.0f;
// We filter only the bottom 200x100 pixels of the foreground.
SkImageFilter::CropRect crop_rect(SkRect::MakeXYWH(0, 100, 200, 100));
FilterOperations filters;
filters.Append(
FilterOperation::CreateReferenceFilter(sk_make_sp<ColorFilterPaintFilter>(
- SkColorFilters::MatrixRowMajor255(matrix), nullptr, &crop_rect)));
+ SkColorFilters::Matrix(matrix), nullptr, &crop_rect)));
// Make the foreground layer's render surface be clipped by the background
// layer.
@@ -405,7 +457,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterClipped) {
transform.Translate(0.0, -100.0);
foreground->SetTransform(transform);
- RunPixelTest(GetPixelTestType(), background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")));
}
@@ -417,16 +469,16 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterNonZeroOrigin) {
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorRED);
background->AddChild(foreground);
- SkScalar matrix[20];
+ float matrix[20];
memset(matrix, 0, 20 * sizeof(matrix[0]));
// This filter does a red-blue swap, so the foreground becomes blue.
- matrix[2] = matrix[6] = matrix[10] = matrix[18] = SK_Scalar1;
+ matrix[2] = matrix[6] = matrix[10] = matrix[18] = 1.0f;
// Set up a crop rec to filter the bottom 200x100 pixels of the foreground.
SkImageFilter::CropRect crop_rect(SkRect::MakeXYWH(0, 100, 200, 100));
FilterOperations filters;
filters.Append(
FilterOperation::CreateReferenceFilter(sk_make_sp<ColorFilterPaintFilter>(
- SkColorFilters::MatrixRowMajor255(matrix), nullptr, &crop_rect)));
+ SkColorFilters::Matrix(matrix), nullptr, &crop_rect)));
// Make the foreground layer's render surface be clipped by the background
// layer.
@@ -437,7 +489,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterNonZeroOrigin) {
// applied only to the top 100 pixels, not the bottom.
foreground->SetFiltersOrigin(gfx::PointF(0.0f, -100.0f));
- RunPixelTest(GetPixelTestType(), background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")));
}
@@ -478,7 +530,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterScaled) {
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0f));
filter->SetBackdropFilters(filters);
- filter->SetBackdropFilterBounds(gfx::RRectF());
+ filter->ClearBackdropFilterBounds();
#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
@@ -504,7 +556,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterScaled) {
#endif
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("backdrop_filter_on_scaled_layer_.png"))
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
@@ -542,12 +594,9 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterRotated) {
filters.Append(FilterOperation::CreateBlurFilter(
5.0f, SkBlurImageFilter::kClamp_TileMode));
filter_layer->SetBackdropFilters(filters);
- // TODO(916311): Adding filter bounds here should work, but it clips
- // the corner of the red box.
- // gfx::RectF backdrop_filter_bounds(gfx::SizeF(filter_layer->bounds()));
- gfx::RRectF backdrop_filter_bounds;
+ gfx::RRectF backdrop_filter_bounds(
+ gfx::RectF(gfx::SizeF(filter_layer->bounds())), 0);
filter_layer->SetBackdropFilterBounds(backdrop_filter_bounds);
-
background->AddChild(filter_layer);
// Allow some fuzziness so that this doesn't fail when Skia makes minor
@@ -563,7 +612,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterRotated) {
average_error_allowed_in_bad_pixels, large_error_allowed,
small_error_allowed));
- RunPixelTest(GetPixelTestType(), background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("backdrop_filter_rotated_.png"))
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
@@ -600,24 +649,26 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageRenderSurfaceScaled) {
// Software has some huge differences in the AA'd pixels on the different
// trybots. See crbug.com/452198.
- float percentage_pixels_large_error = 0.686f;
- float percentage_pixels_small_error = 0.0f;
- float average_error_allowed_in_bad_pixels = 16.f;
- int large_error_allowed = 17;
- 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));
+ if (renderer_type() == LayerTreeTest::RENDERER_SOFTWARE) {
+ float percentage_pixels_large_error = 0.686f;
+ float percentage_pixels_small_error = 0.0f;
+ float average_error_allowed_in_bad_pixels = 16.f;
+ int large_error_allowed = 17;
+ 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));
+ }
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("scaled_render_surface_layer_.png"))
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
-TEST_P(LayerTreeHostFiltersPixelTest, ZoomFilter) {
+TEST_P(LayerTreeHostFiltersPixelTestNonSkia, ZoomFilter) {
scoped_refptr<SolidColorLayer> root =
CreateSolidColorLayer(gfx::Rect(300, 300), SK_ColorWHITE);
@@ -681,7 +732,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, ZoomFilter) {
small_error_allowed));
#endif
- RunPixelTest(GetPixelTestType(), std::move(root),
+ RunPixelTest(renderer_type(), std::move(root),
base::FilePath(FILE_PATH_LITERAL("zoom_filter_.png"))
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
@@ -722,7 +773,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, RotatedFilter) {
small_error_allowed));
#endif
- RunPixelTest(GetPixelTestType(), background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("rotated_filter_.png"))
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
@@ -769,7 +820,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, RotatedDropShadowFilter) {
#endif
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("rotated_drop_shadow_filter_.png"))
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
@@ -808,10 +859,12 @@ TEST_P(LayerTreeHostFiltersPixelTest, TranslatedFilter) {
parent->AddChild(child);
clip->AddChild(parent);
+ if (renderer_type() == RENDERER_SOFTWARE)
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
+
RunPixelTest(
- GetPixelTestType(), clip,
- base::FilePath(FILE_PATH_LITERAL("translated_blue_green_alpha_.png"))
- .InsertBeforeExtensionASCII(GetRendererSuffix()));
+ renderer_type(), clip,
+ base::FilePath(FILE_PATH_LITERAL("translated_blue_green_alpha.png")));
}
TEST_P(LayerTreeHostFiltersPixelTest, EnlargedTextureWithAlphaThresholdFilter) {
@@ -850,7 +903,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, EnlargedTextureWithAlphaThresholdFilter) {
set_enlarge_texture_amount(gfx::Size(50, 50));
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("enlarged_texture_on_threshold.png")));
}
@@ -888,11 +941,12 @@ TEST_P(LayerTreeHostFiltersPixelTest, EnlargedTextureWithCropOffsetFilter) {
set_enlarge_texture_amount(gfx::Size(50, 50));
RunPixelTest(
- GetPixelTestType(), background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("enlarged_texture_on_crop_offset.png")));
}
-TEST_P(LayerTreeHostFiltersPixelTest, BlurFilterWithClip) {
+// TODO(crbug.com/948128): Enable this test for SkiaRenderer.
+TEST_P(LayerTreeHostFiltersPixelTestNonSkia, BlurFilterWithClip) {
scoped_refptr<SolidColorLayer> child1 =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorBLUE);
scoped_refptr<SolidColorLayer> child2 =
@@ -937,7 +991,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, BlurFilterWithClip) {
small_error_allowed));
#endif
- RunPixelTest(GetPixelTestType(), filter_layer,
+ RunPixelTest(renderer_type(), filter_layer,
base::FilePath(FILE_PATH_LITERAL("blur_filter_with_clip_.png"))
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
@@ -945,14 +999,14 @@ TEST_P(LayerTreeHostFiltersPixelTest, BlurFilterWithClip) {
TEST_P(LayerTreeHostFiltersPixelTestGPU, FilterWithGiantCropRect) {
scoped_refptr<SolidColorLayer> tree = BuildFilterWithGiantCropRect(true);
RunPixelTest(
- GetPixelTestType(), tree,
+ renderer_type(), tree,
base::FilePath(FILE_PATH_LITERAL("filter_with_giant_crop_rect.png")));
}
TEST_P(LayerTreeHostFiltersPixelTestGPU, FilterWithGiantCropRectNoClip) {
scoped_refptr<SolidColorLayer> tree = BuildFilterWithGiantCropRect(false);
RunPixelTest(
- GetPixelTestType(), tree,
+ renderer_type(), tree,
base::FilePath(FILE_PATH_LITERAL("filter_with_giant_crop_rect.png")));
}
@@ -976,13 +1030,13 @@ class BackdropFilterWithDeviceScaleFactorTest
filters.Append(FilterOperation::CreateReferenceFilter(
sk_make_sp<OffsetPaintFilter>(0, 80, nullptr)));
filtered->SetBackdropFilters(filters);
- filtered->SetBackdropFilterBounds(gfx::RRectF());
+ filtered->ClearBackdropFilterBounds();
root->AddChild(filtered);
// This should appear as a grid of 4 100x100 squares which are:
// BLACK WHITE
// DARK GREEN LIGHT GREEN
- RunPixelTest(GetPixelTestType(), std::move(root), expected_result);
+ RunPixelTest(renderer_type(), std::move(root), expected_result);
}
private:
@@ -995,12 +1049,12 @@ class BackdropFilterWithDeviceScaleFactorTest
float device_scale_factor_ = 1;
};
-// TODO(crbug.com/948128): Enable these tests for Skia.
-INSTANTIATE_TEST_SUITE_P(
- ,
- BackdropFilterWithDeviceScaleFactorTest,
- ::testing::Values(LayerTreePixelTest::PIXEL_TEST_GL,
- LayerTreePixelTest::PIXEL_TEST_SOFTWARE));
+// TODO(973699): This test is broken in software_renderer. Re-enable this test
+// when fixed.
+INSTANTIATE_TEST_SUITE_P(,
+ BackdropFilterWithDeviceScaleFactorTest,
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL));
TEST_P(BackdropFilterWithDeviceScaleFactorTest, StandardDpi) {
RunPixelTestType(
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index dc63c711f27..9e125057e0d 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -109,7 +109,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffect) {
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -167,7 +167,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, SolidColorLayerEmptyMaskWithEffect) {
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -250,7 +250,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, SolidColorEmptyMaskWithEffect) {
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -313,7 +313,7 @@ TEST_P(LayerTreeHostLayerListPixelTest,
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -322,7 +322,7 @@ TEST_P(LayerTreeHostLayerListPixelTest,
mask_effect.stable_id = 3;
mask_effect.transform_id = 1;
mask_effect.blend_mode = SkBlendMode::kDstIn;
- mask_effect.has_render_surface = true;
+ mask_effect.render_surface_reason = RenderSurfaceReason::kTest;
property_trees.effect_tree.Insert(mask_effect, 2);
scoped_refptr<SolidColorLayer> background =
@@ -378,7 +378,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectNoContentToMask) {
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -418,7 +418,18 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectNoContentToMask) {
&property_trees);
}
-TEST_P(LayerTreeHostLayerListPixelTest, ScaledMaskWithEffect) {
+using LayerTreeHostLayerListPixelTestNonSkia = LayerTreeHostLayerListPixelTest;
+
+// TODO(crbug.com/948128): Enable this test for Skia.
+INSTANTIATE_TEST_SUITE_P(
+ PixelResourceTest,
+ LayerTreeHostLayerListPixelTestNonSkia,
+ ::testing::Combine(
+ ::testing::Values(SOFTWARE, GPU, ONE_COPY, ZERO_COPY),
+ ::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK,
+ Layer::LayerMaskType::MULTI_TEXTURE_MASK)));
+
+TEST_P(LayerTreeHostLayerListPixelTestNonSkia, ScaledMaskWithEffect) {
PropertyTrees property_trees;
scoped_refptr<Layer> root_layer;
InitializeForLayerListMode(&root_layer, &property_trees);
@@ -426,7 +437,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, ScaledMaskWithEffect) {
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -502,7 +513,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectDifferentSize) {
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -562,7 +573,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, ImageMaskWithEffect) {
EffectNode isolation_effect;
isolation_effect.clip_id = 1;
isolation_effect.stable_id = 2;
- isolation_effect.has_render_surface = true;
+ isolation_effect.render_surface_reason = RenderSurfaceReason::kTest;
isolation_effect.transform_id = 1;
property_trees.effect_tree.Insert(isolation_effect, 1);
@@ -806,9 +817,16 @@ class CircleContentLayerClient : public ContentLayerClient {
using LayerTreeHostMasksForBackdropFiltersPixelTest =
ParameterizedPixelResourceTest;
+INSTANTIATE_PIXEL_RESOURCE_TEST_SUITE_P(
+ LayerTreeHostMasksForBackdropFiltersPixelTest);
+
+using LayerTreeHostMasksForBackdropFiltersPixelTestNonSkia =
+ ParameterizedPixelResourceTest;
+
+// TODO(crbug.com/948128): Enable these tests for Skia.
INSTANTIATE_TEST_SUITE_P(
PixelResourceTest,
- LayerTreeHostMasksForBackdropFiltersPixelTest,
+ LayerTreeHostMasksForBackdropFiltersPixelTestNonSkia,
::testing::Combine(
::testing::Values(SOFTWARE, GPU, ONE_COPY, ZERO_COPY),
::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK,
@@ -832,9 +850,8 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
- gfx::RRectF backdrop_filter_bounds;
blur->SetBackdropFilters(filters);
- blur->SetBackdropFilterBounds(backdrop_filter_bounds);
+ blur->ClearBackdropFilterBounds();
gfx::Size mask_bounds(100, 100);
CircleContentLayerClient mask_client(mask_bounds);
@@ -845,21 +862,8 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
blur->SetMaskLayer(mask.get());
CHECK_EQ(Layer::LayerMaskType::SINGLE_TEXTURE_MASK, mask->mask_type());
- float percentage_pixels_large_error = 2.5f; // 2.5%, ~250px / (100*100)
- float percentage_pixels_small_error = 0.0f;
- float average_error_allowed_in_bad_pixels = 100.0f;
- int large_error_allowed = 256;
- int small_error_allowed = 0;
- pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
- true, // discard_alpha
- percentage_pixels_large_error,
- percentage_pixels_small_error,
- average_error_allowed_in_bad_pixels,
- large_error_allowed,
- small_error_allowed);
-
base::FilePath image_name =
- (test_case_ == GPU)
+ (test_case_ == GPU || test_case_ == SKIA_GL)
? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png"))
: base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter.png"));
RunPixelResourceTest(background, image_name);
@@ -940,16 +944,24 @@ class StaticPictureLayer : private ContentLayerClient, public PictureLayer {
scoped_refptr<DisplayItemList> display_list_;
};
+constexpr uint32_t kUseAntialiasing = 1 << 0;
+constexpr uint32_t kForceShaders = 1 << 1;
+
+struct MaskTestConfig {
+ PixelResourceTestCase test_case;
+ uint32_t flags;
+};
+
class LayerTreeHostMaskAsBlendingPixelTest
: public LayerTreeHostPixelResourceTest,
- public ::testing::WithParamInterface<int> {
+ public ::testing::WithParamInterface<MaskTestConfig> {
public:
LayerTreeHostMaskAsBlendingPixelTest()
: LayerTreeHostPixelResourceTest(
- GetParam() ? ZERO_COPY : SOFTWARE,
+ GetParam().test_case,
Layer::LayerMaskType::SINGLE_TEXTURE_MASK),
- use_antialiasing_(GetParam() == 2 || GetParam() == 4),
- force_shaders_(GetParam() == 3 || GetParam() == 4) {
+ use_antialiasing_(GetParam().flags & kUseAntialiasing),
+ force_shaders_(GetParam().flags & kForceShaders) {
float percentage_pixels_small_error = 0.f;
float percentage_pixels_error = 0.f;
float average_error_allowed_in_bad_pixels = 0.f;
@@ -961,7 +973,7 @@ class LayerTreeHostMaskAsBlendingPixelTest
average_error_allowed_in_bad_pixels = 3.5f;
large_error_allowed = 15;
small_error_allowed = 1;
- } else if (test_type_ != PIXEL_TEST_SOFTWARE) {
+ } else if (test_case_ != SOFTWARE) {
percentage_pixels_small_error = 0.9f;
percentage_pixels_error = 6.5f;
average_error_allowed_in_bad_pixels = 3.5f;
@@ -1068,15 +1080,18 @@ class LayerTreeHostMaskAsBlendingPixelTest
bool force_shaders_;
};
+// TODO(crbug.com/948128): Enable these tests for Skia.
+MaskTestConfig const kTestConfigs[] = {
+ MaskTestConfig{SOFTWARE, 0},
+ MaskTestConfig{ZERO_COPY, 0},
+ MaskTestConfig{ZERO_COPY, kUseAntialiasing},
+ MaskTestConfig{ZERO_COPY, kForceShaders},
+ MaskTestConfig{ZERO_COPY, kUseAntialiasing | kForceShaders},
+};
+
INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostMaskAsBlendingPixelTest,
- ::testing::Range(0, 5));
-// Instantiate 5 test modes of the following:
-// 0: SOFTWARE (golden sample)
-// 1: GL
-// 2: GL + AA
-// 3: GL + Forced Shaders
-// 4: GL + Forced Shaders + AA
+ ::testing::ValuesIn(kTestConfigs));
TEST_P(LayerTreeHostMaskAsBlendingPixelTest, PixelAlignedNoop) {
// This test verifies the degenerate case of a no-op mask doesn't affect
@@ -1214,7 +1229,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircle) {
mask_isolation->AddChild(mask_layer);
base::FilePath image_name =
- (test_type_ == PIXEL_TEST_SOFTWARE)
+ (test_case_ == SOFTWARE)
? base::FilePath(
FILE_PATH_LITERAL("mask_as_blending_rotated_circle.png"))
: base::FilePath(
@@ -1261,7 +1276,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) {
mask_isolation->AddChild(mask_layer);
base::FilePath image_name =
- (test_type_ == PIXEL_TEST_SOFTWARE)
+ (test_case_ == SOFTWARE)
? base::FilePath(FILE_PATH_LITERAL(
"mask_as_blending_rotated_circle_underflow.png"))
: base::FilePath(FILE_PATH_LITERAL(
@@ -1269,7 +1284,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) {
RunPixelResourceTest(root, image_name);
}
-TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
+TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTestNonSkia,
MaskOfLayerWithBackdropFilterAndBlend) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE);
@@ -1294,8 +1309,7 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
picture_horizontal->SetBackdropFilters(filters);
- gfx::RRectF backdrop_filter_bounds;
- picture_horizontal->SetBackdropFilterBounds(backdrop_filter_bounds);
+ picture_horizontal->ClearBackdropFilterBounds();
background->AddChild(picture_vertical);
background->AddChild(picture_horizontal);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
index 31051051a9d..41660e1fb34 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -24,16 +24,15 @@ namespace {
// Can't templatize a class on its own members, so ReadbackType and
// ReadbackTestConfig are declared here, before LayerTreeHostReadbackPixelTest.
enum ReadbackType {
- READBACK_INVALID,
- READBACK_DEFAULT,
+ READBACK_TEXTURE,
READBACK_BITMAP,
};
struct ReadbackTestConfig {
- ReadbackTestConfig(LayerTreePixelTest::PixelTestType pixel_test_type_,
+ ReadbackTestConfig(LayerTreeTest::RendererType renderer_type_,
ReadbackType readback_type_)
- : pixel_test_type(pixel_test_type_), readback_type(readback_type_) {}
- LayerTreePixelTest::PixelTestType pixel_test_type;
+ : renderer_type(renderer_type_), readback_type(readback_type_) {}
+ LayerTreeTest::RendererType renderer_type;
ReadbackType readback_type;
};
@@ -42,51 +41,28 @@ class LayerTreeHostReadbackPixelTest
public testing::WithParamInterface<ReadbackTestConfig> {
protected:
LayerTreeHostReadbackPixelTest()
- : readback_type_(READBACK_INVALID),
- insert_copy_request_after_frame_count_(0) {}
-
- void RunReadbackTest(PixelTestType test_type,
- ReadbackType readback_type,
- scoped_refptr<Layer> content_root,
- base::FilePath file_name) {
- readback_type_ = readback_type;
- RunPixelTest(test_type, content_root, file_name);
- }
+ : insert_copy_request_after_frame_count_(0) {}
- void RunReadbackTestWithReadbackTarget(PixelTestType type,
- ReadbackType readback_type,
- scoped_refptr<Layer> content_root,
- Layer* target,
- base::FilePath file_name) {
- readback_type_ = readback_type;
- RunPixelTestWithReadbackTarget(type, content_root, target, file_name);
- }
+ RendererType renderer_type() const { return GetParam().renderer_type; }
+
+ ReadbackType readback_type() const { return GetParam().readback_type; }
std::unique_ptr<viz::CopyOutputRequest> CreateCopyOutputRequest() override {
std::unique_ptr<viz::CopyOutputRequest> request;
- if (readback_type_ == READBACK_BITMAP) {
+ if (readback_type() == READBACK_BITMAP) {
request = std::make_unique<viz::CopyOutputRequest>(
viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
base::BindOnce(
&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
base::Unretained(this)));
} else {
- DCHECK_EQ(readback_type_, READBACK_DEFAULT);
- if (test_type_ == PIXEL_TEST_SOFTWARE) {
- request = std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
- base::BindOnce(
- &LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
- base::Unretained(this)));
- } else {
- DCHECK_EQ(test_type_, PIXEL_TEST_GL);
- request = std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
- base::BindOnce(
- &LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture,
- base::Unretained(this)));
- }
+ DCHECK_NE(renderer_type_, RENDERER_SOFTWARE);
+ request = std::make_unique<viz::CopyOutputRequest>(
+ viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
+ base::BindOnce(
+ &LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture,
+ base::Unretained(this)));
}
if (!copy_subrect_.IsEmpty())
@@ -139,7 +115,6 @@ class LayerTreeHostReadbackPixelTest
result->rect(), bitmap));
}
- ReadbackType readback_type_;
gfx::Rect copy_subrect_;
gfx::ColorSpace output_color_space_ = gfx::ColorSpace::CreateSRGB();
int insert_copy_request_after_frame_count_;
@@ -153,8 +128,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackRootLayer) {
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
background->AddChild(green);
- RunReadbackTest(GetParam().pixel_test_type, GetParam().readback_type,
- background, base::FilePath(FILE_PATH_LITERAL("green.png")));
+ RunPixelTest(renderer_type(), background,
+ base::FilePath(FILE_PATH_LITERAL("green.png")));
}
TEST_P(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild) {
@@ -169,9 +144,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild) {
CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
green->AddChild(blue);
- RunReadbackTest(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
+ RunPixelTest(renderer_type(), background,
+ base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
}
TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer) {
@@ -182,9 +156,9 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer) {
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
background->AddChild(green);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- green.get(), base::FilePath(FILE_PATH_LITERAL("green.png")));
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, green.get(),
+ base::FilePath(FILE_PATH_LITERAL("green.png")));
}
TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer) {
@@ -195,9 +169,9 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer) {
CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
background->AddChild(green);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- green.get(), base::FilePath(FILE_PATH_LITERAL("green_small.png")));
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, green.get(),
+ base::FilePath(FILE_PATH_LITERAL("green_small.png")));
}
TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild) {
@@ -212,9 +186,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild) {
CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
green->AddChild(blue);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- green.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, green.get(),
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -235,9 +208,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSubtreeSurroundsTargetLayer) {
target->AddChild(blue);
copy_subrect_ = gfx::Rect(0, 0, 100, 100);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- target.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, target.get(),
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -259,9 +231,8 @@ TEST_P(LayerTreeHostReadbackPixelTest,
target->AddChild(blue);
copy_subrect_ = gfx::Rect(50, 50, 100, 100);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- target.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, target.get(),
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -278,9 +249,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackHiddenSubtree) {
CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
hidden_target->AddChild(blue);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- hidden_target.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, hidden_target.get(),
base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
}
@@ -300,8 +270,8 @@ TEST_P(LayerTreeHostReadbackPixelTest,
hidden_target->RequestCopyOfOutput(
viz::CopyOutputRequest::CreateStubForTesting());
- RunReadbackTest(GetParam().pixel_test_type, GetParam().readback_type,
- background, base::FilePath(FILE_PATH_LITERAL("black.png")));
+ RunPixelTest(renderer_type(), background,
+ base::FilePath(FILE_PATH_LITERAL("black.png")));
}
TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSubrect) {
@@ -319,8 +289,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSubrect) {
// Grab the middle of the root layer.
copy_subrect_ = gfx::Rect(50, 50, 100, 100);
- RunReadbackTest(
- GetParam().pixel_test_type, GetParam().readback_type, background,
+ RunPixelTest(
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -339,9 +309,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect) {
// Grab the middle of the green layer.
copy_subrect_ = gfx::Rect(25, 25, 100, 100);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- green.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, green.get(),
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -362,9 +331,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackWhenNoDamage) {
target->AddChild(blue);
insert_copy_request_after_frame_count_ = 1;
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- target.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, target.get(),
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -386,9 +354,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackOutsideViewportWhenNoDamage) {
target->AddChild(blue);
insert_copy_request_after_frame_count_ = 1;
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- target.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, target.get(),
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -407,9 +374,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerOutsideViewport) {
CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
green->AddChild(blue);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- green.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, green.get(),
base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
}
@@ -426,9 +392,8 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootOrFirstLayer) {
blue->RequestCopyOfOutput(viz::CopyOutputRequest::CreateStubForTesting());
background->AddChild(blue);
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- background.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, background.get(),
base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
}
@@ -445,21 +410,20 @@ TEST_P(LayerTreeHostReadbackPixelTest, MultipleReadbacksOnLayer) {
background->RequestCopyOfOutput(
viz::CopyOutputRequest::CreateStubForTesting());
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- background.get(), base::FilePath(FILE_PATH_LITERAL("green.png")));
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, background.get(),
+ base::FilePath(FILE_PATH_LITERAL("green.png")));
}
INSTANTIATE_TEST_SUITE_P(
- LayerTreeHostReadbackPixelTests,
+ ,
LayerTreeHostReadbackPixelTest,
::testing::Values(
- ReadbackTestConfig(LayerTreeHostReadbackPixelTest::PIXEL_TEST_SOFTWARE,
- READBACK_DEFAULT),
- ReadbackTestConfig(LayerTreeHostReadbackPixelTest::PIXEL_TEST_GL,
- READBACK_DEFAULT),
- ReadbackTestConfig(LayerTreeHostReadbackPixelTest::PIXEL_TEST_GL,
- READBACK_BITMAP)));
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_TEXTURE),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE)));
class LayerTreeHostReadbackDeviceScalePixelTest
: public LayerTreeHostReadbackPixelTest {
@@ -513,8 +477,8 @@ TEST_P(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackSubrect) {
// Grab the middle of the root layer.
copy_subrect_ = gfx::Rect(25, 25, 50, 50);
device_scale_factor_ = 2.f;
- RunReadbackTest(
- GetParam().pixel_test_type, GetParam().readback_type, background,
+ RunPixelTest(
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
@@ -541,22 +505,20 @@ TEST_P(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackNonRootLayerSubrect) {
// Grab the green layer's content with blue in the bottom right.
copy_subrect_ = gfx::Rect(25, 25, 50, 50);
device_scale_factor_ = 2.f;
- RunReadbackTestWithReadbackTarget(
- GetParam().pixel_test_type, GetParam().readback_type, background,
- green.get(),
+ RunPixelTestWithReadbackTarget(
+ renderer_type(), background, green.get(),
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
INSTANTIATE_TEST_SUITE_P(
- LayerTreeHostReadbackDeviceScalePixelTests,
+ ,
LayerTreeHostReadbackDeviceScalePixelTest,
::testing::Values(
- ReadbackTestConfig(LayerTreeHostReadbackPixelTest::PIXEL_TEST_SOFTWARE,
- READBACK_DEFAULT),
- ReadbackTestConfig(LayerTreeHostReadbackPixelTest::PIXEL_TEST_GL,
- READBACK_DEFAULT),
- ReadbackTestConfig(LayerTreeHostReadbackPixelTest::PIXEL_TEST_GL,
- READBACK_BITMAP)));
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_TEXTURE),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE)));
class LayerTreeHostReadbackColorSpacePixelTest
: public LayerTreeHostReadbackPixelTest {
@@ -589,24 +551,20 @@ TEST_P(LayerTreeHostReadbackColorSpacePixelTest, Readback) {
background->SetBounds(gfx::Size(200, 200));
background->SetIsDrawable(true);
- if (GetParam().pixel_test_type == PIXEL_TEST_SOFTWARE) {
- // Software compositing doesn't support color conversion, so the result will
- // come out in sRGB, regardless of the display's color properties.
- RunReadbackTest(GetParam().pixel_test_type, GetParam().readback_type,
- background, base::FilePath(FILE_PATH_LITERAL("green.png")));
- } else {
- // GL compositing will convert the sRGB green into P3.
- RunReadbackTest(GetParam().pixel_test_type, GetParam().readback_type,
- background,
- base::FilePath(FILE_PATH_LITERAL("srgb_green_in_p3.png")));
- }
+ // The sRGB green should be converted into P3.
+ RunPixelTest(renderer_type(), background,
+ base::FilePath(FILE_PATH_LITERAL("srgb_green_in_p3.png")));
}
-INSTANTIATE_TEST_SUITE_P(LayerTreeHostReadbackColorSpacePixelTests,
- LayerTreeHostReadbackColorSpacePixelTest,
- ::testing::Values(ReadbackTestConfig(
- LayerTreeHostReadbackPixelTest::PIXEL_TEST_GL,
- READBACK_BITMAP)));
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostReadbackColorSpacePixelTest,
+ ::testing::Values(
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_TEXTURE),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP),
+ ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE)));
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index 1c94cf36b3e..8955987ba23 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -12,6 +12,7 @@
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/test/layer_tree_pixel_test.h"
+#include "cc/test/pixel_comparator.h"
#include "cc/test/test_in_process_context_provider.h"
#include "cc/trees/layer_tree_impl.h"
#include "gpu/command_buffer/client/gles2_interface.h"
@@ -21,10 +22,14 @@
namespace cc {
namespace {
-class LayerTreeHostScrollbarsPixelTest : public LayerTreePixelTest {
+class LayerTreeHostScrollbarsPixelTest
+ : public LayerTreePixelTest,
+ public ::testing::WithParamInterface<LayerTreeTest::RendererType> {
protected:
LayerTreeHostScrollbarsPixelTest() = default;
+ RendererType renderer_type() { return GetParam(); }
+
void InitializeSettings(LayerTreeSettings* settings) override {
settings->layer_transforms_should_scale_layer_contents = true;
}
@@ -84,7 +89,12 @@ class PaintedScrollbar : public Scrollbar {
gfx::Rect rect_;
};
-TEST_F(LayerTreeHostScrollbarsPixelTest, NoScale) {
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostScrollbarsPixelTest,
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL));
+
+TEST_P(LayerTreeHostScrollbarsPixelTest, NoScale) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
@@ -95,11 +105,11 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, NoScale) {
layer->SetBounds(gfx::Size(200, 200));
background->AddChild(layer);
- RunPixelTest(PIXEL_TEST_GL, background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("spiral.png")));
}
-TEST_F(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) {
+TEST_P(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) {
// With a device scale of 2, the scrollbar should still be rendered
// pixel-perfect, not show scaling artifacts
device_scale_factor_ = 2.f;
@@ -114,11 +124,11 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) {
layer->SetBounds(gfx::Size(100, 100));
background->AddChild(layer);
- RunPixelTest(PIXEL_TEST_GL, background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("spiral_double_scale.png")));
}
-TEST_F(LayerTreeHostScrollbarsPixelTest, TransformScale) {
+TEST_P(LayerTreeHostScrollbarsPixelTest, TransformScale) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
@@ -135,7 +145,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, TransformScale) {
scale_transform.Scale(2.0, 2.0);
layer->SetTransform(scale_transform);
- RunPixelTest(PIXEL_TEST_GL, background,
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("spiral_double_scale.png")));
}
@@ -145,7 +155,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, TransformScale) {
#else
#define MAYBE_HugeTransformScale HugeTransformScale
#endif
-TEST_F(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) {
+TEST_P(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);
@@ -179,7 +189,10 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) {
scale_transform.Scale(scale, scale);
layer->SetTransform(scale_transform);
- RunPixelTest(PIXEL_TEST_GL, background,
+ if (renderer_type() == RENDERER_SKIA_GL)
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
+
+ RunPixelTest(renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("spiral_64_scale.png")));
}
@@ -241,9 +254,14 @@ class PaintedOverlayScrollbar : public PaintedScrollbar {
}
};
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostOverlayScrollbarsPixelTest,
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL));
+
// Simulate increasing the thickness of a painted overlay scrollbar. Ensure that
// the scrollbar border remains crisp.
-TEST_F(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledUp) {
+TEST_P(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledUp) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);
@@ -261,13 +279,13 @@ TEST_F(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledUp) {
layer->SetPosition(gfx::PointF(185, 10));
RunPixelTest(
- PIXEL_TEST_GL, background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("overlay_scrollbar_scaled_up.png")));
}
// Simulate decreasing the thickness of a painted overlay scrollbar. Ensure that
// the scrollbar border remains crisp.
-TEST_F(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledDown) {
+TEST_P(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledDown) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);
@@ -285,7 +303,7 @@ TEST_F(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledDown) {
layer->SetPosition(gfx::PointF(185, 10));
RunPixelTest(
- PIXEL_TEST_GL, background,
+ renderer_type(), background,
base::FilePath(FILE_PATH_LITERAL("overlay_scrollbar_scaled_down.png")));
}
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
index 8bfca2af17e..fac28b34708 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
@@ -16,65 +16,57 @@
namespace cc {
namespace {
-class LayerTreeHostSynchronousPixelTest : public LayerTreePixelTest {
- public:
+class LayerTreeHostSynchronousPixelTest
+ : public LayerTreePixelTest,
+ public ::testing::WithParamInterface<LayerTreeTest::RendererType> {
+ protected:
void InitializeSettings(LayerTreeSettings* settings) override {
LayerTreePixelTest::InitializeSettings(settings);
settings->single_thread_proxy_scheduler = false;
- settings->use_zero_copy = true;
+ settings->gpu_rasterization_forced = gpu_rasterization_forced_;
+ settings->use_zero_copy = use_zero_copy_;
}
+ LayerTreeTest::RendererType renderer_type() { return GetParam(); }
+
void BeginTest() override {
LayerTreePixelTest::BeginTest();
PostCompositeImmediatelyToMainThread();
}
-};
-
-TEST_F(LayerTreeHostSynchronousPixelTest, OneContentLayer) {
- gfx::Size bounds(200, 200);
- FakeContentLayerClient client;
- client.set_bounds(bounds);
- PaintFlags green_flags;
- green_flags.setColor(SkColorSetARGB(255, 0, 255, 0));
- client.add_draw_rect(gfx::Rect(bounds), green_flags);
- scoped_refptr<PictureLayer> root = PictureLayer::Create(&client);
- root->SetBounds(bounds);
- root->SetIsDrawable(true);
+ void DoContentLayerTest() {
+ gfx::Size bounds(200, 200);
- RunSingleThreadedPixelTest(
- PIXEL_TEST_GL, root, base::FilePath(FILE_PATH_LITERAL("green.png")));
-}
+ FakeContentLayerClient client;
+ client.set_bounds(bounds);
+ PaintFlags green_flags;
+ green_flags.setColor(SkColorSetARGB(255, 0, 255, 0));
+ client.add_draw_rect(gfx::Rect(bounds), green_flags);
+ scoped_refptr<PictureLayer> root = PictureLayer::Create(&client);
+ root->SetBounds(bounds);
+ root->SetIsDrawable(true);
-class LayerTreeHostSynchronousGPUPixelTest : public LayerTreePixelTest {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- LayerTreePixelTest::InitializeSettings(settings);
- settings->single_thread_proxy_scheduler = false;
- settings->gpu_rasterization_forced = true;
+ RunSingleThreadedPixelTest(renderer_type(), root,
+ base::FilePath(FILE_PATH_LITERAL("green.png")));
}
- void BeginTest() override {
- LayerTreePixelTest::BeginTest();
- PostCompositeImmediatelyToMainThread();
- }
+ bool gpu_rasterization_forced_ = false;
+ bool use_zero_copy_ = false;
};
-TEST_F(LayerTreeHostSynchronousGPUPixelTest, OneContentLayer) {
- gfx::Size bounds(200, 200);
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostSynchronousPixelTest,
+ ::testing::Values(LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL));
- FakeContentLayerClient client;
- client.set_bounds(bounds);
- PaintFlags green_flags;
- green_flags.setColor(SkColorSetARGB(255, 0, 255, 0));
- client.add_draw_rect(gfx::Rect(bounds), green_flags);
- scoped_refptr<PictureLayer> root = PictureLayer::Create(&client);
- root->SetBounds(bounds);
- client.set_bounds(bounds);
- root->SetIsDrawable(true);
+TEST_P(LayerTreeHostSynchronousPixelTest, OneContentLayerZeroCopy) {
+ use_zero_copy_ = true;
+ DoContentLayerTest();
+}
- RunSingleThreadedPixelTest(PIXEL_TEST_GL, root,
- base::FilePath(FILE_PATH_LITERAL("green.png")));
+TEST_P(LayerTreeHostSynchronousPixelTest, OneContentLayerGpuRasterization) {
+ gpu_rasterization_forced_ = true;
+ DoContentLayerTest();
}
} // namespace
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index 8ed832e7844..ad22f279d6a 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -21,56 +21,44 @@ namespace cc {
namespace {
enum RasterMode {
- PARTIAL_ONE_COPY,
- FULL_ONE_COPY,
- PARTIAL_GPU,
- FULL_GPU,
- PARTIAL_GPU_LOW_BIT_DEPTH,
- FULL_GPU_LOW_BIT_DEPTH,
- PARTIAL_BITMAP,
- FULL_BITMAP,
+ BITMAP,
+ ONE_COPY,
+ GPU,
+ GPU_LOW_BIT_DEPTH,
};
-class LayerTreeHostTilesPixelTest : public LayerTreePixelTest {
+struct TilesTestConfig {
+ LayerTreeTest::RendererType renderer_type;
+ RasterMode raster_mode;
+};
+
+class LayerTreeHostTilesPixelTest
+ : public LayerTreePixelTest,
+ public ::testing::WithParamInterface<TilesTestConfig> {
protected:
+ RendererType renderer_type() const { return GetParam().renderer_type; }
+
+ RasterMode raster_mode() const { return GetParam().raster_mode; }
+
void InitializeSettings(LayerTreeSettings* settings) override {
LayerTreePixelTest::InitializeSettings(settings);
- switch (raster_mode_) {
- case PARTIAL_ONE_COPY:
+ switch (raster_mode()) {
+ case ONE_COPY:
settings->use_zero_copy = false;
- settings->use_partial_raster = true;
break;
- case FULL_ONE_COPY:
- settings->use_zero_copy = false;
- settings->use_partial_raster = false;
- break;
- case PARTIAL_BITMAP:
- settings->use_partial_raster = true;
- break;
- case FULL_BITMAP:
- settings->use_partial_raster = false;
- break;
- case PARTIAL_GPU:
+ case GPU:
settings->gpu_rasterization_forced = true;
- settings->use_partial_raster = true;
break;
- case FULL_GPU:
+ case GPU_LOW_BIT_DEPTH:
settings->gpu_rasterization_forced = true;
- settings->use_partial_raster = false;
- break;
- case PARTIAL_GPU_LOW_BIT_DEPTH:
- settings->gpu_rasterization_forced = true;
- settings->use_partial_raster = true;
settings->use_rgba_4444 = true;
settings->unpremultiply_and_dither_low_bit_depth_tiles = true;
break;
- case FULL_GPU_LOW_BIT_DEPTH:
- settings->gpu_rasterization_forced = true;
- settings->use_partial_raster = false;
- settings->use_rgba_4444 = true;
- settings->unpremultiply_and_dither_low_bit_depth_tiles = true;
+ default:
break;
}
+
+ settings->use_partial_raster = use_partial_raster_;
}
void BeginTest() override {
@@ -84,36 +72,9 @@ class LayerTreeHostTilesPixelTest : public LayerTreePixelTest {
target->RequestCopyOfOutput(CreateCopyOutputRequest());
}
- void RunRasterPixelTest(bool threaded,
- RasterMode mode,
- scoped_refptr<Layer> content_root,
- base::FilePath file_name) {
- raster_mode_ = mode;
-
- PixelTestType test_type = PIXEL_TEST_SOFTWARE;
- switch (mode) {
- case PARTIAL_ONE_COPY:
- case FULL_ONE_COPY:
- case PARTIAL_GPU:
- case FULL_GPU:
- case PARTIAL_GPU_LOW_BIT_DEPTH:
- case FULL_GPU_LOW_BIT_DEPTH:
- test_type = PIXEL_TEST_GL;
- break;
- case PARTIAL_BITMAP:
- case FULL_BITMAP:
- test_type = PIXEL_TEST_SOFTWARE;
- }
-
- if (threaded)
- RunPixelTest(test_type, content_root, file_name);
- else
- RunSingleThreadedPixelTest(test_type, content_root, file_name);
- }
-
base::FilePath ref_file_;
std::unique_ptr<SkBitmap> result_bitmap_;
- RasterMode raster_mode_;
+ bool use_partial_raster_ = false;
};
class BlueYellowClient : public ContentLayerClient {
@@ -211,81 +172,78 @@ class LayerTreeHostTilesTestPartialInvalidation
scoped_refptr<PictureLayer> picture_layer_;
};
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- PartialRaster_SingleThread_OneCopy) {
- RunRasterPixelTest(
- false, PARTIAL_ONE_COPY, picture_layer_,
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostTilesTestPartialInvalidation,
+ ::testing::Values(TilesTestConfig{LayerTreeTest::RENDERER_SOFTWARE, BITMAP},
+ TilesTestConfig{LayerTreeTest::RENDERER_GL, ONE_COPY},
+ TilesTestConfig{LayerTreeTest::RENDERER_GL, GPU},
+ TilesTestConfig{LayerTreeTest::RENDERER_SKIA_GL,
+ ONE_COPY},
+ TilesTestConfig{LayerTreeTest::RENDERER_SKIA_GL, GPU}));
+
+TEST_P(LayerTreeHostTilesTestPartialInvalidation, PartialRaster) {
+ use_partial_raster_ = true;
+ RunSingleThreadedPixelTest(
+ renderer_type(), picture_layer_,
base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
}
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- FullRaster_SingleThread_OneCopy) {
- RunRasterPixelTest(
- false, FULL_ONE_COPY, picture_layer_,
+TEST_P(LayerTreeHostTilesTestPartialInvalidation, FullRaster) {
+ RunSingleThreadedPixelTest(
+ renderer_type(), picture_layer_,
base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
}
+using LayerTreeHostTilesTestPartialInvalidationMultiThread =
+ LayerTreeHostTilesTestPartialInvalidation;
+
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostTilesTestPartialInvalidationMultiThread,
+ ::testing::Values(TilesTestConfig{LayerTreeTest::RENDERER_GL, ONE_COPY},
+ TilesTestConfig{LayerTreeTest::RENDERER_SKIA_GL,
+ ONE_COPY}));
+
// Flaky on Linux TSAN. https://crbug.com/707711
#if defined(OS_LINUX) && defined(THREAD_SANITIZER)
-#define MAYBE_PartialRaster_MultiThread_OneCopy \
- DISABLED_PartialRaster_MultiThread_OneCopy
+#define MAYBE_PartialRaster DISABLED_PartialRaster
#else
-#define MAYBE_PartialRaster_MultiThread_OneCopy \
- PartialRaster_MultiThread_OneCopy
+#define MAYBE_PartialRaster PartialRaster
#endif
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- MAYBE_PartialRaster_MultiThread_OneCopy) {
- RunRasterPixelTest(
- true, PARTIAL_ONE_COPY, picture_layer_,
+TEST_P(LayerTreeHostTilesTestPartialInvalidationMultiThread,
+ MAYBE_PartialRaster) {
+ use_partial_raster_ = true;
+ RunPixelTest(
+ renderer_type(), picture_layer_,
base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
}
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- FullRaster_MultiThread_OneCopy) {
- RunRasterPixelTest(
- true, FULL_ONE_COPY, picture_layer_,
- base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
-}
-
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- PartialRaster_SingleThread_Software) {
- RunRasterPixelTest(
- false, PARTIAL_BITMAP, picture_layer_,
- base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
-}
-
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- FulllRaster_SingleThread_Software) {
- RunRasterPixelTest(
- false, FULL_BITMAP, picture_layer_,
- base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
-}
-
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- PartialRaster_SingleThread_GpuRaster) {
- RunRasterPixelTest(
- false, PARTIAL_GPU, picture_layer_,
- base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
-}
-
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- FullRaster_SingleThread_GpuRaster) {
- RunRasterPixelTest(
- false, FULL_GPU, picture_layer_,
- base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
+TEST_P(LayerTreeHostTilesTestPartialInvalidationMultiThread, FullRaster) {
+ RunPixelTest(renderer_type(), picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
}
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- PartialRaster_SingleThread_GpuRaster_LowBitDepth) {
- RunRasterPixelTest(false, PARTIAL_GPU_LOW_BIT_DEPTH, picture_layer_,
- base::FilePath(FILE_PATH_LITERAL(
- "blue_yellow_partial_flipped_dither.png")));
+using LayerTreeHostTilesTestPartialInvalidationLowBitDepth =
+ LayerTreeHostTilesTestPartialInvalidation;
+
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostTilesTestPartialInvalidationLowBitDepth,
+ ::testing::Values(
+ TilesTestConfig{LayerTreeTest::RENDERER_GL, GPU_LOW_BIT_DEPTH},
+ TilesTestConfig{LayerTreeTest::RENDERER_SKIA_GL, GPU_LOW_BIT_DEPTH}));
+
+TEST_P(LayerTreeHostTilesTestPartialInvalidationLowBitDepth, PartialRaster) {
+ use_partial_raster_ = true;
+ RunSingleThreadedPixelTest(renderer_type(), picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL(
+ "blue_yellow_partial_flipped_dither.png")));
}
-TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- FullRaster_SingleThread_GpuRaster_LowBitDepth) {
- RunRasterPixelTest(
- false, FULL_GPU_LOW_BIT_DEPTH, picture_layer_,
+TEST_P(LayerTreeHostTilesTestPartialInvalidationLowBitDepth, FullRaster) {
+ RunSingleThreadedPixelTest(
+ renderer_type(), picture_layer_,
base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped_dither.png")));
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index 1698efbc9fa..f10dada2a20 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -351,7 +351,8 @@ class LayerTreeHostTestReadyToActivateNonEmpty
// No single thread test because the commit goes directly to the active tree in
// single thread mode, so notify ready to activate is skipped.
-MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
+// Flaky: https://crbug.com/947673
+// MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
// Test if the LTHI receives ReadyToDraw notifications from the TileManager when
// no raster tasks get scheduled.
@@ -1580,7 +1581,8 @@ class LayerTreeHostTestPrepareTilesWithoutDraw : public LayerTreeHostTest {
// This behavior is specific to Android WebView, which only uses
// multi-threaded compositor.
-MULTI_THREAD_TEST_F(LayerTreeHostTestPrepareTilesWithoutDraw);
+// Flaky: https://crbug.com/947673
+// MULTI_THREAD_TEST_F(LayerTreeHostTestPrepareTilesWithoutDraw);
// Verify CanDraw() is false until first commit.
class LayerTreeHostTestCantDrawBeforeCommit : public LayerTreeHostTest {
@@ -5661,20 +5663,22 @@ class TestSwapPromise : public SwapPromise {
base::AutoLock lock(result_->lock);
EXPECT_FALSE(result_->did_activate_called);
EXPECT_FALSE(result_->did_swap_called);
- EXPECT_FALSE(result_->did_not_swap_called);
+ EXPECT_TRUE(!result_->did_not_swap_called ||
+ action_ == SwapPromise::DidNotSwapAction::KEEP_ACTIVE);
result_->did_activate_called = true;
}
void WillSwap(viz::CompositorFrameMetadata* metadata) override {
base::AutoLock lock(result_->lock);
EXPECT_FALSE(result_->did_swap_called);
- EXPECT_FALSE(result_->did_not_swap_called);
+ EXPECT_TRUE(!result_->did_not_swap_called ||
+ action_ == SwapPromise::DidNotSwapAction::KEEP_ACTIVE);
result_->did_swap_called = true;
}
void DidSwap() override {}
- void DidNotSwap(DidNotSwapReason reason) override {
+ DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
base::AutoLock lock(result_->lock);
EXPECT_FALSE(result_->did_swap_called);
EXPECT_FALSE(result_->did_not_swap_called);
@@ -5682,13 +5686,17 @@ class TestSwapPromise : public SwapPromise {
reason != DidNotSwapReason::SWAP_FAILS);
result_->did_not_swap_called = true;
result_->reason = reason;
+ return action_;
}
+ void set_action(DidNotSwapAction action) { action_ = action; }
+
int64_t TraceId() const override { return 0; }
private:
// Not owned.
TestSwapPromiseResult* result_;
+ DidNotSwapAction action_ = DidNotSwapAction::BREAK_PROMISE;
};
class PinnedLayerTreeSwapPromise : public LayerTreeHostTest {
@@ -6041,7 +6049,7 @@ class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest {
MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromiseMFBA);
-class LayerTreeHostTestBreakSwapPromiseForVisibility
+class LayerTreeHostTestDeferSwapPromiseForVisibility
: public LayerTreeHostTest {
protected:
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -6050,6 +6058,7 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
layer_tree_host()->SetVisible(false);
auto swap_promise =
std::make_unique<TestSwapPromise>(&swap_promise_result_);
+ swap_promise->set_action(SwapPromise::DidNotSwapAction::KEEP_ACTIVE);
layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
std::move(swap_promise));
}
@@ -6060,7 +6069,7 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
sent_queue_request_ = true;
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::BindOnce(&LayerTreeHostTestBreakSwapPromiseForVisibility::
+ base::BindOnce(&LayerTreeHostTestDeferSwapPromiseForVisibility::
SetVisibleFalseAndQueueSwapPromise,
base::Unretained(this)));
}
@@ -6068,25 +6077,42 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
CommitEarlyOutReason reason) override {
- EndTest();
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestDeferSwapPromiseForVisibility::
+ CheckSwapPromiseNotCalled,
+ base::Unretained(this)));
}
- void AfterTest() override {
+ void CheckSwapPromiseNotCalled() {
{
base::AutoLock lock(swap_promise_result_.lock);
EXPECT_FALSE(swap_promise_result_.did_activate_called);
EXPECT_FALSE(swap_promise_result_.did_swap_called);
EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
+ EXPECT_FALSE(swap_promise_result_.dtor_called);
+ }
+ layer_tree_host()->SetVisible(true);
+ }
+
+ void DidCommitAndDrawFrame() override {
+ {
+ base::AutoLock lock(swap_promise_result_.lock);
+ EXPECT_TRUE(swap_promise_result_.did_activate_called);
+ EXPECT_TRUE(swap_promise_result_.did_swap_called);
EXPECT_TRUE(swap_promise_result_.dtor_called);
}
+ EndTest();
}
+ void AfterTest() override {}
+
TestSwapPromiseResult swap_promise_result_;
bool sent_queue_request_ = false;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferSwapPromiseForVisibility);
class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
public:
@@ -7095,7 +7121,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
viz::RenderPass* root_pass = frame_data->render_passes.back().get();
for (auto* draw_quad : root_pass->quad_list) {
// Checkerboards mean an incomplete frame.
- if (draw_quad->material != viz::DrawQuad::TILED_CONTENT)
+ if (draw_quad->material != viz::DrawQuad::Material::kTiledContent)
return 0.f;
const viz::TileDrawQuad* quad =
viz::TileDrawQuad::MaterialCast(draw_quad);
@@ -8315,7 +8341,8 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
image_ = DrawImage(CreateDiscardablePaintImage(gfx::Size(400, 400)),
SkIRect::MakeWH(400, 400), kNone_SkFilterQuality,
- SkMatrix::I(), PaintImage::kDefaultFrameIndex);
+ SkMatrix::I(), PaintImage::kDefaultFrameIndex,
+ gfx::ColorSpace());
auto callback = base::BindRepeating(
&LayerTreeHostTestQueueImageDecode::ImageDecodeFinished,
base::Unretained(this));
@@ -8656,7 +8683,7 @@ class LayerTreeHostTestImageAnimationSynchronousSchedulingSoftwareDraw
void InitializeSettings(LayerTreeSettings* settings) override {
LayerTreeHostTestImageAnimationSynchronousScheduling::InitializeSettings(
settings);
- use_software_renderer_ = true;
+ renderer_type_ = RENDERER_SOFTWARE;
}
void AfterTest() override {
@@ -8732,11 +8759,11 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestImageDecodingHints);
class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest {
public:
- LayerTreeHostTestCheckerboardUkm() : url_(GURL("https://example.com")) {}
-
+ LayerTreeHostTestCheckerboardUkm() : url_(GURL("https://example.com")),
+ ukm_source_id_(123) {}
void BeginTest() override {
PostSetNeedsCommitToMainThread();
- layer_tree_host()->SetURLForUkm(url_);
+ layer_tree_host()->SetSourceURL(ukm_source_id_, url_);
}
void SetupTree() override {
@@ -8772,6 +8799,9 @@ class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest {
auto* recorder = static_cast<ukm::TestUkmRecorder*>(
impl->ukm_manager()->recorder_for_testing());
+ // Tie the source id to the URL. In production, this is already done in
+ // Document, and the source id is passed down to cc.
+ recorder->UpdateSourceURL(ukm_source_id_, url_);
const auto& entries = recorder->GetEntriesByName(kUserInteraction);
EXPECT_EQ(1u, entries.size());
@@ -8789,6 +8819,7 @@ class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest {
private:
const GURL url_;
+ const ukm::SourceId ukm_source_id_;
FakeContentLayerClient content_layer_client_;
};
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
index 6cd39fc0b0d..47a27fd67c8 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1537,9 +1537,11 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
EXPECT_FALSE(animation_->keyframe_effect()
->element_animations()
->has_element_in_pending_list());
- EXPECT_FALSE(animation_host()->NeedsTickAnimations());
+ // Animations still need one more tick to deliver finished event.
+ EXPECT_TRUE(animation_host()->NeedsTickAnimations());
break;
case 2:
+ EXPECT_FALSE(animation_host()->NeedsTickAnimations());
layer_tree_host()->root_layer()->AddChild(layer_);
EXPECT_TRUE(animation_->keyframe_effect()
->element_animations()
@@ -1570,6 +1572,8 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
EXPECT_FALSE(animation_impl->keyframe_effect()
->element_animations()
->has_element_in_active_list());
+ // Having updated state on the host_impl during the commit, we no longer
+ // need to tick animations.
EXPECT_FALSE(GetImplAnimationHost(host_impl)->NeedsTickAnimations());
break;
case 2:
diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
index 929c6658fe8..5ad5e2a6977 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
@@ -20,20 +20,26 @@ const char kCheckerboardImagesMetric[] = "CheckerboardedImagesCount";
class LayerTreeHostCheckerImagingTest : public LayerTreeTest {
public:
- LayerTreeHostCheckerImagingTest() : url_(GURL("https://example.com")) {}
+ LayerTreeHostCheckerImagingTest() : url_(GURL("https://example.com")),
+ ukm_source_id_(123) {}
void BeginTest() override {
- layer_tree_host()->SetURLForUkm(url_);
+ layer_tree_host()->SetSourceURL(ukm_source_id_, url_);
PostSetNeedsCommitToMainThread();
}
void AfterTest() override {}
void VerifyUkmAndEndTest(LayerTreeHostImpl* impl) {
- // Change the URL to ensure any accumulated metrics are flushed.
- impl->ukm_manager()->SetSourceURL(GURL("chrome://test2"));
-
auto* recorder = static_cast<ukm::TestUkmRecorder*>(
impl->ukm_manager()->recorder_for_testing());
+ // Tie the source id to the URL. In production, this is already done in
+ // Document, and the source id is passed down to cc.
+ recorder->UpdateSourceURL(ukm_source_id_, url_);
+
+ // Change the source to ensure any accumulated metrics are flushed.
+ impl->ukm_manager()->SetSourceId(200);
+ recorder->UpdateSourceURL(200, GURL("chrome://test2"));
+
const auto& entries = recorder->GetEntriesByName(kRenderingEvent);
ASSERT_EQ(1u, entries.size());
auto* entry = entries[0];
@@ -76,6 +82,9 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest {
// Accessed only on the main thread.
FakeContentLayerClient content_layer_client_;
GURL url_;
+
+ // Accessed on the impl thread.
+ const ukm::SourceId ukm_source_id_;
};
class LayerTreeHostCheckerImagingTestMergeWithMainFrame
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index 1f0663462d7..a06f23dc57f 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -934,8 +934,10 @@ class LayerTreeHostContextTestDontUseLostResources
TextureLayer::CreateForMailbox(nullptr);
texture->SetBounds(gfx::Size(10, 10));
texture->SetIsDrawable(true);
+ constexpr gfx::Size size(64, 64);
auto resource = viz::TransferableResource::MakeGL(
- mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token);
+ mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token, size,
+ false /* is_overlay_candidate */);
texture->SetTransferableResource(
resource, viz::SingleReleaseCallback::Create(base::BindOnce(
&LayerTreeHostContextTestDontUseLostResources::
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index cad1e7288bd..5bac6e88f25 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -18,6 +18,7 @@
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/service/display/direct_renderer.h"
#include "components/viz/test/fake_output_surface.h"
+#include "components/viz/test/fake_skia_output_surface.h"
#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -25,9 +26,24 @@
namespace cc {
namespace {
-// These tests only use direct rendering, as there is no output to copy for
-// delegated renderers.
-class LayerTreeHostCopyRequestTest : public LayerTreeTest {};
+auto CombineWithCompositorModes(
+ const std::vector<LayerTreeTest::RendererType>& types) {
+ return ::testing::Combine(::testing::ValuesIn(types),
+ ::testing::Values(CompositorMode::SINGLE_THREADED,
+ CompositorMode::THREADED));
+}
+
+class LayerTreeHostCopyRequestTest
+ : public LayerTreeTest,
+ public ::testing::WithParamInterface<
+ ::testing::tuple<LayerTreeTest::RendererType, CompositorMode>> {
+ public:
+ RendererType renderer_type() const { return ::testing::get<0>(GetParam()); }
+
+ CompositorMode compositor_mode() const {
+ return ::testing::get<1>(GetParam());
+ }
+};
class LayerTreeHostCopyRequestTestMultipleRequests
: public LayerTreeHostCopyRequestTest {
@@ -136,27 +152,6 @@ class LayerTreeHostCopyRequestTestMultipleRequests
void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); }
- std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
- scoped_refptr<viz::ContextProvider> compositor_context_provider)
- override {
- if (!use_gl_renderer_) {
- return viz::FakeOutputSurface::CreateSoftware(
- std::make_unique<viz::SoftwareOutputDevice>());
- }
-
- scoped_refptr<viz::TestContextProvider> display_context_provider =
- viz::TestContextProvider::Create();
- viz::TestContextSupport* context_support =
- display_context_provider->support();
- context_support->set_out_of_order_callbacks(out_of_order_callbacks_);
- display_context_provider->BindToCurrentThread();
-
- return viz::FakeOutputSurface::Create3d(
- std::move(display_context_provider));
- }
-
- bool use_gl_renderer_;
- bool out_of_order_callbacks_ = false;
std::map<size_t, gfx::Size> callbacks_;
FakeContentLayerClient client_;
scoped_refptr<FakePictureLayer> root;
@@ -164,72 +159,52 @@ class LayerTreeHostCopyRequestTestMultipleRequests
scoped_refptr<FakePictureLayer> grand_child;
};
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- GLRenderer_RunSingleThread) {
- use_gl_renderer_ = true;
- RunTest(CompositorMode::SINGLE_THREADED);
-}
-
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- GLRenderer_RunMultiThread) {
- use_gl_renderer_ = true;
- RunTest(CompositorMode::THREADED);
-}
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestMultipleRequests,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+ LayerTreeTest::RENDERER_SOFTWARE}));
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- GLRenderer_RunSingleThread_OutOfOrderCallbacks) {
- use_gl_renderer_ = true;
- out_of_order_callbacks_ = true;
- RunTest(CompositorMode::SINGLE_THREADED);
+TEST_P(LayerTreeHostCopyRequestTestMultipleRequests, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
}
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- GLRenderer_RunMultiThread_OutOfOrderCallbacks) {
- use_gl_renderer_ = true;
- out_of_order_callbacks_ = true;
- RunTest(CompositorMode::THREADED);
-}
-
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- SkiaRenderer_RunSingleThread) {
- use_gl_renderer_ = true;
- use_skia_renderer_ = true;
- RunTest(CompositorMode::SINGLE_THREADED);
-}
-
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- SkiaRenderer_RunMultiThread) {
- use_gl_renderer_ = true;
- use_skia_renderer_ = true;
- RunTest(CompositorMode::THREADED);
-}
+// These tests run with |out_of_order_callbacks_| set on the TestContextSupport,
+// which causes callbacks for sync queries to be sent in reverse order.
+class LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder
+ : public LayerTreeHostCopyRequestTestMultipleRequests {
+ std::unique_ptr<viz::SkiaOutputSurface>
+ CreateDisplaySkiaOutputSurfaceOnThread() override {
+ auto skia_output_surface = viz::FakeSkiaOutputSurface::Create3d();
+ skia_output_surface->SetOutOfOrderCallbacks(true);
+ return skia_output_surface;
+ }
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- SkiaRenderer_RunSingleThread_OutOfOrderCallbacks) {
- use_gl_renderer_ = true;
- use_skia_renderer_ = true;
- out_of_order_callbacks_ = true;
- RunTest(CompositorMode::SINGLE_THREADED);
-}
+ std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
+ scoped_refptr<viz::ContextProvider> compositor_context_provider)
+ override {
+ // Since this test does not override CreateLayerTreeFrameSink, the
+ // |compositor_context_provider| will be a viz::TestContextProvider.
+ auto* context_support = static_cast<viz::TestContextSupport*>(
+ compositor_context_provider->ContextSupport());
+ context_support->set_out_of_order_callbacks(true);
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- SkiaRenderer_RunMultiThread_OutOfOrderCallbacks) {
- use_gl_renderer_ = true;
- use_skia_renderer_ = true;
- out_of_order_callbacks_ = true;
- RunTest(CompositorMode::THREADED);
-}
+ return viz::FakeOutputSurface::Create3d(
+ std::move(compositor_context_provider));
+ }
+};
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- SoftwareRenderer_RunSingleThread) {
- use_gl_renderer_ = false;
- RunTest(CompositorMode::SINGLE_THREADED);
-}
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
-TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- SoftwareRenderer_RunMultiThread) {
- use_gl_renderer_ = false;
- RunTest(CompositorMode::THREADED);
+TEST_P(LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
}
// TODO(crbug.com/564832): Remove this test when the workaround it tests is no
@@ -285,7 +260,16 @@ class LayerTreeHostCopyRequestCompletionCausesCommit
scoped_refptr<FakePictureLayer> layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestCompletionCausesCommit);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestCompletionCausesCommit,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestCompletionCausesCommit, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestLayerDestroyed
: public LayerTreeHostCopyRequestTest {
@@ -332,7 +316,7 @@ class LayerTreeHostCopyRequestTestLayerDestroyed
// Destroy the main thread layer right away.
main_destroyed_->RemoveFromParent();
- main_destroyed_ = nullptr;
+ main_destroyed_.reset();
// Should callback with a NULL bitmap.
EXPECT_EQ(1, callback_count_);
@@ -351,7 +335,7 @@ class LayerTreeHostCopyRequestTestLayerDestroyed
// Destroy the impl thread layer.
impl_destroyed_->RemoveFromParent();
- impl_destroyed_ = nullptr;
+ impl_destroyed_.reset();
// No callback yet because it's on the impl side.
EXPECT_EQ(1, callback_count_);
@@ -383,7 +367,16 @@ class LayerTreeHostCopyRequestTestLayerDestroyed
scoped_refptr<FakePictureLayer> impl_destroyed_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestLayerDestroyed,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestLayerDestroyed, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestInHiddenSubtree
: public LayerTreeHostCopyRequestTest {
@@ -483,7 +476,16 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree
scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestInHiddenSubtree);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestInHiddenSubtree,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestInHiddenSubtree, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
: public LayerTreeHostCopyRequestTest {
@@ -596,8 +598,16 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestClippedOut
: public LayerTreeHostCopyRequestTest {
@@ -647,7 +657,16 @@ class LayerTreeHostCopyRequestTestClippedOut
scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestClippedOut);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestClippedOut,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestClippedOut, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestScaledLayer
: public LayerTreeHostCopyRequestTest {
@@ -705,7 +724,16 @@ class LayerTreeHostCopyRequestTestScaledLayer
scoped_refptr<FakePictureLayer> child_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestScaledLayer);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestScaledLayer,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestScaledLayer, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
: public LayerTreeHostCopyRequestTest {
@@ -791,17 +819,36 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostTestAsyncTwoReadbacksWithoutDraw,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostTestAsyncTwoReadbacksWithoutDraw, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestDeleteSharedImage
: public LayerTreeHostCopyRequestTest {
protected:
+ std::unique_ptr<viz::SkiaOutputSurface>
+ CreateDisplaySkiaOutputSurfaceOnThread() override {
+ display_context_provider_ = viz::TestContextProvider::Create();
+ display_context_provider_->BindToCurrentThread();
+ return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
+ }
+
std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
scoped_refptr<viz::ContextProvider> compositor_context_provider)
override {
- display_context_provider_ = viz::TestContextProvider::Create();
- display_context_provider_->BindToCurrentThread();
- return viz::FakeOutputSurface::Create3d(display_context_provider_);
+ // Since this test does not override CreateLayerTreeFrameSink, the
+ // |compositor_context_provider| will be a viz::TestContextProvider.
+ display_context_provider_ = static_cast<viz::TestContextProvider*>(
+ compositor_context_provider.get());
+ return viz::FakeOutputSurface::Create3d(
+ std::move(compositor_context_provider));
}
void SetupTree() override {
@@ -844,7 +891,7 @@ class LayerTreeHostCopyRequestTestDeleteSharedImage
void DestroyCopyResultAndCheckNumSharedImages() {
EXPECT_TRUE(result_);
- result_ = nullptr;
+ result_.reset();
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
@@ -863,7 +910,7 @@ class LayerTreeHostCopyRequestTestDeleteSharedImage
->shared_image_count());
// Drop the reference to the context provider on the compositor thread.
- display_context_provider_ = nullptr;
+ display_context_provider_.reset();
EndTest();
}
@@ -918,11 +965,27 @@ class LayerTreeHostCopyRequestTestDeleteSharedImage
std::unique_ptr<viz::CopyOutputResult> result_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestDeleteSharedImage);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestDeleteSharedImage,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestDeleteSharedImage, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestCountSharedImages
: public LayerTreeHostCopyRequestTest {
protected:
+ std::unique_ptr<viz::SkiaOutputSurface>
+ CreateDisplaySkiaOutputSurfaceOnThread() override {
+ display_context_provider_ = viz::TestContextProvider::Create();
+ display_context_provider_->BindToCurrentThread();
+ return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
+ }
+
std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
scoped_refptr<viz::ContextProvider> compositor_context_provider)
override {
@@ -999,7 +1062,13 @@ class LayerTreeHostCopyRequestTestCountSharedImages
}
}
- virtual void DoEndTest() { EndTest(); }
+ virtual void DoEndTest() {
+ // Drop the reference to the context provider on the main thread. If the
+ // reference is dropped during the test destructor, then there will be a
+ // DCHECK in ~TestContextProvider() for some cases.
+ display_context_provider_.reset();
+ EndTest();
+ }
scoped_refptr<viz::TestContextProvider> display_context_provider_;
int num_swaps_ = 0;
@@ -1042,7 +1111,16 @@ class LayerTreeHostCopyRequestTestCreatesSharedImage
std::unique_ptr<viz::SingleReleaseCallback> release_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestCreatesSharedImage);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestCreatesSharedImage,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestCreatesSharedImage, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestDestroyBeforeCopy
: public LayerTreeHostCopyRequestTest {
@@ -1123,7 +1201,16 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy
scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestDestroyBeforeCopy);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestDestroyBeforeCopy,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestDestroyBeforeCopy, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestShutdownBeforeCopy
: public LayerTreeHostCopyRequestTest {
@@ -1198,7 +1285,16 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy
scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestShutdownBeforeCopy);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestShutdownBeforeCopy,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestShutdownBeforeCopy, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
: public LayerTreeHostCopyRequestTest {
@@ -1324,8 +1420,16 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
bool draw_happened_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest);
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest,
+ CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL}));
+
+TEST_P(LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest, Test) {
+ renderer_type_ = renderer_type();
+ RunTest(compositor_mode());
+}
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
index d0dfd9b9ba7..b0a8b0c9ac2 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
@@ -77,10 +77,10 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
EXPECT_EQ(2u, root_pass->quad_list.size());
// There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
root_pass->quad_list.back()->material);
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ EXPECT_EQ(viz::DrawQuad::Material::kRenderPass,
root_pass->quad_list.front()->material);
const viz::RenderPassDrawQuad* render_pass_quad =
viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
@@ -209,11 +209,11 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
EXPECT_EQ(2u, root_pass->quad_list.size());
// There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
root_pass->quad_list.back()->material);
// The surface is clipped to 10x20.
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ EXPECT_EQ(viz::DrawQuad::Material::kRenderPass,
root_pass->quad_list.front()->material);
const viz::RenderPassDrawQuad* render_pass_quad =
viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
@@ -355,12 +355,12 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale
EXPECT_EQ(2u, root_pass->quad_list.size());
// There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
root_pass->quad_list.back()->material);
// The surface is clipped to 10x20, and then scaled by 2, which ends up
// being 20x40.
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ EXPECT_EQ(viz::DrawQuad::Material::kRenderPass,
root_pass->quad_list.front()->material);
const viz::RenderPassDrawQuad* render_pass_quad =
viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
@@ -488,10 +488,10 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
EXPECT_EQ(2u, root_pass->quad_list.size());
// There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
root_pass->quad_list.back()->material);
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ EXPECT_EQ(viz::DrawQuad::Material::kRenderPass,
root_pass->quad_list.front()->material);
const viz::RenderPassDrawQuad* render_pass_quad =
viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
@@ -619,11 +619,11 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest {
EXPECT_EQ(2u, root_pass->quad_list.size());
// There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ EXPECT_EQ(viz::DrawQuad::Material::kSolidColor,
root_pass->quad_list.back()->material);
// The surface is 100x100
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ EXPECT_EQ(viz::DrawQuad::Material::kRenderPass,
root_pass->quad_list.front()->material);
const viz::RenderPassDrawQuad* render_pass_quad =
viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index 8202fa00798..fbd783c9798 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -619,35 +619,13 @@ LayerImplList::reverse_iterator LayerTreeImpl::rend() {
}
bool LayerTreeImpl::IsElementInPropertyTree(ElementId element_id) const {
- return elements_in_property_trees_.count(element_id);
+ return property_trees()->HasElement(element_id);
}
ElementListType LayerTreeImpl::GetElementTypeForAnimation() const {
return IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
}
-void LayerTreeImpl::AddToElementPropertyTreeList(ElementId element_id) {
-#if DCHECK_IS_ON()
- bool element_id_collision_detected =
- elements_in_property_trees_.count(element_id);
-
- DCHECK(!element_id_collision_detected);
-#endif
-
- elements_in_property_trees_.insert(element_id);
-
- DCHECK(settings().use_layer_lists);
- host_impl_->mutator_host()->RegisterElement(element_id,
- GetElementTypeForAnimation());
-}
-
-void LayerTreeImpl::RemoveFromElementPropertyTreeList(ElementId element_id) {
- DCHECK(settings().use_layer_lists);
- host_impl_->mutator_host()->UnregisterElement(element_id,
- GetElementTypeForAnimation());
- elements_in_property_trees_.erase(element_id);
-}
-
void LayerTreeImpl::AddToElementLayerList(ElementId element_id,
LayerImpl* layer) {
if (!element_id)
@@ -658,9 +636,8 @@ void LayerTreeImpl::AddToElementLayerList(ElementId element_id,
element_id.AsValue().release());
if (!settings().use_layer_lists) {
- elements_in_property_trees_.insert(element_id);
- host_impl_->mutator_host()->RegisterElement(element_id,
- GetElementTypeForAnimation());
+ host_impl_->mutator_host()->RegisterElementId(element_id,
+ GetElementTypeForAnimation());
}
if (layer->scrollable())
@@ -676,9 +653,8 @@ void LayerTreeImpl::RemoveFromElementLayerList(ElementId element_id) {
element_id.AsValue().release());
if (!settings().use_layer_lists) {
- elements_in_property_trees_.erase(element_id);
- host_impl_->mutator_host()->UnregisterElement(element_id,
- GetElementTypeForAnimation());
+ host_impl_->mutator_host()->UnregisterElementId(
+ element_id, GetElementTypeForAnimation());
}
element_id_to_scrollable_layer_.erase(element_id);
@@ -726,6 +702,18 @@ void LayerTreeImpl::SetFilterMutated(ElementId element_id,
set_needs_update_draw_properties();
}
+void LayerTreeImpl::SetBackdropFilterMutated(
+ ElementId element_id,
+ const FilterOperations& backdrop_filters) {
+ DCHECK_EQ(
+ 1u, property_trees()->element_id_to_effect_node_index.count(element_id));
+ if (IsSyncTree() || IsRecycleTree())
+ element_id_to_backdrop_filter_animations_[element_id] = backdrop_filters;
+ if (property_trees()->effect_tree.OnBackdropFilterAnimated(element_id,
+ backdrop_filters))
+ set_needs_update_draw_properties();
+}
+
void LayerTreeImpl::AddPresentationCallbacks(
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks) {
std::copy(std::make_move_iterator(callbacks.begin()),
@@ -827,6 +815,23 @@ void LayerTreeImpl::UpdatePropertyTreeAnimationFromMainThread() {
++element_id_to_filter;
}
+ auto element_id_to_backdrop_filter =
+ element_id_to_backdrop_filter_animations_.begin();
+ while (element_id_to_backdrop_filter !=
+ element_id_to_backdrop_filter_animations_.end()) {
+ const ElementId id = element_id_to_backdrop_filter->first;
+ EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id);
+ if (!node || !node->is_currently_animating_backdrop_filter ||
+ node->backdrop_filters == element_id_to_backdrop_filter->second) {
+ element_id_to_backdrop_filter_animations_.erase(
+ element_id_to_backdrop_filter++);
+ continue;
+ }
+ node->backdrop_filters = element_id_to_backdrop_filter->second;
+ property_trees_.effect_tree.set_needs_update(true);
+ ++element_id_to_backdrop_filter;
+ }
+
auto element_id_to_transform = element_id_to_transform_animations_.begin();
while (element_id_to_transform != element_id_to_transform_animations_.end()) {
const ElementId id = element_id_to_transform->first;
@@ -861,10 +866,9 @@ void LayerTreeImpl::UpdateTransformAnimation(ElementId element_id,
list_type);
if (node->has_potential_animation != has_potential_animation) {
node->has_potential_animation = has_potential_animation;
- node->maximum_animation_scale =
- mutator_host()->MaximumTargetScale(element_id, list_type);
- node->starting_animation_scale =
- mutator_host()->AnimationStartScale(element_id, list_type);
+ mutator_host()->GetAnimationScales(element_id, list_type,
+ &node->maximum_animation_scale,
+ &node->starting_animation_scale);
transform_tree.set_needs_update(true);
set_needs_update_draw_properties();
}
@@ -1084,8 +1088,6 @@ void LayerTreeImpl::SetLocalSurfaceIdAllocationFromParent(
local_surface_id_allocation_from_parent) {
local_surface_id_allocation_from_parent_ =
local_surface_id_allocation_from_parent;
- if (IsActiveTree())
- host_impl_->OnLayerTreeLocalSurfaceIdAllocationChanged();
}
void LayerTreeImpl::RequestNewLocalSurfaceId() {
@@ -1422,6 +1424,7 @@ void LayerTreeImpl::BuildPropertyTreesForTesting() {
gfx::Rect(GetDeviceViewport().size()), host_impl_->DrawTransform(),
&property_trees_);
property_trees_.transform_tree.set_source_to_parent_updates_allowed(false);
+ host_impl_->UpdateElements(GetElementTypeForAnimation());
}
const RenderSurfaceList& LayerTreeImpl::GetRenderSurfaceList() const {
@@ -1755,8 +1758,15 @@ void LayerTreeImpl::QueuePinnedSwapPromise(
void LayerTreeImpl::PassSwapPromises(
std::vector<std::unique_ptr<SwapPromise>> new_swap_promises) {
- for (auto& swap_promise : swap_promise_list_)
- swap_promise->DidNotSwap(SwapPromise::SWAP_FAILS);
+ for (auto& swap_promise : swap_promise_list_) {
+ if (swap_promise->DidNotSwap(SwapPromise::SWAP_FAILS) ==
+ SwapPromise::DidNotSwapAction::KEEP_ACTIVE) {
+ // |swap_promise| must remain active, so place it in |new_swap_promises|
+ // in order to keep it alive and active.
+ new_swap_promises.push_back(std::move(swap_promise));
+ }
+ }
+ swap_promise_list_.clear();
swap_promise_list_.swap(new_swap_promises);
}
@@ -1784,13 +1794,30 @@ void LayerTreeImpl::ClearSwapPromises() {
}
void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
- for (auto& swap_promise : swap_promise_list_)
- swap_promise->DidNotSwap(reason);
- swap_promise_list_.clear();
+ {
+ std::vector<std::unique_ptr<SwapPromise>> persistent_swap_promises;
+ for (auto& swap_promise : swap_promise_list_) {
+ if (swap_promise->DidNotSwap(reason) ==
+ SwapPromise::DidNotSwapAction::KEEP_ACTIVE) {
+ persistent_swap_promises.push_back(std::move(swap_promise));
+ }
+ }
+ // |persistent_swap_promises| must remain active even when swap fails.
+ swap_promise_list_ = std::move(persistent_swap_promises);
+ }
- for (auto& swap_promise : pinned_swap_promise_list_)
- swap_promise->DidNotSwap(reason);
- pinned_swap_promise_list_.clear();
+ {
+ std::vector<std::unique_ptr<SwapPromise>> persistent_swap_promises;
+ for (auto& swap_promise : pinned_swap_promise_list_) {
+ if (swap_promise->DidNotSwap(reason) ==
+ SwapPromise::DidNotSwapAction::KEEP_ACTIVE) {
+ persistent_swap_promises.push_back(std::move(swap_promise));
+ }
+ }
+
+ // |persistent_swap_promises| must remain active even when swap fails.
+ pinned_swap_promise_list_ = std::move(persistent_swap_promises);
+ }
}
void LayerTreeImpl::DidModifyTilePriorities() {
@@ -2114,9 +2141,10 @@ static void FindClosestMatchingLayer(const gfx::PointF& screen_space_point,
}
}
-struct FindScrollingLayerOrScrollbarFunctor {
+struct HitTestScrollingLayerOrScrollbarFunctor {
bool operator()(LayerImpl* layer) const {
- return layer->scrollable() || layer->is_scrollbar();
+ return layer->HitTestable() &&
+ (layer->scrollable() || layer->is_scrollbar());
}
};
@@ -2128,7 +2156,7 @@ LayerImpl* LayerTreeImpl::FindFirstScrollingLayerOrScrollbarThatIsHitByPoint(
FindClosestMatchingLayerState state;
LayerImpl* root_layer = layer_list_[0];
FindClosestMatchingLayer(screen_space_point, root_layer,
- FindScrollingLayerOrScrollbarFunctor(), &state);
+ HitTestScrollingLayerOrScrollbarFunctor(), &state);
return state.closest_match;
}
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 88d798bce13..21f3f87674a 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -183,7 +183,6 @@ class CC_EXPORT LayerTreeImpl {
void PushPropertyTreesTo(LayerTreeImpl* tree_impl);
void PushPropertiesTo(LayerTreeImpl* tree_impl);
void PushSurfaceRangesTo(LayerTreeImpl* tree_impl);
- void PushRegisteredElementIdsTo(LayerTreeImpl* tree_impl);
void MoveChangeTrackingToLayers();
@@ -200,6 +199,8 @@ class CC_EXPORT LayerTreeImpl {
const gfx::Transform& transform);
void SetOpacityMutated(ElementId element_id, float opacity);
void SetFilterMutated(ElementId element_id, const FilterOperations& filters);
+ void SetBackdropFilterMutated(ElementId element_id,
+ const FilterOperations& backdrop_filters);
const std::unordered_map<ElementId, float, ElementIdHash>&
element_id_to_opacity_animations_for_testing() const {
@@ -213,6 +214,10 @@ class CC_EXPORT LayerTreeImpl {
element_id_to_filter_animations_for_testing() const {
return element_id_to_filter_animations_;
}
+ const std::unordered_map<ElementId, FilterOperations, ElementIdHash>&
+ element_id_to_backdrop_filter_animations_for_testing() const {
+ return element_id_to_backdrop_filter_animations_;
+ }
int source_frame_number() const { return source_frame_number_; }
void set_source_frame_number(int frame_number) {
@@ -645,11 +650,6 @@ class CC_EXPORT LayerTreeImpl {
LayerTreeLifecycle& lifecycle() { return lifecycle_; }
- const std::unordered_set<ElementId, ElementIdHash>&
- elements_in_property_trees() {
- return elements_in_property_trees_;
- }
-
std::string LayerListAsJson() const;
// TODO(pdr): This should be removed because there is no longer a tree
// of layers, only a list.
@@ -722,15 +722,14 @@ class CC_EXPORT LayerTreeImpl {
// Set of layers that need to push properties.
base::flat_set<LayerImpl*> layers_that_should_push_properties_;
- // Set of ElementIds which are present in the |layer_list_|.
- std::unordered_set<ElementId, ElementIdHash> elements_in_property_trees_;
-
std::unordered_map<ElementId, float, ElementIdHash>
element_id_to_opacity_animations_;
std::unordered_map<ElementId, gfx::Transform, ElementIdHash>
element_id_to_transform_animations_;
std::unordered_map<ElementId, FilterOperations, ElementIdHash>
element_id_to_filter_animations_;
+ std::unordered_map<ElementId, FilterOperations, ElementIdHash>
+ element_id_to_backdrop_filter_animations_;
std::unordered_map<ElementId, LayerImpl*, ElementIdHash>
element_id_to_scrollable_layer_;
diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc
index e703093d5b4..4dc46346a58 100644
--- a/chromium/cc/trees/layer_tree_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_impl_unittest.cc
@@ -2362,16 +2362,39 @@ TEST_F(LayerTreeImplTest, ScrollSizeWithoutLayers) {
namespace {
-class StubSwapPromise : public SwapPromise,
- public base::SupportsWeakPtr<StubSwapPromise> {
+class PersistentSwapPromise
+ : public SwapPromise,
+ public base::SupportsWeakPtr<PersistentSwapPromise> {
public:
- StubSwapPromise() = default;
- ~StubSwapPromise() override = default;
+ PersistentSwapPromise() = default;
+ ~PersistentSwapPromise() override = default;
+
+ void DidActivate() override {}
+ MOCK_METHOD1(WillSwap, void(viz::CompositorFrameMetadata* metadata));
+ MOCK_METHOD0(DidSwap, void());
+
+ DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
+ return DidNotSwapAction::KEEP_ACTIVE;
+ }
+
+ void OnCommit() override {}
+ int64_t TraceId() const override { return 0; }
+};
+
+class NotPersistentSwapPromise
+ : public SwapPromise,
+ public base::SupportsWeakPtr<NotPersistentSwapPromise> {
+ public:
+ NotPersistentSwapPromise() = default;
+ ~NotPersistentSwapPromise() override = default;
void DidActivate() override {}
void WillSwap(viz::CompositorFrameMetadata* metadata) override {}
void DidSwap() override {}
- void DidNotSwap(DidNotSwapReason reason) override {}
+
+ DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
+ return DidNotSwapAction::BREAK_PROMISE;
+ }
void OnCommit() override {}
int64_t TraceId() const override { return 0; }
@@ -2379,31 +2402,64 @@ class StubSwapPromise : public SwapPromise,
} // namespace
-TEST_F(LayerTreeImplTest, StubSwapPromisesAreDroppedWhenSwapFails) {
+TEST_F(LayerTreeImplTest, PersistentSwapPromisesAreKeptAlive) {
+ const size_t promises_count = 2;
+
+ std::vector<base::WeakPtr<PersistentSwapPromise>> persistent_promises;
+ std::vector<std::unique_ptr<PersistentSwapPromise>>
+ persistent_promises_to_pass;
+ for (size_t i = 0; i < promises_count; ++i) {
+ persistent_promises_to_pass.push_back(
+ std::make_unique<PersistentSwapPromise>());
+ }
+
+ for (auto& promise : persistent_promises_to_pass) {
+ persistent_promises.push_back(promise->AsWeakPtr());
+ host_impl().active_tree()->QueueSwapPromise(std::move(promise));
+ }
+
+ std::vector<std::unique_ptr<SwapPromise>> promises;
+ host_impl().active_tree()->PassSwapPromises(std::move(promises));
+ host_impl().active_tree()->BreakSwapPromises(
+ SwapPromise::DidNotSwapReason::SWAP_FAILS);
+
+ ASSERT_EQ(promises_count, persistent_promises.size());
+ for (size_t i = 0; i < persistent_promises.size(); ++i) {
+ SCOPED_TRACE(testing::Message() << "While checking case #" << i);
+ ASSERT_TRUE(persistent_promises[i]);
+ EXPECT_CALL(*persistent_promises[i], WillSwap(testing::_));
+ }
+ host_impl().active_tree()->FinishSwapPromises(nullptr);
+}
+
+TEST_F(LayerTreeImplTest, NotPersistentSwapPromisesAreDroppedWhenSwapFails) {
const size_t promises_count = 2;
- std::vector<base::WeakPtr<StubSwapPromise>> weak_swap_promises;
- std::vector<std::unique_ptr<StubSwapPromise>> swap_promises_to_pass;
+ std::vector<base::WeakPtr<NotPersistentSwapPromise>> not_persistent_promises;
+ std::vector<std::unique_ptr<NotPersistentSwapPromise>>
+ not_persistent_promises_to_pass;
for (size_t i = 0; i < promises_count; ++i) {
- swap_promises_to_pass.push_back(std::make_unique<StubSwapPromise>());
+ not_persistent_promises_to_pass.push_back(
+ std::make_unique<NotPersistentSwapPromise>());
}
- for (auto& promise : swap_promises_to_pass) {
- weak_swap_promises.push_back(promise->AsWeakPtr());
+ for (auto& promise : not_persistent_promises_to_pass) {
+ not_persistent_promises.push_back(promise->AsWeakPtr());
host_impl().active_tree()->QueueSwapPromise(std::move(promise));
}
std::vector<std::unique_ptr<SwapPromise>> promises;
host_impl().active_tree()->PassSwapPromises(std::move(promises));
- ASSERT_EQ(promises_count, weak_swap_promises.size());
- for (size_t i = 0; i < weak_swap_promises.size(); ++i) {
- EXPECT_FALSE(weak_swap_promises[i]) << "While checking case #" << i;
+ ASSERT_EQ(promises_count, not_persistent_promises.size());
+ for (size_t i = 0; i < not_persistent_promises.size(); ++i) {
+ EXPECT_FALSE(not_persistent_promises[i]) << "While checking case #" << i;
}
- // Finally, check that the promises do not survive
+ // Finally, check that not persistent promise doesn't survive
// |LayerTreeImpl::BreakSwapPromises|.
{
- std::unique_ptr<StubSwapPromise> promise(new StubSwapPromise());
+ std::unique_ptr<NotPersistentSwapPromise> promise(
+ new NotPersistentSwapPromise());
auto weak_promise = promise->AsWeakPtr();
host_impl().active_tree()->QueueSwapPromise(std::move(promise));
host_impl().active_tree()->BreakSwapPromises(
diff --git a/chromium/cc/trees/layer_tree_mutator.cc b/chromium/cc/trees/layer_tree_mutator.cc
index 15d2b6aebb2..9e285596b4a 100644
--- a/chromium/cc/trees/layer_tree_mutator.cc
+++ b/chromium/cc/trees/layer_tree_mutator.cc
@@ -13,12 +13,12 @@ AnimationWorkletInput::AddAndUpdateState::AddAndUpdateState(
std::string name,
double current_time,
std::unique_ptr<AnimationOptions> options,
- int num_effects)
+ std::unique_ptr<AnimationEffectTimings> effect_timings)
: worklet_animation_id(worklet_animation_id),
name(name),
current_time(current_time),
options(std::move(options)),
- num_effects(num_effects) {}
+ effect_timings(std::move(effect_timings)) {}
AnimationWorkletInput::AddAndUpdateState::AddAndUpdateState(
AddAndUpdateState&&) = default;
AnimationWorkletInput::AddAndUpdateState::~AddAndUpdateState() = default;
diff --git a/chromium/cc/trees/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h
index fd5956c21fa..ff1c32579c6 100644
--- a/chromium/cc/trees/layer_tree_mutator.h
+++ b/chromium/cc/trees/layer_tree_mutator.h
@@ -9,6 +9,7 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "cc/cc_export.h"
+#include "cc/trees/animation_effect_timings.h"
#include "cc/trees/animation_options.h"
#include <memory>
@@ -64,13 +65,13 @@ struct CC_EXPORT AnimationWorkletInput {
// Worklet animation's current time, from its associated timeline.
double current_time;
std::unique_ptr<AnimationOptions> options;
- int num_effects;
+ std::unique_ptr<AnimationEffectTimings> effect_timings;
AddAndUpdateState(WorkletAnimationId worklet_animation_id,
std::string name,
double current_time,
std::unique_ptr<AnimationOptions> options,
- int num_effects);
+ std::unique_ptr<AnimationEffectTimings> effect_timings);
AddAndUpdateState(AddAndUpdateState&&);
~AddAndUpdateState();
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 644305bc425..092fb1b7ea3 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -172,11 +172,6 @@ class CC_EXPORT LayerTreeSettings {
// go away and CC should send Blink fractional values:
// https://crbug.com/414283.
bool commit_fractional_scroll_deltas = false;
-
- // If true, LayerTreeHostImpl automatically allocates LocalSurfaceIds as
- // necessary. If false, it is clients generate LocalSurfaceIds as necessary.
- // TODO(sky): remove this once https://crbug.com/921129 is fixed.
- bool automatically_allocate_surface_ids = true;
};
} // namespace cc
diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h
index 377579edb91..03e3ce4d4a0 100644
--- a/chromium/cc/trees/mutator_host.h
+++ b/chromium/cc/trees/mutator_host.h
@@ -26,9 +26,8 @@ class MutatorHostClient;
class LayerTreeMutator;
class ScrollTree;
-// Used as the return value of MaximumTargetScale() and AnimationStartScale() to
-// indicate that there is no active scale animation or the scale cannot be
-// computed.
+// Used as the return value of GetAnimationScales() to indicate that there is
+// no active scale animation or the scale cannot be computed.
const float kNotScaled = 0;
// A MutatorHost owns all the animation and mutation effects.
@@ -47,12 +46,13 @@ class MutatorHost {
virtual void ClearMutators() = 0;
+ virtual void UpdateRegisteredElementIds(ElementListType changed_list) = 0;
virtual void InitClientAnimationState() = 0;
- virtual void RegisterElement(ElementId element_id,
- ElementListType list_type) = 0;
- virtual void UnregisterElement(ElementId element_id,
+ virtual void RegisterElementId(ElementId element_id,
ElementListType list_type) = 0;
+ virtual void UnregisterElementId(ElementId element_id,
+ ElementListType list_type) = 0;
virtual void SetMutatorHostClient(MutatorHostClient* client) = 0;
@@ -66,7 +66,7 @@ class MutatorHost {
base::TimeDelta duration) = 0;
virtual bool NeedsTickAnimations() const = 0;
- virtual bool ActivateAnimations() = 0;
+ virtual bool ActivateAnimations(MutatorEvents* events) = 0;
// TODO(smcgruer): Once we only tick scroll-based animations on scroll, we
// don't need to pass the scroll tree in here.
virtual bool TickAnimations(base::TimeTicks monotonic_time,
@@ -88,6 +88,9 @@ class MutatorHost {
virtual bool IsAnimatingFilterProperty(ElementId element_id,
ElementListType list_type) const = 0;
+ virtual bool IsAnimatingBackdropFilterProperty(
+ ElementId element_id,
+ ElementListType list_type) const = 0;
virtual bool IsAnimatingOpacityProperty(ElementId element_id,
ElementListType list_type) const = 0;
virtual bool IsAnimatingTransformProperty(
@@ -97,6 +100,9 @@ class MutatorHost {
virtual bool HasPotentiallyRunningFilterAnimation(
ElementId element_id,
ElementListType list_type) const = 0;
+ virtual bool HasPotentiallyRunningBackdropFilterAnimation(
+ ElementId element_id,
+ ElementListType list_type) const = 0;
virtual bool HasPotentiallyRunningOpacityAnimation(
ElementId element_id,
ElementListType list_type) const = 0;
@@ -108,22 +114,18 @@ class MutatorHost {
ElementId element_id,
TargetProperty::Type property) const = 0;
- virtual bool HasOnlyTranslationTransforms(
- ElementId element_id,
- ElementListType list_type) const = 0;
virtual bool AnimationsPreserveAxisAlignment(ElementId element_id) const = 0;
- // Returns the maximum scale along any dimension at any destination in active
- // scale animations, or kNotScaled if there is no active scale animation or
- // the maximum scale cannot be computed.
- virtual float MaximumTargetScale(ElementId element_id,
- ElementListType list_type) const = 0;
-
- // Returns the maximum of starting animation scale along any dimension at any
- // destination in active scale animations, or kNotScaled if there is no active
- // scale animation or the starting scale cannot be computed.
- virtual float AnimationStartScale(ElementId element_id,
- ElementListType list_type) const = 0;
+ // Gets scales transform animations. On return, |maximum_scale| is the maximum
+ // scale along any dimension at any destination in active scale animations,
+ // and |starting_scale| is the maximum of starting animation scale along any
+ // dimension at any destination in active scale animations. They are set to
+ // kNotScaled if there is no active scale animation or the scales cannot be
+ // computed.
+ virtual void GetAnimationScales(ElementId element_id,
+ ElementListType list_type,
+ float* maximum_scale,
+ float* starting_scale) const = 0;
virtual bool IsElementAnimating(ElementId element_id) const = 0;
virtual bool HasTickingKeyframeModelForTesting(
diff --git a/chromium/cc/trees/mutator_host_client.h b/chromium/cc/trees/mutator_host_client.h
index 44bad2c372b..5d221f3051c 100644
--- a/chromium/cc/trees/mutator_host_client.h
+++ b/chromium/cc/trees/mutator_host_client.h
@@ -29,8 +29,8 @@ enum class AnimationWorkletMutationState {
class MutatorHostClient {
public:
- virtual bool IsElementInList(ElementId element_id,
- ElementListType list_type) const = 0;
+ virtual bool IsElementInPropertyTrees(ElementId element_id,
+ ElementListType list_type) const = 0;
virtual void SetMutatorsNeedCommit() = 0;
virtual void SetMutatorsNeedRebuildPropertyTrees() = 0;
@@ -38,6 +38,10 @@ class MutatorHostClient {
virtual void SetElementFilterMutated(ElementId element_id,
ElementListType list_type,
const FilterOperations& filters) = 0;
+ virtual void SetElementBackdropFilterMutated(
+ ElementId element_id,
+ ElementListType list_type,
+ const FilterOperations& backdrop_filters) = 0;
virtual void SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) = 0;
diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc
index 3c73e1d45bf..e4da0f3f7c4 100644
--- a/chromium/cc/trees/occlusion_tracker.cc
+++ b/chromium/cc/trees/occlusion_tracker.cc
@@ -341,6 +341,9 @@ void OcclusionTracker::MarkOccludedBehindLayer(const LayerImpl* layer) {
if (layer->Is3dSorted())
return;
+ if (!layer->draw_properties().rounded_corner_bounds.IsEmpty())
+ return;
+
SimpleEnclosedRegion opaque_layer_region = layer->VisibleOpaqueRegion();
if (opaque_layer_region.IsEmpty())
return;
diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc
index 80d87380237..04827454e5e 100644
--- a/chromium/cc/trees/occlusion_tracker_unittest.cc
+++ b/chromium/cc/trees/occlusion_tracker_unittest.cc
@@ -166,17 +166,6 @@ class OcclusionTrackerTest : public testing::Test {
return layer_ptr;
}
- LayerImpl* CreateMaskLayer(LayerImpl* owning_layer, const gfx::Size& bounds) {
- LayerTreeImpl* tree = host_->host_impl()->active_tree();
- int id = next_layer_impl_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));
- return layer_ptr;
- }
-
TestContentLayerImpl* CreateDrawingSurface(LayerImpl* parent,
const gfx::Transform& transform,
const gfx::PointF& position,
@@ -905,6 +894,11 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest {
parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
true);
+ gfx::Transform rounded_corner_transform;
+ TestContentLayerImpl* rounded_corner_layer = this->CreateDrawingLayer(
+ parent, rounded_corner_transform, gfx::PointF(30.f, 30.f),
+ gfx::Size(500, 500), true);
+
blur_layer->test_properties()->force_render_surface = true;
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(10.f));
@@ -920,10 +914,19 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest {
filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
opacity_layer->test_properties()->filters = filters;
+ rounded_corner_layer->test_properties()->rounded_corner_bounds =
+ gfx::RRectF(1, 2, 3, 4, 5, 6);
+
this->CalcDrawEtc(parent);
TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
+ // Rounded corners won't contribute to occlusion.
+ this->EnterLayer(rounded_corner_layer, &occlusion);
+ EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
+ EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
+ this->LeaveLayer(rounded_corner_layer, &occlusion);
+
// Opacity layer won't contribute to occlusion.
this->VisitLayer(opacity_layer, &occlusion);
this->EnterContributingSurface(opacity_layer, &occlusion);
diff --git a/chromium/cc/trees/paint_holding_commit_trigger.h b/chromium/cc/trees/paint_holding_commit_trigger.h
new file mode 100644
index 00000000000..fcf4832a5b8
--- /dev/null
+++ b/chromium/cc/trees/paint_holding_commit_trigger.h
@@ -0,0 +1,28 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_PAINT_HOLDING_COMMIT_TRIGGER_H_
+#define CC_TREES_PAINT_HOLDING_COMMIT_TRIGGER_H_
+
+namespace cc {
+
+enum class PaintHoldingCommitTrigger {
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+
+ // The Paint Holding flag is not enabled
+ kFeatureDisabled = 0,
+ // Paint Holding is not allowed due to different origin or wrong protocol
+ kDisallowed = 1,
+ // The commit was triggered by first contentful paint (FCP)
+ kFirstContentfulPaint = 2,
+ // The commit was triggered by a timeout waiting for FCP
+ kTimeout = 3,
+ // Required for UMA enum
+ kMaxValue = kTimeout
+};
+
+} // namespace cc
+
+#endif // CC_TREES_PAINT_HOLDING_COMMIT_TRIGGER_H_
diff --git a/chromium/cc/trees/presentation_time_callback_buffer.cc b/chromium/cc/trees/presentation_time_callback_buffer.cc
new file mode 100644
index 00000000000..5274d5bdf1c
--- /dev/null
+++ b/chromium/cc/trees/presentation_time_callback_buffer.cc
@@ -0,0 +1,117 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/presentation_time_callback_buffer.h"
+
+#include <utility>
+#include <vector>
+
+namespace cc {
+
+PresentationTimeCallbackBuffer::PresentationTimeCallbackBuffer() = default;
+
+PresentationTimeCallbackBuffer::PresentationTimeCallbackBuffer(
+ PresentationTimeCallbackBuffer&& other)
+ : frame_token_infos_(std::move(other.frame_token_infos_)) {}
+
+PresentationTimeCallbackBuffer& PresentationTimeCallbackBuffer::operator=(
+ PresentationTimeCallbackBuffer&& other) {
+ if (this != &other) {
+ frame_token_infos_ = std::move(other.frame_token_infos_);
+ }
+ return *this;
+}
+
+PresentationTimeCallbackBuffer::~PresentationTimeCallbackBuffer() = default;
+
+PresentationTimeCallbackBuffer::FrameTokenInfo::FrameTokenInfo(uint32_t token)
+ : token(token) {}
+
+PresentationTimeCallbackBuffer::FrameTokenInfo::FrameTokenInfo(
+ FrameTokenInfo&&) = default;
+PresentationTimeCallbackBuffer::FrameTokenInfo&
+PresentationTimeCallbackBuffer::FrameTokenInfo::operator=(FrameTokenInfo&&) =
+ default;
+PresentationTimeCallbackBuffer::FrameTokenInfo::~FrameTokenInfo() = default;
+
+void PresentationTimeCallbackBuffer::RegisterMainThreadPresentationCallbacks(
+ uint32_t frame_token,
+ std::vector<CallbackType> callbacks) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ FrameTokenInfo& frame_info = GetOrMakeRegistration(frame_token);
+
+ // Splice the given |callbacks| onto the vector of existing callbacks.
+ auto& sink = frame_info.main_thread_callbacks;
+ sink.reserve(sink.size() + callbacks.size());
+ std::move(callbacks.begin(), callbacks.end(), std::back_inserter(sink));
+
+ DCHECK_LE(frame_token_infos_.size(), 25u);
+}
+
+void PresentationTimeCallbackBuffer::RegisterFrameTime(
+ uint32_t frame_token,
+ base::TimeTicks frame_time) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ FrameTokenInfo& frame_info = GetOrMakeRegistration(frame_token);
+
+ // Protect against clobbering previously registered frame times.
+ DCHECK(frame_info.frame_time.is_null() ||
+ frame_info.frame_time == frame_time);
+ frame_info.frame_time = frame_time;
+
+ DCHECK_LE(frame_token_infos_.size(), 25u);
+}
+
+PresentationTimeCallbackBuffer::PendingCallbacks::PendingCallbacks() = default;
+PresentationTimeCallbackBuffer::PendingCallbacks::PendingCallbacks(
+ PendingCallbacks&&) = default;
+PresentationTimeCallbackBuffer::PendingCallbacks&
+PresentationTimeCallbackBuffer::PendingCallbacks::operator=(
+ PendingCallbacks&&) = default;
+PresentationTimeCallbackBuffer::PendingCallbacks::~PendingCallbacks() = default;
+
+PresentationTimeCallbackBuffer::PendingCallbacks
+PresentationTimeCallbackBuffer::PopPendingCallbacks(uint32_t frame_token) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ PendingCallbacks result;
+
+ while (!frame_token_infos_.empty()) {
+ auto info = frame_token_infos_.begin();
+ if (viz::FrameTokenGT(info->token, frame_token))
+ break;
+
+ // Forward compositor frame timings on exact frame token matches. These
+ // timings correspond to frames that caused on-screen damage.
+ if (info->token == frame_token && !info->frame_time.is_null())
+ result.frame_time = info->frame_time;
+
+ // Collect the main-thread callbacks. It's the caller's job to post them to
+ // the main thread.
+ std::move(info->main_thread_callbacks.begin(),
+ info->main_thread_callbacks.end(),
+ std::back_inserter(result.main_thread_callbacks));
+
+ frame_token_infos_.erase(info);
+ }
+
+ return result;
+}
+
+PresentationTimeCallbackBuffer::FrameTokenInfo&
+PresentationTimeCallbackBuffer::GetOrMakeRegistration(uint32_t frame_token) {
+ // If the freshest registration is for an earlier frame token, add a new
+ // entry to the queue.
+ if (frame_token_infos_.empty() ||
+ viz::FrameTokenGT(frame_token, frame_token_infos_.back().token)) {
+ frame_token_infos_.emplace_back(frame_token);
+ }
+
+ // Registrations should use monotonically increasing frame tokens.
+ DCHECK_EQ(frame_token_infos_.back().token, frame_token);
+
+ return frame_token_infos_.back();
+}
+
+} // namespace cc
diff --git a/chromium/cc/trees/presentation_time_callback_buffer.h b/chromium/cc/trees/presentation_time_callback_buffer.h
new file mode 100644
index 00000000000..cdebf905c36
--- /dev/null
+++ b/chromium/cc/trees/presentation_time_callback_buffer.h
@@ -0,0 +1,132 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef CC_TREES_PRESENTATION_TIME_CALLBACK_BUFFER_H_
+#define CC_TREES_PRESENTATION_TIME_CALLBACK_BUFFER_H_
+
+#include <vector>
+
+#include "base/containers/circular_deque.h"
+#include "base/sequence_checker.h"
+#include "cc/trees/layer_tree_host.h"
+
+namespace cc {
+
+// Maintains a queue of callbacks and compositor frame times that we want to
+// buffer until a relevant frame is presented.
+//
+// Callbacks are queued through |RegisterMainThreadPresentationCallbacks|.
+//
+// Once a frame is presented, users of this class can call
+// |PopPendingCallbacks| to get their callbacks back. This class never runs
+// callbacks itself so it's up to calling code to |PostTask| as needed.
+//
+// This class is thread unsafe so concurrent access would require external
+// synchronization. In practice, however, instances of this class are only used
+// on the compositor thread even though the buffered callbacks are intended to
+// be run on the renderer main thread.
+//
+// CC_EXPORT is only needed for testing.
+class CC_EXPORT PresentationTimeCallbackBuffer {
+ public:
+ using CallbackType = LayerTreeHost::PresentationTimeCallback;
+
+ PresentationTimeCallbackBuffer();
+
+ PresentationTimeCallbackBuffer(const PresentationTimeCallbackBuffer&) =
+ delete;
+ PresentationTimeCallbackBuffer(PresentationTimeCallbackBuffer&&);
+
+ PresentationTimeCallbackBuffer& operator=(
+ const PresentationTimeCallbackBuffer&) = delete;
+ PresentationTimeCallbackBuffer& operator=(PresentationTimeCallbackBuffer&&);
+
+ ~PresentationTimeCallbackBuffer();
+
+ // Buffers the given |callbacks| in preparation for a GPU frame swap at or
+ // after the given |frame_token|. Calling code posts these callbacks to the
+ // main thread once they're popped.
+ void RegisterMainThreadPresentationCallbacks(
+ uint32_t frame_token,
+ std::vector<CallbackType> callbacks);
+
+ // The given |frame_time| is associated with the given |frame_token| and will
+ // be exposed through |PopPendingCallbacks| if there is an exact frame token
+ // match. Note that it is an error to register distinct |frame_time|s against
+ // the same |frame_token|.
+ void RegisterFrameTime(uint32_t frame_token, base::TimeTicks frame_time);
+
+ // Structured return value for |PopPendingCallbacks|. CC_EXPORT is only
+ // needed for testing.
+ struct CC_EXPORT PendingCallbacks {
+ PendingCallbacks();
+
+ PendingCallbacks(const PendingCallbacks&) = delete;
+ PendingCallbacks(PendingCallbacks&&);
+
+ PendingCallbacks& operator=(const PendingCallbacks&) = delete;
+ PendingCallbacks& operator=(PendingCallbacks&&);
+
+ ~PendingCallbacks();
+
+ // Holds callbacks registered through
+ // |RegisterMainThreadPresentationCallbacks|.
+ std::vector<CallbackType> main_thread_callbacks;
+
+ // Note: calling code needs to test against frame_time.is_null() because
+ // frame_time is not always defined. See |PopPendingCallbacks|.
+ base::TimeTicks frame_time;
+ };
+
+ // Call this once the presentation for the given |frame_token| has completed.
+ // Yields any pending callbacks that were registered against a frame token
+ // that was less than or equal to the given |frame_token|. It is the caller's
+ // responsibility to run the callbacks on the right threads/sequences. When
+ // the given |frame_token| is an exact match to a registered entry,
+ // |frame_time| will be set to the frame time supplied through
+ // |RegisterFrameTime|. Otherwise, |frame_time| will be default constructed
+ // and should not be used. Calling code can assume |frame_time| is meaningful
+ // iff frame_time.is_null() returns false.
+ PendingCallbacks PopPendingCallbacks(uint32_t frame_token);
+
+ private:
+ // Stores information needed once we get a response for a particular
+ // presentation token.
+ struct FrameTokenInfo {
+ explicit FrameTokenInfo(uint32_t token);
+ FrameTokenInfo(const FrameTokenInfo&) = delete;
+ FrameTokenInfo(FrameTokenInfo&&);
+ FrameTokenInfo& operator=(const FrameTokenInfo&) = delete;
+ FrameTokenInfo& operator=(FrameTokenInfo&&);
+ ~FrameTokenInfo();
+
+ // A |CompositorFrameMetadata::frame_token| that we use to associate
+ // presentation feedback with the relevant compositor frame.
+ uint32_t token;
+
+ // A copy of the |frame_time| from the |BeginFrameArgs| associated with
+ // frame. Useful for tracking latency between frame requests and frame
+ // presentations.
+ base::TimeTicks frame_time;
+
+ // The callbacks to send back to the main thread.
+ std::vector<CallbackType> main_thread_callbacks;
+ };
+
+ // Returns a reference to a |FrameTokenInfo| with the given |frame_token|.
+ // The instance is created if necessary and occupies the appropriate place in
+ // |frame_token_infos_|.
+ FrameTokenInfo& GetOrMakeRegistration(uint32_t frame_token);
+
+ // Queue of pending registrations ordered by |token|. We can use a deque
+ // because we require callers to use non-decreasing tokens when registering.
+ base::circular_deque<FrameTokenInfo> frame_token_infos_;
+
+ // When DCHECK is enabled, check that instances of this class aren't being
+ // used concurrently.
+ SEQUENCE_CHECKER(sequence_checker_);
+};
+
+} // namespace cc
+
+#endif // CC_TREES_PRESENTATION_TIME_CALLBACK_BUFFER_H_
diff --git a/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc b/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc
new file mode 100644
index 00000000000..2d6b36f1f54
--- /dev/null
+++ b/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/presentation_time_callback_buffer.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+std::vector<cc::PresentationTimeCallbackBuffer::CallbackType> GenerateCallbacks(
+ int num_callbacks) {
+ std::vector<cc::PresentationTimeCallbackBuffer::CallbackType> result;
+
+ while (num_callbacks-- > 0) {
+ // PresentationTimeCallbackBuffer isn't supposed to invoke any callbacks.
+ // We can check for that by passing callbacks which cause test failure.
+ result.emplace_back(base::BindOnce([](const gfx::PresentationFeedback&) {
+ FAIL() << "Callbacks should not be directly invoked by "
+ "PresentationTimeCallbackBuffer";
+ }));
+ }
+
+ return result;
+}
+
+base::TimeTicks MakeTicks(uint64_t us) {
+ return base::TimeTicks() + base::TimeDelta::FromMicroseconds(us);
+}
+
+constexpr uint32_t kFrameToken1 = 234;
+constexpr uint32_t kFrameToken2 = 345;
+constexpr uint32_t kFrameToken3 = 456;
+constexpr uint32_t kFrameToken4 = 567;
+
+} // namespace
+
+namespace cc {
+
+TEST(PresentationTimeCallbackBufferTest, TestNoCallbacks) {
+ PresentationTimeCallbackBuffer buffer;
+
+ auto result = buffer.PopPendingCallbacks(kFrameToken1);
+
+ EXPECT_TRUE(result.main_thread_callbacks.empty());
+ EXPECT_TRUE(result.frame_time.is_null());
+}
+
+TEST(PresentationTimeCallbackBufferTest, TestOneMainThreadCallback) {
+ PresentationTimeCallbackBuffer buffer;
+
+ buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2,
+ GenerateCallbacks(1));
+
+ // Make sure that popping early frame tokens doesn't return irrelevant
+ // entries.
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken1);
+ EXPECT_TRUE(result.main_thread_callbacks.empty());
+ EXPECT_TRUE(result.frame_time.is_null());
+ }
+
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken2);
+ EXPECT_EQ(result.main_thread_callbacks.size(), 1ull);
+ EXPECT_TRUE(result.frame_time.is_null());
+ }
+
+ // Make sure that the buffer has removed the registration since the "pop".
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken2);
+ EXPECT_TRUE(result.main_thread_callbacks.empty());
+ EXPECT_TRUE(result.frame_time.is_null());
+ }
+}
+
+TEST(PresentationTimeCallbackBufferTest, TestFrameTimeRegistration) {
+ PresentationTimeCallbackBuffer buffer;
+
+ base::TimeTicks frame_time = MakeTicks(234);
+ buffer.RegisterFrameTime(kFrameToken2, frame_time);
+
+ // Make sure that popping early frame tokens doesn't return irrelevant
+ // entries.
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken1);
+ EXPECT_TRUE(result.main_thread_callbacks.empty());
+ EXPECT_TRUE(result.frame_time.is_null());
+ }
+
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken2);
+ EXPECT_TRUE(result.main_thread_callbacks.empty());
+ EXPECT_FALSE(result.frame_time.is_null());
+ EXPECT_EQ(result.frame_time, frame_time);
+ }
+
+ // Make sure that the buffer has removed the registration since the "pop".
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken2);
+ EXPECT_TRUE(result.main_thread_callbacks.empty());
+ EXPECT_TRUE(result.frame_time.is_null());
+ }
+}
+
+TEST(PresentationTimeCallbackBufferTest, TestCallbackBatchingNoFrameTime) {
+ PresentationTimeCallbackBuffer buffer;
+
+ base::TimeTicks frame_time1 = MakeTicks(123);
+ base::TimeTicks frame_time2 = MakeTicks(234);
+ base::TimeTicks frame_time4 = MakeTicks(456);
+
+ // Register one callback for frame1, two for frame2 and two for frame4.
+ buffer.RegisterMainThreadPresentationCallbacks(kFrameToken1,
+ GenerateCallbacks(1));
+ buffer.RegisterFrameTime(kFrameToken1, frame_time1);
+ buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2,
+ GenerateCallbacks(2));
+ buffer.RegisterFrameTime(kFrameToken2, frame_time2);
+ buffer.RegisterMainThreadPresentationCallbacks(kFrameToken4,
+ GenerateCallbacks(2));
+ buffer.RegisterFrameTime(kFrameToken4, frame_time4);
+
+ // Pop callbacks up to and including frame3. Should be three in total; one
+ // from frame1 and two from frame2. There shouldn't be a frame time because
+ // no frame time was registered against exactly kFrameToken3.
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken3);
+ EXPECT_EQ(result.main_thread_callbacks.size(), 3ull);
+ EXPECT_TRUE(result.frame_time.is_null());
+ }
+}
+
+TEST(PresentationTimeCallbackBufferTest, TestCallbackBatchingWithFrameTime) {
+ PresentationTimeCallbackBuffer buffer;
+
+ base::TimeTicks frame_time3 = MakeTicks(345);
+
+ // Register one callback for frame1, two for frame2 and two for frame4.
+ buffer.RegisterMainThreadPresentationCallbacks(kFrameToken1,
+ GenerateCallbacks(1));
+ buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2,
+ GenerateCallbacks(2));
+ buffer.RegisterFrameTime(kFrameToken3, frame_time3);
+ buffer.RegisterMainThreadPresentationCallbacks(kFrameToken4,
+ GenerateCallbacks(2));
+
+ // Pop callbacks up to and including frame3. Should be three in total; one
+ // from frame1 and two from frame2. There should be a frame time because
+ // a frame time was registered against exactly kFrameToken3.
+ {
+ auto result = buffer.PopPendingCallbacks(kFrameToken3);
+ EXPECT_EQ(result.main_thread_callbacks.size(), 3ull);
+ EXPECT_FALSE(result.frame_time.is_null());
+ EXPECT_EQ(result.frame_time, frame_time3);
+ }
+}
+
+} // namespace cc
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index 9801773b479..5d6b0b82fa1 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -831,13 +831,13 @@ void EffectTree::UpdateHasMaskingChild(EffectNode* node,
// when we actually encounter a masking child.
node->has_masking_child = false;
if (node->blend_mode == SkBlendMode::kDstIn) {
- DCHECK(parent_node->has_render_surface);
+ DCHECK(parent_node->HasRenderSurface());
parent_node->has_masking_child = true;
}
}
void EffectTree::UpdateSurfaceContentsScale(EffectNode* effect_node) {
- if (!effect_node->has_render_surface) {
+ if (!effect_node->HasRenderSurface()) {
effect_node->surface_contents_scale = gfx::Vector2dF(1.0f, 1.0f);
return;
}
@@ -902,6 +902,20 @@ bool EffectTree::OnFilterAnimated(ElementId id,
return true;
}
+bool EffectTree::OnBackdropFilterAnimated(
+ ElementId id,
+ const FilterOperations& backdrop_filters) {
+ EffectNode* node = FindNodeFromElementId(id);
+ DCHECK(node);
+ if (node->backdrop_filters == backdrop_filters)
+ return false;
+ node->backdrop_filters = backdrop_filters;
+ node->effect_changed = true;
+ property_trees()->changed = true;
+ property_trees()->effect_tree.set_needs_update(true);
+ return true;
+}
+
void EffectTree::UpdateEffects(int id) {
EffectNode* node = Node(id);
EffectNode* parent_node = parent(node);
@@ -951,7 +965,7 @@ void EffectTree::TakeCopyRequestsAndTransformToSurface(
int node_id,
std::vector<std::unique_ptr<viz::CopyOutputRequest>>* requests) {
EffectNode* effect_node = Node(node_id);
- DCHECK(effect_node->has_render_surface);
+ DCHECK(effect_node->HasRenderSurface());
DCHECK(effect_node->has_copy_request);
// The area needs to be transformed from the space of content that draws to
@@ -1071,7 +1085,7 @@ void EffectTree::UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl) {
for (int id = kContentsRootNodeId; id < static_cast<int>(size()); ++id) {
EffectNode* effect_node = Node(id);
bool needs_render_surface =
- id == kContentsRootNodeId || effect_node->has_render_surface;
+ id == kContentsRootNodeId || effect_node->HasRenderSurface();
if (needs_render_surface == !!render_surfaces_[id])
continue;
@@ -1120,7 +1134,7 @@ bool EffectTree::CreateOrReuseRenderSurfaces(
std::vector<std::pair<uint64_t, int>> stable_id_node_id_list;
for (int id = kContentsRootNodeId; id < static_cast<int>(size()); ++id) {
EffectNode* node = Node(id);
- if (node->has_render_surface) {
+ if (node->HasRenderSurface()) {
stable_id_node_id_list.push_back(
std::make_pair(node->stable_id, node->id));
}
@@ -1934,6 +1948,24 @@ bool PropertyTrees::ElementIsAnimatingChanged(
<< "Attempting to animate filter on non existent effect node";
}
break;
+ case TargetProperty::BACKDROP_FILTER:
+ if (EffectNode* effect_node =
+ effect_tree.FindNodeFromElementId(element_id)) {
+ if (mask.currently_running[property])
+ effect_node->is_currently_animating_backdrop_filter =
+ state.currently_running[property];
+ if (mask.potentially_animating[property])
+ effect_node->has_potential_backdrop_filter_animation =
+ state.potentially_animating[property];
+ // Backdrop-filter animation changes only the node, and the subtree
+ // does not care, thus there is no need to request property tree
+ // update.
+ } else {
+ DCHECK_NODE_EXISTENCE(check_node_existence, state, property,
+ needs_rebuild)
+ << "Attempting to animate filter on non existent effect node";
+ }
+ break;
default:
break;
}
@@ -2228,6 +2260,12 @@ ClipRectData* PropertyTrees::FetchClipRectFromCache(int clip_id,
return &clip_node->cached_clip_rects->back();
}
+bool PropertyTrees::HasElement(ElementId element_id) const {
+ return element_id_to_effect_node_index.contains(element_id) ||
+ element_id_to_scroll_node_index.contains(element_id) ||
+ element_id_to_transform_node_index.contains(element_id);
+}
+
DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id,
int effect_id) const {
const EffectNode* effect_node = effect_tree.Node(effect_id);
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index 3296420fe6f..f61d2c26a84 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -319,6 +319,8 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
EffectNode* FindNodeFromElementId(ElementId id);
bool OnOpacityAnimated(ElementId id, float opacity);
bool OnFilterAnimated(ElementId id, const FilterOperations& filters);
+ bool OnBackdropFilterAnimated(ElementId id,
+ const FilterOperations& backdrop_filters);
void UpdateEffects(int id);
@@ -700,6 +702,8 @@ class CC_EXPORT PropertyTrees final {
ClipRectData* FetchClipRectFromCache(int clip_id, int target_id);
+ bool HasElement(ElementId element_id) 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 0e5434ee2b5..bd5882ee4f9 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -30,7 +30,6 @@ namespace cc {
namespace {
-template <typename LayerType>
struct DataForRecursion {
int transform_tree_parent;
int transform_tree_parent_fixed;
@@ -90,35 +89,30 @@ class PropertyTreeBuilderContext {
private:
void BuildPropertyTreesInternal(
LayerType* layer,
- const DataForRecursion<LayerType>& data_from_parent) const;
+ const DataForRecursion& data_from_parent) const;
- bool AddTransformNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
- LayerType* layer,
- bool created_render_surface,
- DataForRecursion<LayerType>* data_for_children) const;
+ bool AddTransformNodeIfNeeded(const DataForRecursion& data_from_ancestor,
+ LayerType* layer,
+ bool created_render_surface,
+ DataForRecursion* data_for_children) const;
- void AddClipNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
- LayerType* layer,
- bool created_transform_node,
- DataForRecursion<LayerType>* data_for_children) const;
+ void AddClipNodeIfNeeded(const DataForRecursion& data_from_ancestor,
+ LayerType* layer,
+ bool created_transform_node,
+ DataForRecursion* data_for_children) const;
- bool AddEffectNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
- LayerType* layer,
- DataForRecursion<LayerType>* data_for_children) const;
+ bool AddEffectNodeIfNeeded(const DataForRecursion& data_from_ancestor,
+ LayerType* layer,
+ DataForRecursion* data_for_children) const;
- void AddScrollNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
- LayerType* layer,
- DataForRecursion<LayerType>* data_for_children) const;
+ void AddScrollNodeIfNeeded(const DataForRecursion& data_from_ancestor,
+ LayerType* layer,
+ DataForRecursion* data_for_children) const;
- bool UpdateRenderSurfaceIfNeeded(
- int parent_effect_tree_id,
- DataForRecursion<LayerType>* data_for_children,
- bool subtree_has_rounded_corner,
- bool created_transform_node) const;
+ bool UpdateRenderSurfaceIfNeeded(int parent_effect_tree_id,
+ DataForRecursion* data_for_children,
+ bool subtree_has_rounded_corner,
+ bool created_transform_node) const;
LayerType* root_layer_;
const LayerType* page_scale_layer_;
@@ -207,18 +201,16 @@ static bool HasRoundedCorner(Layer* layer) {
}
static bool HasRoundedCorner(LayerImpl* layer) {
- return false;
+ return !layer->test_properties()->rounded_corner_bounds.IsEmpty();
}
static gfx::RRectF RoundedCornerBounds(Layer* layer) {
- const std::array<uint32_t, 4> radii = layer->corner_radii();
- return gfx::RRectF(gfx::RectF(gfx::Rect(layer->bounds())), radii[0], radii[0],
- radii[1], radii[1], radii[2], radii[2], radii[3],
- radii[3]);
+ return gfx::RRectF(gfx::RectF(gfx::Rect(layer->bounds())),
+ layer->corner_radii());
}
static gfx::RRectF RoundedCornerBounds(LayerImpl* layer) {
- return gfx::RRectF();
+ return layer->test_properties()->rounded_corner_bounds;
}
static PictureLayer* MaskLayer(Layer* layer) {
@@ -286,21 +278,13 @@ bool HasPotentiallyRunningTransformAnimation(const MutatorHost& host,
}
template <typename LayerType>
-bool HasOnlyTranslationTransforms(const MutatorHost& host, LayerType* layer) {
- return host.HasOnlyTranslationTransforms(layer->element_id(),
- layer->GetElementTypeForAnimation());
-}
-
-template <typename LayerType>
-float MaximumAnimationScale(const MutatorHost& host, LayerType* layer) {
- return host.MaximumTargetScale(layer->element_id(),
- layer->GetElementTypeForAnimation());
-}
-
-template <typename LayerType>
-float StartingAnimationScale(const MutatorHost& host, LayerType* layer) {
- return host.AnimationStartScale(layer->element_id(),
- layer->GetElementTypeForAnimation());
+void GetAnimationScales(const MutatorHost& host,
+ LayerType* layer,
+ float* maximum_scale,
+ float* starting_scale) {
+ return host.GetAnimationScales(layer->element_id(),
+ layer->GetElementTypeForAnimation(),
+ maximum_scale, starting_scale);
}
template <typename LayerType>
@@ -319,8 +303,7 @@ bool HasAnyAnimationTargetingProperty(const MutatorHost& host,
// -------------------------------------------------------------------
template <typename LayerType>
-static int GetTransformParent(const DataForRecursion<LayerType>& data,
- LayerType* layer) {
+static int GetTransformParent(const DataForRecursion& data, LayerType* layer) {
return PositionConstraint(layer).is_fixed_position()
? data.transform_tree_parent_fixed
: data.transform_tree_parent;
@@ -333,8 +316,7 @@ static bool LayerClipsSubtree(LayerType* layer) {
}
template <typename LayerType>
-static int GetScrollParentId(const DataForRecursion<LayerType>& data,
- LayerType* layer) {
+static int GetScrollParentId(const DataForRecursion& data, LayerType* layer) {
const bool inherits_scroll = !ScrollParent(layer);
const int id = inherits_scroll ? data.scroll_tree_parent
: ScrollParent(layer)->scroll_tree_index();
@@ -375,10 +357,10 @@ static inline bool HasLatestSequenceNumber(const LayerImpl*, int) {
template <typename LayerType>
void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
+ const DataForRecursion& data_from_ancestor,
LayerType* layer,
bool created_transform_node,
- DataForRecursion<LayerType>* data_for_children) const {
+ DataForRecursion* data_for_children) const {
const bool inherits_clip = !ClipParent(layer);
// Sanity check the clip parent already built clip node before us.
DCHECK(inherits_clip ||
@@ -445,10 +427,10 @@ static inline bool ShouldFlattenTransform(LayerImpl* layer) {
template <typename LayerType>
bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
+ const DataForRecursion& data_from_ancestor,
LayerType* layer,
bool created_render_surface,
- DataForRecursion<LayerType>* data_for_children) const {
+ DataForRecursion* data_for_children) const {
const bool is_root = !LayerParent(layer);
const bool is_page_scale_layer = layer == page_scale_layer_;
const bool is_overscroll_elasticity_layer =
@@ -576,8 +558,8 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded(
node->has_potential_animation = has_potentially_animated_transform;
node->is_currently_animating = TransformIsAnimating(mutator_host_, layer);
- node->maximum_animation_scale = MaximumAnimationScale(mutator_host_, layer);
- node->starting_animation_scale = StartingAnimationScale(mutator_host_, layer);
+ GetAnimationScales(mutator_host_, layer, &node->maximum_animation_scale,
+ &node->starting_animation_scale);
float post_local_scale_factor = 1.0f;
@@ -716,11 +698,11 @@ static inline bool CacheRenderSurface(LayerImpl* layer) {
return layer->test_properties()->cache_render_surface;
}
-static inline bool ForceRenderSurface(Layer* layer) {
+static inline bool ForceRenderSurfaceForTesting(Layer* layer) {
return layer->force_render_surface_for_testing();
}
-static inline bool ForceRenderSurface(LayerImpl* layer) {
+static inline bool ForceRenderSurfaceForTesting(LayerImpl* layer) {
return layer->test_properties()->force_render_surface;
}
@@ -805,11 +787,13 @@ static inline const FilterOperations& BackdropFilters(LayerImpl* layer) {
return layer->test_properties()->backdrop_filters;
}
-static inline const gfx::RRectF& BackdropFilterBounds(Layer* layer) {
+static inline const base::Optional<gfx::RRectF>& BackdropFilterBounds(
+ Layer* layer) {
return layer->backdrop_filter_bounds();
}
-static inline const gfx::RRectF& BackdropFilterBounds(LayerImpl* layer) {
+static inline const base::Optional<gfx::RRectF>& BackdropFilterBounds(
+ LayerImpl* layer) {
return layer->test_properties()->backdrop_filter_bounds;
}
@@ -846,40 +830,40 @@ static inline bool PropertyChanged(LayerImpl* layer) {
}
template <typename LayerType>
-bool ShouldCreateRenderSurface(const MutatorHost& mutator_host,
- LayerType* layer,
- gfx::Transform current_transform,
- bool animation_axis_aligned) {
+RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host,
+ LayerType* layer,
+ gfx::Transform current_transform,
+ bool animation_axis_aligned) {
const bool preserves_2d_axis_alignment =
current_transform.Preserves2dAxisAlignment() && animation_axis_aligned;
const bool is_root = !LayerParent(layer);
if (is_root)
- return true;
+ return RenderSurfaceReason::kRoot;
// If the layer uses a mask.
if (MaskLayer(layer)) {
- return true;
+ return RenderSurfaceReason::kMask;
}
// If the layer uses trilinear filtering.
if (TrilinearFiltering(layer)) {
- return true;
+ return RenderSurfaceReason::kTrilinearFiltering;
}
// If the layer uses a CSS filter.
if (!Filters(layer).IsEmpty()) {
- return true;
+ return RenderSurfaceReason::kFilter;
}
// If the layer uses a CSS backdrop-filter.
if (!BackdropFilters(layer).IsEmpty()) {
- return true;
+ return RenderSurfaceReason::kBackdropFilter;
}
// If the layer will use a CSS filter. In this case, the animation
// will start and add a filter to this layer, so it needs a surface.
if (HasPotentiallyRunningFilterAnimation(mutator_host, layer)) {
- return true;
+ return RenderSurfaceReason::kFilterAnimation;
}
int num_descendants_that_draw_content = NumDescendantsThatDrawContent(layer);
@@ -888,15 +872,12 @@ bool ShouldCreateRenderSurface(const MutatorHost& mutator_host,
// parent (i.e. parent participates in a 3D rendering context).
if (LayerIsInExisting3DRenderingContext(layer) &&
ShouldFlattenTransform(layer) && num_descendants_that_draw_content > 0) {
- TRACE_EVENT_INSTANT0(
- "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface flattening",
- TRACE_EVENT_SCOPE_THREAD);
- return true;
+ return RenderSurfaceReason::k3dTransformFlattening;
}
if (!IsFastRoundedCorner(layer) && HasRoundedCorner(layer) &&
num_descendants_that_draw_content > 1) {
- return true;
+ return RenderSurfaceReason::kRoundedCorner;
}
// If the layer has blending.
@@ -904,20 +885,14 @@ bool ShouldCreateRenderSurface(const MutatorHost& mutator_host,
// types of quads than viz::RenderPassDrawQuad. Layers having descendants that
// draw content will still create a separate rendering surface.
if (BlendMode(layer) != SkBlendMode::kSrcOver) {
- TRACE_EVENT_INSTANT0(
- "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface blending",
- TRACE_EVENT_SCOPE_THREAD);
- return true;
+ return RenderSurfaceReason::kBlendMode;
}
// If the layer clips its descendants but it is not axis-aligned with respect
// to its parent.
bool layer_clips_external_content = LayerClipsSubtree(layer);
if (layer_clips_external_content && !preserves_2d_axis_alignment &&
num_descendants_that_draw_content > 0) {
- TRACE_EVENT_INSTANT0(
- "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface clipping",
- TRACE_EVENT_SCOPE_THREAD);
- return true;
+ return RenderSurfaceReason::kClipAxisAlignment;
}
// If the layer has some translucency and does not have a preserves-3d
@@ -934,11 +909,8 @@ bool ShouldCreateRenderSurface(const MutatorHost& mutator_host,
HasPotentiallyRunningOpacityAnimation(mutator_host, layer);
if (may_have_transparency && ShouldFlattenTransform(layer) &&
at_least_two_layers_in_subtree_draw_content) {
- TRACE_EVENT_INSTANT0(
- "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface opacity",
- TRACE_EVENT_SCOPE_THREAD);
DCHECK(!is_root);
- return true;
+ return RenderSurfaceReason::kOpacity;
}
// If the layer has isolation.
// TODO(rosca): to be optimized - create separate rendering surface only when
@@ -946,25 +918,22 @@ bool ShouldCreateRenderSurface(const MutatorHost& mutator_host,
// (layer has transparent background or descendants overflow).
// https://code.google.com/p/chromium/issues/detail?id=301738
if (IsRootForIsolatedGroup(layer)) {
- TRACE_EVENT_INSTANT0(
- "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface isolation",
- TRACE_EVENT_SCOPE_THREAD);
- return true;
+ return RenderSurfaceReason::kRootOrIsolatedGroup;
}
// If we force it.
- if (ForceRenderSurface(layer))
- return true;
+ if (ForceRenderSurfaceForTesting(layer))
+ return RenderSurfaceReason::kTest;
// If we cache it.
if (CacheRenderSurface(layer))
- return true;
+ return RenderSurfaceReason::kCache;
// If we'll make a copy of the layer's contents.
if (HasCopyRequest(layer))
- return true;
+ return RenderSurfaceReason::kCopyRequest;
- return false;
+ return RenderSurfaceReason::kNone;
}
static void TakeCopyRequests(
@@ -1015,9 +984,9 @@ bool UpdateSubtreeHasCopyRequestRecursive(LayerType* layer) {
template <typename LayerType>
bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
+ const DataForRecursion& data_from_ancestor,
LayerType* layer,
- DataForRecursion<LayerType>* data_for_children) const {
+ DataForRecursion* data_for_children) const {
const bool is_root = !LayerParent(layer);
const bool has_transparency = EffectiveOpacity(layer) != 1.f;
const bool has_potential_opacity_animation =
@@ -1028,10 +997,12 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
data_for_children->animation_axis_aligned_since_render_target &=
AnimationsPreserveAxisAlignment(mutator_host_, layer);
data_for_children->compound_transform_since_render_target *= Transform(layer);
- const bool should_create_render_surface = ShouldCreateRenderSurface(
+ auto render_surface_reason = ComputeRenderSurfaceReason(
mutator_host_, layer,
data_for_children->compound_transform_since_render_target,
data_for_children->animation_axis_aligned_since_render_target);
+ bool should_create_render_surface =
+ render_surface_reason != RenderSurfaceReason::kNone;
bool not_axis_aligned_since_last_clip =
data_from_ancestor.not_axis_aligned_since_last_clip
@@ -1063,7 +1034,6 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
node->opacity = Opacity(layer);
node->blend_mode = BlendMode(layer);
node->unscaled_mask_target_size = layer->bounds();
- node->has_render_surface = should_create_render_surface;
node->cache_render_surface = CacheRenderSurface(layer);
node->has_copy_request = HasCopyRequest(layer);
node->filters = Filters(layer);
@@ -1081,6 +1051,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
node->is_currently_animating_filter = FilterIsAnimating(mutator_host_, layer);
node->effect_changed = PropertyChanged(layer);
node->subtree_has_copy_request = SubtreeHasCopyRequest(layer);
+ node->render_surface_reason = render_surface_reason;
node->closest_ancestor_with_cached_render_surface_id =
CacheRenderSurface(layer)
? node_id
@@ -1157,7 +1128,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
template <typename LayerType>
bool PropertyTreeBuilderContext<LayerType>::UpdateRenderSurfaceIfNeeded(
int parent_effect_tree_id,
- DataForRecursion<LayerType>* data_for_children,
+ DataForRecursion* data_for_children,
bool subtree_has_rounded_corner,
bool created_transform_node) const {
// No effect node was generated for this layer.
@@ -1180,7 +1151,7 @@ bool PropertyTreeBuilderContext<LayerType>::UpdateRenderSurfaceIfNeeded(
// single rrect per quad at draw time, it would be unable to handle
// intersections thus resulting in artifacts.
if (subtree_has_rounded_corner && has_rounded_corner)
- effect_node->has_render_surface = true;
+ effect_node->render_surface_reason = RenderSurfaceReason::kRoundedCorner;
// Inform the parent that its subtree has rounded corners if one of the two
// scenario is true:
@@ -1191,9 +1162,9 @@ bool PropertyTreeBuilderContext<LayerType>::UpdateRenderSurfaceIfNeeded(
// surface of its own to prevent blending artifacts due to intersecting
// rounded corners.
*data_for_children->subtree_has_rounded_corner =
- (subtree_has_rounded_corner && !effect_node->has_render_surface) ||
+ (subtree_has_rounded_corner && !effect_node->HasRenderSurface()) ||
has_rounded_corner;
- return effect_node->has_render_surface;
+ return effect_node->HasRenderSurface();
}
static inline bool UserScrollableHorizontal(Layer* layer) {
@@ -1245,9 +1216,9 @@ void SetHasTransformNode(LayerType* layer, bool val) {
template <typename LayerType>
void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded(
- const DataForRecursion<LayerType>& data_from_ancestor,
+ const DataForRecursion& data_from_ancestor,
LayerType* layer,
- DataForRecursion<LayerType>* data_for_children) const {
+ DataForRecursion* data_for_children) const {
int parent_id = GetScrollParentId(data_from_ancestor, layer);
bool is_root = !LayerParent(layer);
@@ -1339,10 +1310,9 @@ void SetBackfaceVisibilityTransform(LayerType* layer,
}
template <typename LayerType>
-void SetSafeOpaqueBackgroundColor(
- const DataForRecursion<LayerType>& data_from_ancestor,
- LayerType* layer,
- DataForRecursion<LayerType>* data_for_children) {
+void SetSafeOpaqueBackgroundColor(const DataForRecursion& data_from_ancestor,
+ LayerType* layer,
+ DataForRecursion* data_for_children) {
SkColor background_color = layer->background_color();
data_for_children->safe_opaque_background_color =
SkColorGetA(background_color) == 255
@@ -1363,10 +1333,10 @@ static void SetLayerPropertyChangedForChild(LayerImpl* parent,
template <typename LayerType>
void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal(
LayerType* layer,
- const DataForRecursion<LayerType>& data_from_parent) const {
+ const DataForRecursion& data_from_parent) const {
layer->set_property_tree_sequence_number(property_trees_.sequence_number);
- DataForRecursion<LayerType> data_for_children(data_from_parent);
+ DataForRecursion data_for_children(data_from_parent);
*data_for_children.subtree_has_rounded_corner = false;
bool created_render_surface =
@@ -1498,7 +1468,7 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees(
return;
}
- DataForRecursion<LayerType> data_for_recursion;
+ DataForRecursion data_for_recursion;
data_for_recursion.transform_tree_parent = TransformTree::kInvalidNodeId;
data_for_recursion.transform_tree_parent_fixed =
TransformTree::kInvalidNodeId;
diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc
index 1e0a02ae142..848d6e057fb 100644
--- a/chromium/cc/trees/property_tree_unittest.cc
+++ b/chromium/cc/trees/property_tree_unittest.cc
@@ -195,7 +195,8 @@ TEST(PropertyTreeTest, TransformsWithFlattening) {
int grand_parent = tree.Insert(TransformNode(), 0);
int effect_grand_parent = effect_tree.Insert(EffectNode(), 0);
- effect_tree.Node(effect_grand_parent)->has_render_surface = true;
+ effect_tree.Node(effect_grand_parent)->render_surface_reason =
+ RenderSurfaceReason::kTest;
effect_tree.Node(effect_grand_parent)->transform_id = grand_parent;
effect_tree.Node(effect_grand_parent)->surface_contents_scale =
gfx::Vector2dF(1.f, 1.f);
@@ -207,7 +208,8 @@ TEST(PropertyTreeTest, TransformsWithFlattening) {
int parent = tree.Insert(TransformNode(), grand_parent);
int effect_parent = effect_tree.Insert(EffectNode(), effect_grand_parent);
effect_tree.Node(effect_parent)->transform_id = parent;
- effect_tree.Node(effect_parent)->has_render_surface = true;
+ effect_tree.Node(effect_parent)->render_surface_reason =
+ RenderSurfaceReason::kTest;
effect_tree.Node(effect_parent)->surface_contents_scale =
gfx::Vector2dF(1.f, 1.f);
tree.Node(parent)->source_node_id = grand_parent;
@@ -493,7 +495,8 @@ TEST(PropertyTreeTest, SingularTransformSnapTest) {
int parent = tree.Insert(TransformNode(), 0);
int effect_parent = effect_tree.Insert(EffectNode(), 0);
- effect_tree.Node(effect_parent)->has_render_surface = true;
+ effect_tree.Node(effect_parent)->render_surface_reason =
+ RenderSurfaceReason::kTest;
effect_tree.Node(effect_parent)->surface_contents_scale =
gfx::Vector2dF(1.f, 1.f);
tree.Node(parent)->scrolls = true;
@@ -547,7 +550,7 @@ TEST(EffectTreeTest, CopyOutputRequestsAreTransformed) {
EffectTree& effect_tree = property_trees.effect_tree;
EffectNode effect_node;
- effect_node.has_render_surface = true;
+ effect_node.render_surface_reason = RenderSurfaceReason::kTest;
effect_node.has_copy_request = true;
effect_node.transform_id = contents_root.id;
effect_node.id = effect_tree.Insert(effect_node, 0);
@@ -646,7 +649,7 @@ TEST(EffectTreeTest, CopyOutputRequestsThatBecomeIllegalAreDropped) {
EffectTree& effect_tree = property_trees.effect_tree;
EffectNode effect_node;
- effect_node.has_render_surface = true;
+ effect_node.render_surface_reason = RenderSurfaceReason::kTest;
effect_node.has_copy_request = true;
effect_node.transform_id = contents_root.id;
effect_node.id = effect_tree.Insert(effect_node, 0);
diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h
index b275bc84635..10a58a32998 100644
--- a/chromium/cc/trees/proxy.h
+++ b/chromium/cc/trees/proxy.h
@@ -5,8 +5,6 @@
#ifndef CC_TREES_PROXY_H_
#define CC_TREES_PROXY_H_
-#include <stdint.h>
-
#include <memory>
#include <string>
@@ -17,6 +15,7 @@
#include "base/values.h"
#include "cc/cc_export.h"
#include "cc/input/browser_controls_state.h"
+#include "cc/trees/paint_holding_commit_trigger.h"
#include "cc/trees/task_runner_provider.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
@@ -71,7 +70,7 @@ class CC_EXPORT Proxy {
virtual void StartDeferringCommits(base::TimeDelta timeout) = 0;
// Immediately stop deferring commits.
- virtual void StopDeferringCommits() = 0;
+ virtual void StopDeferringCommits(PaintHoldingCommitTrigger) = 0;
virtual bool CommitRequested() const = 0;
@@ -93,13 +92,10 @@ class CC_EXPORT Proxy {
virtual void RequestBeginMainFrameNotExpected(bool new_state) = 0;
- // See description in LayerTreeHost
- virtual uint32_t GenerateChildSurfaceSequenceNumberSync() = 0;
-
// Testing hooks
virtual bool MainFrameWillHappenForTesting() = 0;
- virtual void SetURLForUkm(const GURL& url) = 0;
+ virtual void SetSourceURL(ukm::SourceId source_id, const GURL& url) = 0;
virtual void ClearHistory() = 0;
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index 9d5f067d3d0..cdfd8d3a135 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -497,13 +497,6 @@ void ProxyImpl::DidPresentCompositorFrameOnImplThread(
std::move(callbacks), feedback));
}
-void ProxyImpl::DidGenerateLocalSurfaceIdAllocationOnImplThread(
- const viz::LocalSurfaceIdAllocation& allocation) {
- MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyMain::DidGenerateLocalSurfaceIdAllocation,
- proxy_main_weak_ptr_, allocation));
-}
-
void ProxyImpl::NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType element_list_type) {
@@ -745,9 +738,9 @@ base::SingleThreadTaskRunner* ProxyImpl::MainThreadTaskRunner() {
return task_runner_provider_->MainThreadTaskRunner();
}
-void ProxyImpl::SetURLForUkm(const GURL& url) {
+void ProxyImpl::SetSourceURL(ukm::SourceId source_id, const GURL& url) {
DCHECK(IsImplThread());
- host_impl_->SetActiveURL(url);
+ host_impl_->SetActiveURL(url, source_id);
}
void ProxyImpl::ClearHistory() {
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index 4916e5a09a6..62636b88386 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -58,7 +58,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
LayerTreeHost* layer_tree_host,
base::TimeTicks main_thread_start_time,
bool hold_commit_for_activation);
- void SetURLForUkm(const GURL& url);
+ void SetSourceURL(ukm::SourceId source_id, const GURL& url);
void ClearHistory();
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer);
@@ -109,8 +109,6 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) override;
- void DidGenerateLocalSurfaceIdAllocationOnImplThread(
- const viz::LocalSurfaceIdAllocation& allocation) override;
void NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType element_list_type) override;
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index 8cb9c0516b2..20299713e6a 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -39,7 +39,7 @@ ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host,
commit_waits_for_activation_(false),
started_(false),
defer_main_frame_update_(false),
- defer_commits_(false),
+ defer_commits_(true),
frame_sink_bound_weak_factory_(this),
weak_factory_(this) {
TRACE_EVENT0("cc", "ProxyMain::ProxyMain");
@@ -232,7 +232,7 @@ void ProxyMain::BeginMainFrame(
// Check now if we should stop deferring commits
if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) {
- StopDeferringCommits();
+ StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout);
}
// At this point the main frame may have deferred commits to avoid committing
@@ -360,11 +360,6 @@ void ProxyMain::DidPresentCompositorFrame(
feedback);
}
-void ProxyMain::DidGenerateLocalSurfaceIdAllocation(
- const viz::LocalSurfaceIdAllocation& allocation) {
- layer_tree_host_->DidGenerateLocalSurfaceIdAllocation(allocation);
-}
-
bool ProxyMain::IsStarted() const {
DCHECK(IsMainThread());
return started_;
@@ -480,10 +475,11 @@ void ProxyMain::StartDeferringCommits(base::TimeDelta timeout) {
commits_restart_time_ = base::TimeTicks::Now() + timeout;
}
-void ProxyMain::StopDeferringCommits() {
+void ProxyMain::StopDeferringCommits(PaintHoldingCommitTrigger trigger) {
if (!defer_commits_)
return;
defer_commits_ = false;
+ UMA_HISTOGRAM_ENUMERATION("PaintHolding.CommitTrigger", trigger);
commits_restart_time_ = base::TimeTicks();
TRACE_EVENT_ASYNC_END0("cc", "ProxyMain::SetDeferCommits", this);
}
@@ -547,9 +543,9 @@ void ProxyMain::Stop() {
void ProxyMain::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
TRACE_EVENT0("cc", "ThreadProxy::SetMutator");
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyImpl::InitializeMutatorOnImpl,
- base::Unretained(proxy_impl_.get()),
- base::Passed(std::move(mutator))));
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::InitializeMutatorOnImpl,
+ base::Unretained(proxy_impl_.get()), std::move(mutator)));
}
void ProxyMain::SetPaintWorkletLayerPainter(
@@ -558,20 +554,13 @@ void ProxyMain::SetPaintWorkletLayerPainter(
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&ProxyImpl::InitializePaintWorkletLayerPainterOnImpl,
- base::Unretained(proxy_impl_.get()),
- base::Passed(std::move(painter))));
+ base::Unretained(proxy_impl_.get()), std::move(painter)));
}
bool ProxyMain::SupportsImplScrolling() const {
return true;
}
-uint32_t ProxyMain::GenerateChildSurfaceSequenceNumberSync() {
- // This function only makes sense for single-threaded mode.
- NOTREACHED();
- return 0u;
-}
-
bool ProxyMain::MainFrameWillHappenForTesting() {
DCHECK(IsMainThread());
bool main_frame_will_happen = false;
@@ -645,11 +634,12 @@ base::SingleThreadTaskRunner* ProxyMain::ImplThreadTaskRunner() {
return task_runner_provider_->ImplThreadTaskRunner();
}
-void ProxyMain::SetURLForUkm(const GURL& url) {
+void ProxyMain::SetSourceURL(ukm::SourceId source_id, const GURL& url) {
DCHECK(IsMainThread());
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyImpl::SetURLForUkm,
- base::Unretained(proxy_impl_.get()), url));
+ FROM_HERE, base::BindOnce(&ProxyImpl::SetSourceURL,
+ base::Unretained(proxy_impl_.get()),
+ source_id, url));
}
void ProxyMain::ClearHistory() {
diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h
index a9e5fb4c06f..7b110c08a7d 100644
--- a/chromium/cc/trees/proxy_main.h
+++ b/chromium/cc/trees/proxy_main.h
@@ -10,10 +10,6 @@
#include "cc/trees/proxy.h"
#include "cc/trees/proxy_common.h"
-namespace viz {
-class LocalSurfaceIdAllocation;
-}
-
namespace cc {
class MutatorEvents;
@@ -62,8 +58,6 @@ class CC_EXPORT ProxyMain : public Proxy {
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback);
- void DidGenerateLocalSurfaceIdAllocation(
- const viz::LocalSurfaceIdAllocation& allocation);
CommitPipelineStage max_requested_pipeline_stage() const {
return max_requested_pipeline_stage_;
@@ -90,7 +84,7 @@ class CC_EXPORT ProxyMain : public Proxy {
bool RequestedAnimatePending() override;
void SetDeferMainFrameUpdate(bool defer_main_frame_update) override;
void StartDeferringCommits(base::TimeDelta timeout) override;
- void StopDeferringCommits() override;
+ void StopDeferringCommits(PaintHoldingCommitTrigger) override;
bool CommitRequested() const override;
void Start() override;
void Stop() override;
@@ -98,14 +92,13 @@ class CC_EXPORT ProxyMain : public Proxy {
void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override;
void SetPaintWorkletLayerPainter(
std::unique_ptr<PaintWorkletLayerPainter> painter) override;
- uint32_t GenerateChildSurfaceSequenceNumberSync() override;
bool MainFrameWillHappenForTesting() override;
void ReleaseLayerTreeFrameSink() override;
void UpdateBrowserControlsState(BrowserControlsState constraints,
BrowserControlsState current,
bool animate) override;
void RequestBeginMainFrameNotExpected(bool new_state) override;
- void SetURLForUkm(const GURL& url) override;
+ void SetSourceURL(ukm::SourceId source_id, const GURL& url) override;
void ClearHistory() override;
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) override;
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 8a5393d776d..d74fe26e408 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -50,7 +50,7 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
#endif
inside_draw_(false),
defer_main_frame_update_(false),
- defer_commits_(false),
+ defer_commits_(true),
animate_requested_(false),
commit_requested_(false),
inside_synchronous_composite_(false),
@@ -300,11 +300,13 @@ void SingleThreadProxy::StartDeferringCommits(base::TimeDelta timeout) {
commits_restart_time_ = base::TimeTicks::Now() + timeout;
}
-void SingleThreadProxy::StopDeferringCommits() {
+void SingleThreadProxy::StopDeferringCommits(
+ PaintHoldingCommitTrigger trigger) {
if (!defer_commits_)
return;
defer_commits_ = false;
commits_restart_time_ = base::TimeTicks();
+ UMA_HISTOGRAM_ENUMERATION("PaintHolding.CommitTrigger", trigger);
TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
}
@@ -525,23 +527,12 @@ void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
feedback);
}
-void SingleThreadProxy::DidGenerateLocalSurfaceIdAllocationOnImplThread(
- const viz::LocalSurfaceIdAllocation& allocation) {
- DebugScopedSetMainThread main(task_runner_provider_);
- layer_tree_host_->DidGenerateLocalSurfaceIdAllocation(allocation);
-}
-
void SingleThreadProxy::NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType element_list_type) {
layer_tree_host_->NotifyAnimationWorkletStateChange(state, element_list_type);
}
-uint32_t SingleThreadProxy::GenerateChildSurfaceSequenceNumberSync() {
- DebugScopedSetImplThread impl(task_runner_provider_);
- return host_impl_->GenerateChildSurfaceSequenceNumberSync();
-}
-
void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
if (scheduler_on_impl_thread_) {
scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
@@ -813,7 +804,7 @@ void SingleThreadProxy::BeginMainFrame(
// Check now if we should stop deferring commits
if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) {
- StopDeferringCommits();
+ StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout);
}
// At this point the main frame may have deferred commits to avoid committing
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 24f95bfb7ad..97a449b3442 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -54,7 +54,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
bool RequestedAnimatePending() override;
void SetDeferMainFrameUpdate(bool defer_main_frame_update) override;
void StartDeferringCommits(base::TimeDelta timeout) override;
- void StopDeferringCommits() override;
+ void StopDeferringCommits(PaintHoldingCommitTrigger) override;
bool CommitRequested() const override;
void Start() override;
void Stop() override;
@@ -63,7 +63,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
std::unique_ptr<PaintWorkletLayerPainter> painter) override;
bool SupportsImplScrolling() const override;
bool MainFrameWillHappenForTesting() override;
- void SetURLForUkm(const GURL& url) override {
+ void SetSourceURL(ukm::SourceId source_id, const GURL& url) override {
// Single-threaded mode is only for browser compositing and for renderers in
// layout tests. This will still get called in the latter case, but we don't
// need to record UKM in that case.
@@ -126,14 +126,11 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
bool skip_draw) override;
void NeedsImplSideInvalidation(bool needs_first_draw_on_activation) override;
void RequestBeginMainFrameNotExpected(bool new_state) override;
- uint32_t GenerateChildSurfaceSequenceNumberSync() override;
void NotifyImageDecodeRequestFinished() override;
void DidPresentCompositorFrameOnImplThread(
uint32_t frame_token,
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) override;
- void DidGenerateLocalSurfaceIdAllocationOnImplThread(
- const viz::LocalSurfaceIdAllocation& allocation) override;
void NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType element_list_type) override;
diff --git a/chromium/cc/trees/swap_promise.h b/chromium/cc/trees/swap_promise.h
index b8663a61aa5..b5638c9e391 100644
--- a/chromium/cc/trees/swap_promise.h
+++ b/chromium/cc/trees/swap_promise.h
@@ -52,13 +52,20 @@ class CC_EXPORT SwapPromise {
ACTIVATION_FAILS,
};
+ enum class DidNotSwapAction {
+ BREAK_PROMISE,
+ KEEP_ACTIVE,
+ };
+
SwapPromise() {}
virtual ~SwapPromise() {}
virtual void DidActivate() = 0;
virtual void WillSwap(viz::CompositorFrameMetadata* metadata) = 0;
virtual void DidSwap() = 0;
- virtual void DidNotSwap(DidNotSwapReason reason) = 0;
+ // Return |KEEP_ACTIVE| if this promise should remain active (should not be
+ // broken by the owner).
+ virtual DidNotSwapAction DidNotSwap(DidNotSwapReason reason) = 0;
// This is called when the main thread starts a (blocking) commit
virtual void OnCommit() {}
diff --git a/chromium/cc/trees/swap_promise_manager.cc b/chromium/cc/trees/swap_promise_manager.cc
index 939cc02d1f6..76c2488d2e0 100644
--- a/chromium/cc/trees/swap_promise_manager.cc
+++ b/chromium/cc/trees/swap_promise_manager.cc
@@ -50,9 +50,14 @@ SwapPromiseManager::TakeSwapPromises() {
void SwapPromiseManager::BreakSwapPromises(
SwapPromise::DidNotSwapReason reason) {
- for (const auto& swap_promise : swap_promise_list_)
- swap_promise->DidNotSwap(reason);
- swap_promise_list_.clear();
+ std::vector<std::unique_ptr<SwapPromise>> keep_active_swap_promises;
+ for (auto& swap_promise : swap_promise_list_) {
+ if (swap_promise->DidNotSwap(reason) ==
+ SwapPromise::DidNotSwapAction::KEEP_ACTIVE) {
+ keep_active_swap_promises.push_back(std::move(swap_promise));
+ }
+ }
+ swap_promise_list_.swap(keep_active_swap_promises);
}
} // namespace cc
diff --git a/chromium/cc/trees/swap_promise_manager_unittest.cc b/chromium/cc/trees/swap_promise_manager_unittest.cc
index d88818e90e2..154feb117f0 100644
--- a/chromium/cc/trees/swap_promise_manager_unittest.cc
+++ b/chromium/cc/trees/swap_promise_manager_unittest.cc
@@ -32,7 +32,9 @@ class MockSwapPromise : public SwapPromise {
void DidActivate() override {}
void WillSwap(viz::CompositorFrameMetadata* metadata) override {}
void DidSwap() override {}
- void DidNotSwap(DidNotSwapReason reason) override {}
+ DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
+ return DidNotSwapAction::BREAK_PROMISE;
+ }
MOCK_METHOD0(OnCommit, void());
int64_t TraceId() const override { return 0; }
};
diff --git a/chromium/cc/trees/target_property.h b/chromium/cc/trees/target_property.h
index f28649ce203..407090f27c4 100644
--- a/chromium/cc/trees/target_property.h
+++ b/chromium/cc/trees/target_property.h
@@ -24,9 +24,10 @@ enum Type {
BACKGROUND_COLOR,
BOUNDS,
CSS_CUSTOM_PROPERTY,
+ BACKDROP_FILTER,
// These sentinels must be last
FIRST_TARGET_PROPERTY = TRANSFORM,
- LAST_TARGET_PROPERTY = CSS_CUSTOM_PROPERTY
+ LAST_TARGET_PROPERTY = BACKDROP_FILTER
};
} // namespace TargetProperty
diff --git a/chromium/cc/trees/transform_node.cc b/chromium/cc/trees/transform_node.cc
index bf8f4262a19..d91bf1d61bf 100644
--- a/chromium/cc/trees/transform_node.cc
+++ b/chromium/cc/trees/transform_node.cc
@@ -30,8 +30,6 @@ TransformNode::TransformNode()
node_and_ancestors_have_only_integer_translation(true),
scrolls(false),
should_be_snapped(false),
- moved_by_inner_viewport_bounds_delta_x(false),
- moved_by_inner_viewport_bounds_delta_y(false),
moved_by_outer_viewport_bounds_delta_x(false),
moved_by_outer_viewport_bounds_delta_y(false),
in_subtree_of_page_scale_layer(false),
@@ -64,10 +62,6 @@ bool TransformNode::operator==(const TransformNode& other) const {
other.node_and_ancestors_have_only_integer_translation &&
scrolls == other.scrolls &&
should_be_snapped == other.should_be_snapped &&
- moved_by_inner_viewport_bounds_delta_x ==
- other.moved_by_inner_viewport_bounds_delta_x &&
- moved_by_inner_viewport_bounds_delta_y ==
- other.moved_by_inner_viewport_bounds_delta_y &&
moved_by_outer_viewport_bounds_delta_x ==
other.moved_by_outer_viewport_bounds_delta_x &&
moved_by_outer_viewport_bounds_delta_y ==
diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h
index ba14b1469b7..5a19ccec9e0 100644
--- a/chromium/cc/trees/transform_node.h
+++ b/chromium/cc/trees/transform_node.h
@@ -105,11 +105,6 @@ struct CC_EXPORT TransformNode {
bool should_be_snapped : 1;
- // These are used to position nodes wrt the right or bottom of the inner or
- // outer viewport.
- bool moved_by_inner_viewport_bounds_delta_x : 1;
- bool moved_by_inner_viewport_bounds_delta_y : 1;
-
// These are used by the compositor to determine which layers need to be
// repositioned by the compositor as a result of browser controls
// expanding/contracting the outer viewport size before Blink repositions the
@@ -143,8 +138,8 @@ struct CC_EXPORT TransformNode {
gfx::Vector2dF source_offset;
gfx::Vector2dF source_to_parent;
- // See ElementAnimations::MaximumTargetScale() and AnimationStartScale() for
- // their meanings. Updated by PropertyTrees::AnimationScalesChanged().
+ // See MutatorHost::GetAnimationScales() for their meanings. Updated by
+ // PropertyTrees::AnimationScalesChanged().
float maximum_animation_scale;
float starting_animation_scale;
diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc
index 34839495a62..9e329f02eaa 100644
--- a/chromium/cc/trees/tree_synchronizer.cc
+++ b/chromium/cc/trees/tree_synchronizer.cc
@@ -89,25 +89,6 @@ void PushLayerList(OwnedLayerImplMap* old_layers,
}
template <typename LayerTreeType>
-void PushElementsInPropertyTreesTo(LayerTreeType* host,
- LayerTreeImpl* tree_impl) {
- for (auto id_iter = tree_impl->elements_in_property_trees().begin();
- id_iter != tree_impl->elements_in_property_trees().end();) {
- const auto& id = *(id_iter++);
- if (!host->elements_in_property_trees().count(id))
- tree_impl->RemoveFromElementPropertyTreeList(id);
- }
-
- for (const auto& id : host->elements_in_property_trees()) {
- if (!tree_impl->IsElementInPropertyTree(id)) {
- // TODO(flackr): We should expose adding element ids without a
- // layer pointer.
- tree_impl->AddToElementPropertyTreeList(id);
- }
- }
-}
-
-template <typename LayerTreeType>
void SynchronizeTreesInternal(LayerTreeType* source_tree,
LayerTreeImpl* tree_impl,
PropertyTrees* property_trees) {
@@ -220,8 +201,6 @@ void TreeSynchronizer::PushLayerProperties(LayerTreeImpl* pending_tree,
PushLayerPropertiesInternal(layers.begin(), layers.end(), active_tree);
PushLayerPropertiesInternal(picture_layers.begin(), picture_layers.end(),
active_tree);
- if (pending_tree->settings().use_layer_lists)
- PushElementsInPropertyTreesTo(pending_tree, active_tree);
pending_tree->ClearLayersThatShouldPushProperties();
}
@@ -232,10 +211,6 @@ void TreeSynchronizer::PushLayerProperties(LayerTreeHost* host_tree,
"layer_count", layers.size());
PushLayerPropertiesInternal(layers.begin(), layers.end(), host_tree,
impl_tree);
- // When using layer lists, we may not have layers for all property tree
- // node ids and need to synchronize the registered id list.
- if (host_tree->IsUsingLayerLists())
- PushElementsInPropertyTreesTo(host_tree, impl_tree);
host_tree->ClearLayersThatShouldPushProperties();
}
diff --git a/chromium/cc/trees/ukm_manager.cc b/chromium/cc/trees/ukm_manager.cc
index cf500c922b8..7b8c98100d6 100644
--- a/chromium/cc/trees/ukm_manager.cc
+++ b/chromium/cc/trees/ukm_manager.cc
@@ -19,13 +19,12 @@ UkmManager::~UkmManager() {
RecordRenderingUkm();
}
-void UkmManager::SetSourceURL(const GURL& url) {
- // If we accumulating any metrics, record them before reseting the source.
+void UkmManager::SetSourceId(ukm::SourceId source_id) {
+ // If we accumulated any metrics, record them before resetting the source.
RecordCheckerboardUkm();
RecordRenderingUkm();
- source_id_ = recorder_->GetNewSourceID();
- recorder_->UpdateSourceURL(source_id_, url);
+ source_id_ = source_id;
}
void UkmManager::SetUserInteractionInProgress(bool in_progress) {
diff --git a/chromium/cc/trees/ukm_manager.h b/chromium/cc/trees/ukm_manager.h
index fef49175828..aeeda10cd0a 100644
--- a/chromium/cc/trees/ukm_manager.h
+++ b/chromium/cc/trees/ukm_manager.h
@@ -27,7 +27,7 @@ class CC_EXPORT UkmManager {
explicit UkmManager(std::unique_ptr<ukm::UkmRecorder> recorder);
~UkmManager();
- void SetSourceURL(const GURL& url);
+ void SetSourceId(ukm::SourceId source_id);
// These metrics are recorded while a user interaction is in progress.
void SetUserInteractionInProgress(bool in_progress);
diff --git a/chromium/cc/trees/ukm_manager_unittest.cc b/chromium/cc/trees/ukm_manager_unittest.cc
index f69ab618536..9f4dd926f5b 100644
--- a/chromium/cc/trees/ukm_manager_unittest.cc
+++ b/chromium/cc/trees/ukm_manager_unittest.cc
@@ -6,12 +6,14 @@
#include "components/ukm/test_ukm_recorder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
namespace cc {
namespace {
-const char kTestUrl1[] = "https://example.com/foo";
-const char kTestUrl2[] = "https://example.com/bar";
+const char kTestUrl[] = "https://example.com/foo";
+const int64_t kTestSourceId1 = 100;
+const int64_t kTestSourceId2 = 200;
const char kUserInteraction[] = "Compositor.UserInteraction";
const char kRendering[] = "Compositor.Rendering";
@@ -27,7 +29,11 @@ class UkmManagerTest : public testing::Test {
auto recorder = std::make_unique<ukm::TestUkmRecorder>();
test_ukm_recorder_ = recorder.get();
manager_ = std::make_unique<UkmManager>(std::move(recorder));
- manager_->SetSourceURL(GURL(kTestUrl1));
+
+ // In production, new UKM Source would have been already created, so
+ // manager only needs to know the source id.
+ test_ukm_recorder_->UpdateSourceURL(kTestSourceId1, GURL(kTestUrl));
+ manager_->SetSourceId(kTestSourceId1);
}
protected:
@@ -49,7 +55,7 @@ TEST_F(UkmManagerTest, Basic) {
for (const auto* entry : entries) {
original_id = entry->source_id;
EXPECT_NE(ukm::kInvalidSourceId, entry->source_id);
- test_ukm_recorder_->ExpectEntrySourceHasUrl(entry, GURL(kTestUrl1));
+ test_ukm_recorder_->ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardArea, 10);
test_ukm_recorder_->ExpectEntryMetric(entry, kMissingTiles, 2);
test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 50);
@@ -71,7 +77,7 @@ TEST_F(UkmManagerTest, Basic) {
manager_->AddCheckerboardStatsForFrame(10, 1, 100);
manager_->AddCheckerboardStatsForFrame(30, 5, 100);
- manager_->SetSourceURL(GURL(kTestUrl2));
+ manager_->SetSourceId(kTestSourceId2);
const auto& entries2 = test_ukm_recorder_->GetEntriesByName(kUserInteraction);
EXPECT_EQ(1u, entries2.size());