Bug 235757 - When interpolating between transform lists partial prefix matches should not use matrix interpolation
Summary: When interpolating between transform lists partial prefix matches should not ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: Safari Technology Preview
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Martin Robinson
URL:
Keywords: InRadar
: 235780 235800 235805 (view as bug list)
Depends on: 222595
Blocks: 232087
  Show dependency treegraph
 
Reported: 2022-01-28 00:40 PST by Martin Robinson
Modified: 2022-03-01 13:51 PST (History)
10 users (show)

See Also:


Attachments
Patch (89.65 KB, patch)
2022-02-21 04:46 PST, Martin Robinson
no flags Details | Formatted Diff | Diff
Patch (89.55 KB, patch)
2022-02-22 03:47 PST, Martin Robinson
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Robinson 2022-01-28 00:40:44 PST
When interpolating between two transform lists that have a match prefix, for instance:

from transform: translateX(25px) rotate(25deg)
to tranform: translateX(100px)

The match prefix should blend together directly and the rest of the list should be blended using matrix interpolation. This especially comes into play when doing multiple rotations around an axis.
Comment 1 Radar WebKit Bug Importer 2022-02-04 00:41:16 PST
<rdar://problem/88477922>
Comment 2 Martin Robinson 2022-02-04 01:12:15 PST
The tricky thing here is mapping the CSS model onto CoreAnimation. For the TextureMapper there isn't an issue because animations are done by calling directly into TransformOperations::blend at each animation tick. On the CoreAnimation side, animations are constructed by stepping through the index of each transform function and constructing an animation for this function across all keyframes.

This will need to change, because the CSS specification only considers interpolation between any two frames. So for instance in this case:

Keyframe 1: translate(...) rotate(...) perspective(...)
Keyframe 2: translate(...) scale(...) translate(...)
Keyframe 3: translate(...) scale(...) rotate(...)

Between keyframe 1 and 2 the computed operations should use the following set of operations (with interpolated arguments):

translate(...) matrix(...)

where matrix is a matrix decomposition and interpolation of the remaining functions. Yet between keyframe 2 and 3 the computed operations are:

translate(...) scale(...) matrix(...)

An option is to only break out transform functions shared across all frames and then use matrix interpolation for the rest. The issue is that this still has the potential to lose full rotations where the specification says we shouldn't, also meaning the displayed contents will be different than the CSS computed values.
Comment 3 Martin Robinson 2022-02-08 08:17:06 PST
I've decided to split the easier part of this issue of into bug 222595 which only handles prefix matches with lists of different lengths and not suffixes that do not match.
Comment 4 Simon Fraser (smfr) 2022-02-08 14:28:53 PST
(In reply to Martin Robinson from comment #0)
> When interpolating between two transform lists that have a match prefix, for
> instance:
> 
> from transform: translateX(25px) rotate(25deg)
> to tranform: translateX(100px)
> 
> The match prefix should blend together directly and the rest of the list
> should be blended using matrix interpolation. This especially comes into
> play when doing multiple rotations around an axis.
 
I see this in the CSS Transforms 1 spec[1], but not the level 2 spec [2]. When does "blend the rest as a matrix" happen, and when does "blend with the equivalent identify function" happen?

[1] https://www.w3.org/TR/css-transforms-1/#interpolation-of-transforms
[2] https://www.w3.org/TR/css-transforms-2/#interpolation-of-transform-functions
Comment 5 Martin Robinson 2022-02-08 15:40:50 PST
(In reply to Simon Fraser (smfr) from comment #4)
> (In reply to Martin Robinson from comment #0)
> > When interpolating between two transform lists that have a match prefix, for
> > instance:
> > 
> > from transform: translateX(25px) rotate(25deg)
> > to tranform: translateX(100px)
> > 
> > The match prefix should blend together directly and the rest of the list
> > should be blended using matrix interpolation. This especially comes into
> > play when doing multiple rotations around an axis.
>  
> I see this in the CSS Transforms 1 spec[1], but not the level 2 spec [2].
> When does "blend the rest as a matrix" happen, and when does "blend with the
> equivalent identify function" happen?

It's true that the specification doesn't say this explicitly, but it's implied in the next section which discusses accumulation of transform lists:

"Accumulation of two transform lists Va and Vb follows the same steps as interpolation with regards to matching transform functions including padding lists with identity transform functions, converting none to an identity transform function, and converting both arguments to matrices as necessary (see CSS Transforms 1 § 11 Interpolation of Transforms)."

Perhaps this is a specification bug?
Comment 6 Martin Robinson 2022-02-21 04:46:15 PST
Created attachment 452723 [details]
Patch
Comment 7 Martin Robinson 2022-02-22 03:47:55 PST
Created attachment 452849 [details]
Patch
Comment 8 EWS 2022-03-01 12:02:44 PST
Committed r290667 (247939@main): <https://commits.webkit.org/247939@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 452849 [details].
Comment 9 Antoine Quint 2022-03-01 13:49:49 PST
*** Bug 235800 has been marked as a duplicate of this bug. ***
Comment 10 Antoine Quint 2022-03-01 13:51:52 PST
*** Bug 235780 has been marked as a duplicate of this bug. ***
Comment 11 Antoine Quint 2022-03-01 13:51:57 PST
*** Bug 235805 has been marked as a duplicate of this bug. ***