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

Clip against near plane for bounds calculus #2741

Merged
merged 1 commit into from May 9, 2018
Merged

Conversation

@kvark
Copy link
Member

kvark commented May 8, 2018

Fixes #2389
Fixes #2272
Improves #2429 a great deal (there are general plane splitting issues in there still)

TODO:


This change is Reviewable

@kvark kvark force-pushed the kvark:perspective branch from 2cf4c77 to fbaf67b May 8, 2018
@bors-servo
Copy link
Contributor

bors-servo commented May 8, 2018

The latest upstream changes (presumably #2736) made this pull request unmergeable. Please resolve the merge conflicts.

@kvark kvark force-pushed the kvark:perspective branch 3 times, most recently from 176e93c to cf5c87b May 9, 2018
@kvark kvark changed the title [WIP] Clip against near plane for bounds calculus Clip against near plane for bounds calculus May 9, 2018
@kvark
Copy link
Member Author

kvark commented May 9, 2018

Inviting reviewers! cc @glennw


// All clipping ClipScrollNodes should have outer rectangles, because they never
// use the BorderCorner clip type and they always have at last one non-ClipOut
// Rectangle ClipSource.
let screen_outer_rect = screen_outer_rect.expect("Clipping node didn't have outer rect.");
let screen_outer_rect = match screen_outer_rect {

This comment has been minimized.

@mrobinson

mrobinson May 9, 2018

Member

Do ClipScrollNodes not always have an outer rectangle now?

This comment has been minimized.

@kvark

kvark May 9, 2018

Author Member

In this code, it may be None if either local_outer_rect of the clip source is None, or the computed bounding rect is outside the screen.

This comment has been minimized.

@mrobinson

mrobinson May 9, 2018

Member

For ClipScrollNodes, the local_outer_rect is never None. We use None to indicate situations where an outer rect cannot be calculated and an empty rectangle to indicate a situation where the clip rect is empty. I think the case where the outer bounds do not intersect with the screen rect is an empty clip rectangle situation. In order to avoid having None do double duty (and subtly breaking other parts of the code), I think we should maintain the expect here and have the non-intersection case produce an empty rectangle.

transform.transform_point2d(&rect.bottom_left()),
transform.transform_point2d(&rect.bottom_right()),
screen_bounds: Option<&DeviceIntRect>,
) -> Option<DeviceIntRect> {

This comment has been minimized.

@mrobinson

mrobinson May 9, 2018

Member

I recall this function as being extremely performance sensitive, so is there any way to have a fast path when it isn't necessary to do all of these calculations?

This comment has been minimized.

@kvark

kvark May 9, 2018

Author Member

The way it's build is to avoid extra steps unless necessary. So the old transform_point2d for each corner is equivalent to transform_point_2d_homogeneous followed by to_point2d at the end.
Extra overhead may come from the following sources:

  1. more stuff being moved around (copies are the doom of Rust code)
  2. comparing 4 f32 values to 0 in homogens.iter().any(|h| h.w <= 0.0)
  3. worse instruction cache utilization for the function body being grown

Overall, I think it's a reasonable compromise, and it's not clear to me if we can do better here.

This comment has been minimized.

@mrobinson

mrobinson May 9, 2018

Member

One thing we could do here is to detect when transformation doesn't project into three dimensions and to use the old code for this situation. You could have this path be an early return and avoid the long if statement in the body.

@kvark
Copy link
Member Author

kvark commented May 9, 2018

I'm a bit puzzled over AppVeyor reftest failure...

Copy link
Member Author

kvark left a comment

The try push also looks good.


// All clipping ClipScrollNodes should have outer rectangles, because they never
// use the BorderCorner clip type and they always have at last one non-ClipOut
// Rectangle ClipSource.
let screen_outer_rect = screen_outer_rect.expect("Clipping node didn't have outer rect.");
let screen_outer_rect = match screen_outer_rect {

This comment has been minimized.

@kvark

kvark May 9, 2018

Author Member

In this code, it may be None if either local_outer_rect of the clip source is None, or the computed bounding rect is outside the screen.

transform.transform_point2d(&rect.bottom_left()),
transform.transform_point2d(&rect.bottom_right()),
screen_bounds: Option<&DeviceIntRect>,
) -> Option<DeviceIntRect> {

This comment has been minimized.

@kvark

kvark May 9, 2018

Author Member

The way it's build is to avoid extra steps unless necessary. So the old transform_point2d for each corner is equivalent to transform_point_2d_homogeneous followed by to_point2d at the end.
Extra overhead may come from the following sources:

  1. more stuff being moved around (copies are the doom of Rust code)
  2. comparing 4 f32 values to 0 in homogens.iter().any(|h| h.w <= 0.0)
  3. worse instruction cache utilization for the function body being grown

Overall, I think it's a reasonable compromise, and it's not clear to me if we can do better here.

@kvark kvark force-pushed the kvark:perspective branch from cf5c87b to 9ed15e4 May 9, 2018
@kvark
Copy link
Member Author

kvark commented May 9, 2018

@mrobinson thanks for taking a look! I think we are all set, unless there are more concerns.

@@ -15,7 +15,7 @@ extern crate core_graphics;
extern crate crossbeam;
#[cfg(target_os = "windows")]
extern crate dwrote;
#[cfg(feature = "logging")]
#[cfg(feature = "env_logger")]

This comment has been minimized.

@mrobinson

mrobinson May 9, 2018

Member

I think this was landed in another patch?

Copy link
Member

mrobinson left a comment

Sorry for the weird review on my part! This is looking pretty reasonable to me, but I have a few minor nits that I think could be addressed before landing.

… where transformed polygons intersect the near plane.
@kvark kvark force-pushed the kvark:perspective branch from 9ed15e4 to cafeb7a May 9, 2018
@kvark
Copy link
Member Author

kvark commented May 9, 2018

@mrobinson
Rebased and fixed the local outer rect now (hopefully).

One thing we could do here is to detect when transformation doesn't project into three dimensions and to use the old code for this situation. You could have this path be an early return and avoid the long if statement in the body.

It would involve more logic duplication and control flow tweaks, so I'm not sure it's worth it. Maybe we can leave a TODO comment in the code saying to keep an eye for this branch when profiling?

@kvark
Copy link
Member Author

kvark commented May 9, 2018

I don't want this to stall any longer.
@bors-servo r=mrobinson

@bors-servo
Copy link
Contributor

bors-servo commented May 9, 2018

📌 Commit cafeb7a has been approved by mrobinson

@bors-servo
Copy link
Contributor

bors-servo commented May 9, 2018

Testing commit cafeb7a with merge fac0040...

bors-servo added a commit that referenced this pull request May 9, 2018
Clip against near plane for bounds calculus

Fixes #2389
Fixes #2272
Improves #2429 a great deal (there are general plane splitting issues in there still)

TODO:
- [x] reviews
- [x] green CI
- [x] try push: https://treeherder.mozilla.org/#/jobs?repo=try&revision=ddccbd9f16aea173fe950293f1a4f429650dea6a

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

bors-servo commented May 9, 2018

☀️ Test successful - status-appveyor, status-taskcluster
Approved by: mrobinson
Pushing fac0040 to master...

@bors-servo bors-servo merged commit cafeb7a into servo:master May 9, 2018
3 checks passed
3 checks passed
Taskcluster (pull_request) TaskGroup: success
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
homu Test successful
Details
@kvark kvark deleted the kvark:perspective branch May 10, 2018
bors-servo added a commit that referenced this pull request Aug 3, 2018
Proper near plane splitting

The PR is built on the shoulders of #2913, #2741, servo/euclid#277, servo/euclid#291, servo/plane-split#12, and (last but not the least!) servo/plane-split#15

It uses the new clipping semantics in `plane-split` crate uniformly for both bounding box computation and 3d plane splitting itself, ensuring that no incorrect perspective divisions are performed (and closing quite a few TODO entries). Also adds a small reftest for the latter.

Fixes #2272

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/2947)
<!-- Reviewable:end -->
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

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