Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upSupport arbitrary tiling origins and negative tile offsets during tile decomposition #3409
Conversation
|
At this stage this passes reftests locally but I still need a try push and some more changes in various other places to really support negative tile offsets in WebRender as well as some plumbing to let blob images pass the right information along and benefit from this. The best way to review this might be to just look at the new code since it is similar but subtly different from the way it worked previously and almost every line in this change is important. I added some ascii diagrams in an attempt to make some things easier to understand but it's hard to tell whether it'll help anyone but me. Let me know if they make things worse and I'll remove my scribbles. |
b3ab003
to
5a73e29
|
I think that I figured all of the remaining reftest failures out, let's see if this try push comes back green: https://treeherder.mozilla.org/#/jobs?repo=try&revision=b5be9a0bc5f9d4102340d90eb9766f1b30a39026 |
|
The try push is green. |
|
@nical Did you have someone specifically in mind to review this? I can take a look over it if needed, although I'm quite out of the loop on the blob re-coord changes, which I think this is for? |
|
@glennw I think that anybody who understands (or want to understand) how tile decomposition works is a good fit for this review. This PR doesn't have much of the blob recoordination in it but it takes a somewhat hairy bag of arithmetic and adds a few extra parameters so the tile decomposition aspect is more important than the overall recoordination stuff. If nobody volunteers for the review I'd nominate either @kvark or you (as you two tend to do a lot of the webrender reviews) or @jrmuizel. |
|
Mainly just nits, looks good to me. Probably worthwhile getting someone else to look too though. |
|
|
||
| let mut segment_rect = LayoutRect { | ||
| origin: LayoutPoint::new( | ||
| self.local_origin.x + tile_offset.x as f32 * self.tile_size.width, | ||
| self.local_origin.y + tile_offset.y as f32 * self.tile_size.height, | ||
| self.local_origin.x + tile_offset.x as f32 * self.regular_tile_size.width, |
This comment has been minimized.
This comment has been minimized.
jamienicol
Jan 4, 2019
Contributor
Does this not have to take in to account the first_tile_layout_size?
This comment has been minimized.
This comment has been minimized.
| // the latters can have image bounds with negative values (the blob image's | ||
| // visible area provided by gecko). | ||
| // | ||
| // Likewise, the alyout space tiling origin (layout position of tile offset |
This comment has been minimized.
This comment has been minimized.
| layer_tile_size.height * leftover_device_size.height as f32 / device_tile_size_f32, | ||
| ); | ||
| // The decomposition logic is exactly the same on each axis so we reduce | ||
| // this to a 1-dimmensional problem in an attempt to make the code simpler. |
This comment has been minimized.
This comment has been minimized.
| local_origin: prim_rect.origin, | ||
| } | ||
| } | ||
|
|
||
| /// Decompose tiles along an arbitray axis. |
This comment has been minimized.
This comment has been minimized.
jamienicol
Jan 4, 2019
Contributor
I don't think the ascii art is necessary to explain what treating the problem in one dimension means. The "why" is more important (like you explained above)
This comment has been minimized.
This comment has been minimized.
|
|
||
| // The visible tiles (because of culling). | ||
| // | ||
| // Here we don't need to do the off by one dance we did above because f32::floor |
This comment has been minimized.
This comment has been minimized.
jamienicol
Jan 4, 2019
Contributor
I think you're referring to the division in first_and_last_tile_1d? This isn't "above" (maybe it was then you refactored that in to a separate function?).
In any case, it'd be more useful to say what the behaviour is (round to -infinity) than just it's what we want
This comment has been minimized.
This comment has been minimized.
| let first_visible_tile = f32::floor((layout_visible_range.start - layout_tiling_origin) / layout_tile_size) as i32; | ||
| let last_visible_tile = f32::floor((layout_visible_range.end - layout_tiling_origin) / layout_tile_size) as i32; | ||
|
|
||
| // Combine the above two to get the tiles in the image that are visible this frame. |
This comment has been minimized.
This comment has been minimized.
jamienicol
Jan 4, 2019
Contributor
nit: Maybe "intersect" instead of "combine"? And delete the blank line
| image_range: &Range<i32>, | ||
| regular_tile_size: i32, | ||
| ) -> i32 { | ||
| // We have to account for how the modulo operation behaves for negative values. |
This comment has been minimized.
This comment has been minimized.
jamienicol
Jan 4, 2019
Contributor
I think technically the issue is % is a remainder operator rather than modulo, and we want modulo, so we need the extra code. might be better to say that instead.
|
|
||
| // Most tiles are going to have base_size as width and height, | ||
| // except for tiles around the edges that are shrunk to fit the image data | ||
| // (See decompose_tiled_image in frame.rs). |
This comment has been minimized.
This comment has been minimized.
jamienicol
Jan 4, 2019
Contributor
neither decompose_tiled_image nor frame.rs exist. should this just be tiles() (in the same file now this function has moved)
|
|
||
| #[test] | ||
| #[ignore] | ||
| fn failing_doubly_partial_tiles() { |
This comment has been minimized.
This comment has been minimized.
jamienicol
Jan 4, 2019
Contributor
can we not just always min(m, image_size) for all cases of the match statements in first/last_tile_size_1d?
This comment has been minimized.
This comment has been minimized.
|
I addressed the review comments. I won't be near a computer this weekend so let's wait until Monday before landing this, just to be on the safe side. |
|
Looks pretty neat! Left my notes below
webrender/src/image.rs, line 187 at r2 (raw file):
would be good to also return webrender/src/image.rs, line 193 at r2 (raw file):
might be cleaner to just compute the row flags each iteration instead of trying to preserve them webrender/src/image.rs, line 282 at r2 (raw file):
looks like a constructor method would be helpful webrender/src/image.rs, line 360 at r2 (raw file):
good stuff webrender/src/image.rs, line 383 at r2 (raw file):
there is something disturbing to me in the way the code handles inclusive/exclusive ranges. So For example: let layout_tiling_origin = 0;
let layout_tile_size = 10.0;
let layout_visible_range.end = 20;What the algorithm needs to produce is that 2 tiles are visible, but it will end up considering 3 tiles to be visible. webrender/src/image.rs, line 388 at r2 (raw file):
should we webrender/src/image.rs, line 406 at r2 (raw file):
nit: webrender/src/image.rs, line 441 at r2 (raw file):
This is not entirely correct. If both webrender/src/image.rs, line 504 at r2 (raw file):
it looks like most of this function could also be well separated by axis webrender/src/image.rs, line 519 at r2 (raw file):
this is not an elegant use of |
webrender/src/image.rs, line 187 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/image.rs, line 193 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Agreed. webrender/src/image.rs, line 282 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
If it's used in only one place in the same file I don't feel much need for it. webrender/src/image.rs, line 383 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
You are right. In fixing that i rewrote it to use [a..b[ kind of exclusive ranges everywhere. Not sure whether it's simpler but it's at least more consistent. webrender/src/image.rs, line 388 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I wonder if this can happen in edge-casey clipping conditions, I'd rather not assert in doubt. If this happens it means everything is clipped out and the tile iterator will None at its first iteration which is what one would expect. webrender/src/image.rs, line 441 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Nice catch. webrender/src/image.rs, line 519 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I did originally and found this version easier to read but I don't feel strongly enough to get into an argument about it. |
webrender/src/image.rs, line 383 at r2 (raw file): Previously, nical (Nicolas Silva) wrote…
much better now, thank you! webrender/src/image.rs, line 441 at r2 (raw file): Previously, nical (Nicolas Silva) wrote…
I think it's still wrong though: let regular_tile_size = 10;
let image_range.end = -10;
let end = -1; // computed
if (image_range.end % regular_tile_size == 0) == (image_range.end < 0) { } // returns truewe'll end up with I believe the condition should just be |
Add Rect::x_range/y_range. A little goodie that would be useful in servo/webrender#3409. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/euclid/313) <!-- Reviewable:end -->
Add Rect::x_range/y_range. A little goodie that would be useful in servo/webrender#3409. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/euclid/313) <!-- Reviewable:end -->
webrender/src/image.rs, line 383 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yeah I'll add some tests shortly. webrender/src/image.rs, line 441 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Indeed, thanks! |
|
Alright, looks like only some extra tests are missing, and the logic is good.
|
|
|
nical commentedDec 13, 2018
•
edited by larsbergstrom
The tile decomposition code is rewritten to support:
This code is a bit trickier than it would seem at first due to how we have to tile in two spaces (image and layout) at the same time in order to get boundary tiles and culling right. Since the problem is exactly the same along each axis I reduced it to 1 dimension in to reduce the complexity and likelihood of copy-pasta accidents.
This change is