Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement matrix decomposition and interpolation #13188

Merged
merged 5 commits into from Sep 16, 2016
Merged

Conversation

@canova
Copy link
Member

canova commented Sep 6, 2016

Implement 2D and 3D matrix decomposition and interpolation for animated properties.
r? @Manishearth


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • There are tests for these changes OR
  • These changes do not require tests because there are no tests for it and we manually tested it.

This change is Reviewable

@highfive
Copy link

highfive commented Sep 6, 2016

Heads up! This PR modifies the following files:

  • @bholley: components/style/properties/helpers/animated_properties.mako.rs
@highfive
Copy link

highfive commented Sep 6, 2016

warning Warning warning

  • These commits modify style code, but no tests are modified. Please consider adding a test!
@@ -751,12 +769,236 @@ impl Interpolate for LengthOrNone {
}
} else {
// TODO(gw): Implement matrix decomposition and interpolation
// TODO(canaltinova): Do I need to interpolate each item of the list?

This comment has been minimized.

Copy link
@canova

canova Sep 6, 2016

Author Member

I'm not sure how to implement interpolation here

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

ignore this for now

@canova canova force-pushed the canova:matrix branch from c6ee9fe to 4332243 Sep 6, 2016
let mut fd_matrix = ComputedMatrix::identity();
let mut td_matrix = ComputedMatrix::identity();
fd_matrix.m43 = -1. / fd.0 as f32;
td_matrix.m43 = -1. / _td.0 as f32;

This comment has been minimized.

Copy link
@canova

canova Sep 6, 2016

Author Member

I had to convert Au value to f32 but I'm not sure if it's correct or not.

This comment has been minimized.

Copy link
@emilio

emilio Sep 7, 2016

Member

You have Au::to_f32_px() if I'm not wrong.

This comment has been minimized.

Copy link
@canova

canova Sep 7, 2016

Author Member

You are right, thanks!

@@ -701,8 +703,11 @@ impl Interpolate for LengthOrNone {
match (from, to) {
(&TransformOperation::Matrix(from),
&TransformOperation::Matrix(_to)) => {
// TODO(gw): Implement matrix decomposition and interpolation
result.push(TransformOperation::Matrix(from));
let decomposed_from = MatrixDecomposed2D::from(from);

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

leave comments that it doesn't yet handle cases where one of the two matrices is not 2D


let decomposed_f = MatrixDecomposed2D::from(matrix_f);
let decomposed_t = MatrixDecomposed2D::from(matrix_t);
let interpolated = decomposed_f.interpolate(&decomposed_t, time).unwrap();

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

this code is common (and will get more complicated when we handle 3d interpolation), perhaps we should implement Interpolate for ComputedMatrix?

result.extend_from_slice(from_list);
}

TransformList(Some(result))
}

fn rotate_to_matrix(x: f32, y: f32, z: f32, a: SpecifiedAngle) -> ComputedMatrix {

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

We could probably just use the same code from layout/display_list_builder.rs?

let theta = 2.0f32 * f32::consts::PI - theta.radians();
Matrix4D::create_rotation(ax, ay, az, Radians::new(theta))

This comment has been minimized.

Copy link
@Manishearth
let sq = 1.0 / 2.0 * (1.0 - (rad).cos());

ComputedMatrix {
m11: 1.0 - 2.0 * (y * y + z * z) * sq, m12: 2.0 * (x * y * sq - z * sc),

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

might be best to indent this as:

m11:
m12:
m13:
m14:

m21:
...

#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct DecomposedMatrix {

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

2DInnerMatrix might be a better name

This comment has been minimized.

Copy link
@canova

canova Sep 7, 2016

Author Member

I tried it but rust is not allowing structs to start with integer value(It's same with MatrixDecomposed2D. I tried 2DMatrixDecomposed but couldn't make it), so I'll change it to InnerMatrix2D, if it's ok.

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

InnerMatrix2D works

// Translate matrix.
computed_matrix.m41 = decomposed.translate.0 * decomposed.matrix.m11 +
decomposed.translate.1 * decomposed.matrix.m21;
computed_matrix.m42 = decomposed.translate.0 * decomposed.matrix.m11 +

This comment has been minimized.

Copy link
@Manishearth

Manishearth Sep 7, 2016

Member

decomposed_matrix.m12 and m22 here

@Manishearth
Copy link
Member

Manishearth commented Sep 7, 2016

Looks correct aside from a few issues. Once those are fixed, could you test this with various matrices (those which are guaranteed to follow the "is 2d matrix" property in the spec) and ensure the animation matches the one firefox does. (Alternatively, just implement the 3D one too so that it's easier to test)

There aren't unit tests in firefox (probably are reftests though). I can maybe generate some test data by logging https://dxr.mozilla.org/mozilla-central/source/layout/style/StyleAnimationValue.cpp#1634, but it's not entirely necessary for now.

@Manishearth
Copy link
Member

Manishearth commented Sep 7, 2016

Firefox's layout/style/test/test_transitions_per_property.html has a bunch of testcases under transformTests. But we'll work on those in a future thing, or I might add them directly later.

@canova canova force-pushed the canova:matrix branch from 4332243 to 5ee93b2 Sep 7, 2016
@canova
Copy link
Member Author

canova commented Sep 7, 2016

Fixed issues except using Matrix4D::create_rotation instead of rotate_to_matrix function. I would prefer avoiding code duplication here but I have to convert Matrix4D to ComputedMatrix afterwards. I need to implement impl From for ComputedMatrix probably. Which one do you prefer, leave it this way or use Matrix4D::create_rotation?

@Manishearth
Copy link
Member

Manishearth commented Sep 7, 2016

Yeah, ignore my comment about create_rotation, it's fine the way it is.

@Manishearth
Copy link
Member

Manishearth commented Sep 8, 2016

02:57 #servo: < canaltinova> Manishearth: Hi, I'm trying to test the changes. But the firefox test is a bit complicated and I couldn't test it on servo yet :/
02:59 #servo: < canaltinova> Manishearth: I tried to add debug!'s for getting the matrices but these codes never run in my scenarios :/
03:01 #servo: < canaltinova> Manishearth: Are there any tips to test them? :)

For now, don't write unit tests -- just test it manually with simple transitions (https://robots.thoughtbot.com/transitions-and-transforms). Have a div which moves between two matrices or something

@Manishearth
Copy link
Member

Manishearth commented Sep 8, 2016

It might be better to first implement the 3D interpolation, so that we can test all cases. I'll test this one for you for now.

@canova
Copy link
Member Author

canova commented Sep 8, 2016

Ok, thanks! So should I implement 3D interpolation in this pull request too or is it better to make it in another pr?

@Manishearth
Copy link
Member

Manishearth commented Sep 8, 2016

Same PR is fine. I don't want to merge this unless I'm able to manually test it (or we have unit tests), and it may take a few days for me to get time for that, so you can just append to this PR

@canova
Copy link
Member Author

canova commented Sep 8, 2016

Ok, I will work on interpolation of 3D matrices now on. So I have to determine in interpolate_transform_list function that the matrix is 2D or 3D. Is there a way to determine it?

@canova
Copy link
Member Author

canova commented Sep 8, 2016

Thanks, I'll look at it!

@canova canova force-pushed the canova:matrix branch from f47987f to 47edb53 Sep 11, 2016
@canova
Copy link
Member Author

canova commented Sep 15, 2016

@bors-servo
Copy link
Contributor

bors-servo commented Sep 15, 2016

Trying commit 3cc3aee with merge 032a364...

bors-servo added a commit that referenced this pull request Sep 15, 2016
Implement matrix decomposition and interpolation

<!-- Please describe your changes on the following line: -->
Implement 2D and 3D matrix decomposition and interpolation for animated properties.
r? @Manishearth

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13188)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Sep 15, 2016

💔 Test failed - mac-rel-wpt

@Manishearth
Copy link
Member

Manishearth commented Sep 15, 2016

@notriddle
Copy link
Contributor

notriddle commented Sep 15, 2016

The CSS build passed.

@Manishearth
Copy link
Member

Manishearth commented Sep 16, 2016

Webkit's 2d recomposition agrees with ours wrt translate.

Additionally, webkit (well, safari) doesn't seem to have this bug

@Manishearth
Copy link
Member

Manishearth commented Sep 16, 2016

Overall https://github.com/WebKit/webkit/blob/284f456f1d22f45d2a68cf6d88bafc49a63ee018/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp is a pretty good bit of code which is close to matching the spec. Or perhaps the spec was written by looking at this code.

@Manishearth
Copy link
Member

Manishearth commented Sep 16, 2016

Anyway, I'm good with merging this (once I test it out myself on your testcases), could you squash (just the last two commits is fine). Though squashing isn't necessary here, so I might just merge directly -- let me know what you prefer.

Thanks!

@Manishearth
Copy link
Member

Manishearth commented Sep 16, 2016

@bors-servo r+

Everything from your pastebin passes now, except for one.

There's a bit of an jump with

matrix(0.879385, -0.507713, 0.921605, 0.532089, 10, -100) -> matrix3d(-0.648456, 0.744262, -0.159932, 0, 0.574503, 0.340618, -0.744262, 0, -0.49945, -0.574503, -0.648456, 0, 0, 0, 0, 1); // translate(10px, -100px) rotate(320deg) skew(20deg, 10deg) -> rotate3d(1, 2, -1, 192deg)

however it's a 3D transform and Servo has issues with those anyway. It's also 2D->3D which is broken in other browsers. I'd rather wait for the spec to figure this stuff out before fixing this.

I'm not sure if it's even an issue, because the transition keeps flickering so I'm not sure if it's a jump or a flicker.

Thanks for sticking with this! Great work!

@bors-servo
Copy link
Contributor

bors-servo commented Sep 16, 2016

📌 Commit 3cc3aee has been approved by Manishearth

@canova canova force-pushed the canova:matrix branch from 3cc3aee to 63c329b Sep 16, 2016
@Manishearth
Copy link
Member

Manishearth commented Sep 16, 2016

@bors-servo
Copy link
Contributor

bors-servo commented Sep 16, 2016

📌 Commit 63c329b has been approved by Manishearth

@bors-servo
Copy link
Contributor

bors-servo commented Sep 16, 2016

Testing commit 63c329b with merge ad7befd...

bors-servo added a commit that referenced this pull request Sep 16, 2016
Implement matrix decomposition and interpolation

<!-- Please describe your changes on the following line: -->
Implement 2D and 3D matrix decomposition and interpolation for animated properties.
r? @Manishearth

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because there are no tests for it and we manually tested it.

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13188)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Sep 16, 2016

@bors-servo bors-servo merged commit 63c329b into servo:master Sep 16, 2016
3 checks passed
3 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@canova
Copy link
Member Author

canova commented Sep 16, 2016

🎉 🎉 🎉 I enjoyed it and you helped me a lot during whole process! Thanks for helping me and reviewing it @Manishearth!

@canova canova deleted the canova:matrix branch Sep 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

7 participants
You can’t perform that action at this time.