Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@ bool apply_decoration_value(dom_node& node,const std::string& name,const std::st
} else if (name == "animation") {
apply_animation_shorthand(node.style, value);
decision.classification = "partially-supported";
decision.semantic_slice = "first animation; opacity @keyframes";
decision.semantic_slice =
"first animation; opacity, rotate(), and bounded filter @keyframes";
return true;
} else if (name == "animation-name") {
node.style.mutable_animations().animation_name_value = value;
decision.classification = "partially-supported";
decision.semantic_slice = "first animation; opacity @keyframes";
decision.semantic_slice =
"first animation; opacity, rotate(), and bounded filter @keyframes";
return true;
} else if (name == "animation-duration") {
node.style.mutable_animations().animation_duration_value = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ struct compiled_css_selector final {
struct css_opacity_keyframes final {
std::vector<node_style::opacity_keyframe> opacity_stops;
std::vector<node_style::rotation_keyframe> rotation_stops;
std::vector<node_style::filter_keyframe> filter_stops;
};

struct css_inheritance_candidate_rule final {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ std::optional<prepared_stylesheet> prepare_stylesheet(std::string_view text,
for(auto& [name,definition]:sink.keyframes()) {
finish_keyframes(host.output.keyframes,std::move(name),std::move(definition));
host.output.diagnostics.push_back({"at-rule:@keyframes","partially-supported",
"opacity and rotate() keyframes with host-clock timing"});
"opacity, rotate(), and bounded filter keyframes with host-clock timing"});
}
// A property known to WebScene must never cross the preparation boundary as
// raw property grammar. Unknown properties remain explicit diagnostics, and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ inline void configure_keyframes(node_style& style,
animations.opacity_keyframe_animation_signature.clear();
animations.rotation_keyframes.clear();
animations.rotation_keyframe_animation_signature.clear();
animations.filter_keyframes.clear();
animations.filter_keyframe_animation_signature.clear();
if (animations.animation_name_value == "none") return;
const auto names = split_css_component_list(animations.animation_name_value, ',');
if (names.empty()) return;
Expand Down Expand Up @@ -266,10 +268,12 @@ inline void configure_keyframes(node_style& style,
animations.opacity_keyframe_y2 = animation_timing.y2;
animations.opacity_keyframes = definition->second.opacity_stops;
animations.rotation_keyframes = definition->second.rotation_stops;
animations.filter_keyframes = definition->second.filter_stops;
if (animations.opacity_keyframe_duration_ms <= 0
|| animations.opacity_keyframe_iterations == 0
|| (animations.opacity_keyframes.size() < 2U
&& animations.rotation_keyframes.size() < 2U)) return;
&& animations.rotation_keyframes.size() < 2U
&& animations.filter_keyframes.size() < 2U)) return;
std::ostringstream signature;
signature << name << '|' << animations.opacity_keyframe_duration_ms << '|'
<< animations.opacity_keyframe_delay_ms << '|'
Expand All @@ -294,6 +298,14 @@ inline void configure_keyframes(node_style& style,
}
animations.rotation_keyframe_animation_signature = signature.str();
}
if (animations.filter_keyframes.size() >= 2U) {
signature.str(base_signature);
signature.clear();
for (const auto& stop : animations.filter_keyframes) {
signature << '|' << stop.offset << ':' << stop.value;
}
animations.filter_keyframe_animation_signature = signature.str();
}
}

inline void append_keyframe(
Expand All @@ -309,6 +321,10 @@ inline void append_keyframe(
declarations.begin(), declarations.end(), [](const auto& declaration) {
return declaration.name == "transform";
});
const auto filter = std::find_if(
declarations.begin(), declarations.end(), [](const auto& declaration) {
return declaration.name == "filter";
});
const auto rotation_degrees = [&]() -> std::optional<float> {
if (transform == declarations.end()) return std::nullopt;
auto value = ascii_lower(trim_value(transform->value));
Expand Down Expand Up @@ -347,6 +363,9 @@ inline void append_keyframe(
if (rotation_degrees.has_value()) {
definition.rotation_stops.push_back({offset, *rotation_degrees});
}
if (filter != declarations.end()) {
definition.filter_stops.push_back({offset, filter->value});
}
}
}

Expand All @@ -373,12 +392,14 @@ inline void finish_keyframes(
};
normalize(definition.opacity_stops);
normalize(definition.rotation_stops);
normalize(definition.filter_stops);
if (definition.rotation_stops.size() == 1U
&& definition.rotation_stops.front().offset > 0) {
definition.rotation_stops.insert(definition.rotation_stops.begin(), {0, 0});
}
if (definition.opacity_stops.size() >= 2U
|| definition.rotation_stops.size() >= 2U) {
|| definition.rotation_stops.size() >= 2U
|| definition.filter_stops.size() >= 2U) {
definitions[ascii_lower(trim_value(std::move(name)))] =
std::move(definition);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ bool style_establishes_atomic_stacking_context(const dom_node& node) noexcept
|| node.style.contain_stacking_context
|| node.style.opacity < 0.999F
|| node.style.transform_stacking_context
|| !node.painted_filter_functions_value().empty()
|| node.has_painted_filter_override_value()
|| (filter != effects.end() && filter->second != "none");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,36 @@
bool operator==(const retained_filter_function&) const = default;
};

inline float retained_filter_identity_amount(uint32_t flags) noexcept
{
return flags == (1U << 31U) || flags == (1U << 29U)
|| flags == (1U << 27U) ? 1.0F : 0.0F;
}

inline bool make_retained_filter_lists_compatible(
std::vector<retained_filter_function>& left,
std::vector<retained_filter_function>& right)
{
const auto shared = std::min(left.size(), right.size());
for (size_t index = 0U; index < shared; ++index) {
if (left[index].flags != right[index].flags) return false;
}
if (left.size() > right.size()) {
for (size_t index = right.size(); index < left.size(); ++index) {
right.push_back({
left[index].flags,
retained_filter_identity_amount(left[index].flags)});
}
} else if (right.size() > left.size()) {
for (size_t index = left.size(); index < right.size(); ++index) {
left.push_back({
right[index].flags,
retained_filter_identity_amount(right[index].flags)});
}
}
return true;
}

struct layout_rect final {
float x{0};
float y{0};
Expand Down Expand Up @@ -145,6 +175,10 @@
float offset{0};
float degrees{0};
};
struct filter_keyframe final {
float offset{0};
std::string value;
};

struct transition_timing final {
float duration_ms{0};
Expand Down Expand Up @@ -177,6 +211,8 @@
std::vector<opacity_keyframe> opacity_keyframes;
std::string rotation_keyframe_animation_signature;
std::vector<rotation_keyframe> rotation_keyframes;
std::string filter_keyframe_animation_signature;
std::vector<filter_keyframe> filter_keyframes;
float opacity_keyframe_duration_ms{0};
float opacity_keyframe_delay_ms{0};
float opacity_keyframe_iterations{1};
Expand Down Expand Up @@ -1191,8 +1227,8 @@
return std::all_of(values_.begin(), values_.end(), [&other](const auto& entry) {
const auto match = other.find(entry.first);
return match != other.end() && match->second == entry.second
&& namespace_uri(entry.first) == other.namespace_uri(entry.first)

Check failure on line 1230 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

'this' cannot be implicitly captured because no default capture mode has been specified

Check failure on line 1230 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

'this' cannot be implicitly captured because no default capture mode has been specified

Check failure on line 1230 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

'this' cannot be implicitly captured because no default capture mode has been specified
&& local_name(entry.first) == other.local_name(entry.first);

Check failure on line 1231 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

'this' cannot be implicitly captured because no default capture mode has been specified

Check failure on line 1231 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

'this' cannot be implicitly captured because no default capture mode has been specified

Check failure on line 1231 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

'this' cannot be implicitly captured because no default capture mode has been specified
});
}

Expand Down Expand Up @@ -1374,6 +1410,11 @@
// authored animation data. Keeping it inline made every static DOM node
// pay for three transition machines and two keyframe signatures.
struct animation_runtime_data final {
struct retained_filter_keyframe final {
float offset{0};
std::vector<retained_filter_function> functions;
bool authored_none{false};
};
css_length painted_transform_translate_x{};
css_length painted_transform_translate_y{};
css_length transform_animation_from_translate_x{};
Expand Down Expand Up @@ -1444,6 +1485,12 @@
std::string rotation_keyframe_animation_signature;
double rotation_keyframe_animation_started_ms{0};
bool rotation_keyframe_animation_active{false};
std::string filter_keyframe_animation_signature;
std::vector<retained_filter_keyframe> filter_keyframes;
std::vector<retained_filter_function> filter_keyframe_underlying;
double filter_keyframe_animation_started_ms{0};
bool filter_keyframe_animation_active{false};
bool filter_keyframe_animation_filled{false};
bool keyframe_animation_end_event_sent{false};
uint32_t painted_foreground_rgba{0};
uint32_t color_animation_from_rgba{0};
Expand Down Expand Up @@ -1795,6 +1842,14 @@
&& animation_runtime_state->rotation_keyframe_animation_active;
}

bool has_painted_filter_override_value() const noexcept
{
return animation_runtime_state != nullptr
&& (animation_runtime_state->filter_animation_active
|| animation_runtime_state->filter_keyframe_animation_active
|| animation_runtime_state->filter_keyframe_animation_filled);
}

bool transform_animation_active_value() const noexcept
{
return animation_runtime_state != nullptr
Expand All @@ -1810,8 +1865,7 @@
std::span<const retained_filter_function> painted_filter_functions_value()
const noexcept
{
if (animation_runtime_state == nullptr
|| !animation_runtime_state->filter_animation_active) return {};
if (!has_painted_filter_override_value()) return {};
return animation_runtime_state->painted_filter_functions;
}

Expand Down Expand Up @@ -2439,7 +2493,7 @@
// ABI-specific equalities: libc++, libstdc++, and MSVC intentionally use
// different std::string and container representations.
static_assert(
sizeof(void*) != 8 || sizeof(dom_node) <= 1024,

Check failure on line 2496 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

static_assert failed: 'dom_node exceeded its cross-library 64-bit footprint budget'

Check failure on line 2496 in experiments/WebScene.NativeEngine.Probe/native/webscene_native_dom.h

View workflow job for this annotation

GitHub Actions / Build win-x64

static_assert failed: 'dom_node exceeded its cross-library 64-bit footprint budget'
"dom_node exceeded its cross-library 64-bit footprint budget");
static_assert(
sizeof(void*) != 8 || sizeof(dom_node::form_control_data) <= 64,
Expand Down
Loading
Loading