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

Remove manual interpolation of local space in transform shaders. #2069

Merged
merged 2 commits into from Nov 22, 2017

Conversation

@glennw
Copy link
Member

glennw commented Nov 21, 2017

Instead, for vertex transform shaders we now write out:
(world.xy, z * world.w, world.w)

This gives us constant Z across the polygon for draw ordering.

It also means we can use the hardware interpolators instead of
manually dividing by Z in the fragment shader for local_pos.

This is mostly preparation work for switching shaders over to
be brush primitives, but has the happy side effect of:

  • Fixing a small number of Gecko + Servo reftests.
  • Simpler and faster code.

This change is Reviewable

@glennw
Copy link
Member Author

glennw commented Nov 21, 2017

r? @kvark

New passes in Servo:
PASS [expected FAIL] /css/css-transforms/css-transforms-3d-on-anonymous-block-001.html
PASS [expected FAIL] /_mozilla/css/transform_skew_a.html

New passes in Gecko:
transform-3d/split-non-ortho1.html

Gecko try is here (looks to be all green except for the PASS above and intermittents):
https://hg.mozilla.org/try/rev/9d2110ecd88f77aec63dd5cfd8c0d58ce08b1128
https://treeherder.mozilla.org/#/jobs?repo=try&revision=9d2110ecd88f77aec63dd5cfd8c0d58ce08b1128

@glennw
Copy link
Member Author

glennw commented Nov 21, 2017

There's clearly some more tidy up that can be done as a follow up with this change (e.g. we could unify write_vertex and write_transform_vertex quite easily), but I think it's reasonable to do those as follow ups as we switch primitives over to be brush shaders.

@glennw
Copy link
Member Author

glennw commented Nov 21, 2017

To save any more rebase hassles for @lsalzman, we should make sure #2058 lands before this (I'll rebase on that if needed, but review of this should still be fine in the meantime).

@bors-servo
Copy link
Contributor

bors-servo commented Nov 21, 2017

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

@glennw glennw force-pushed the glennw:xf branch from 32500f9 to 3f2464a Nov 21, 2017
@glennw
Copy link
Member Author

glennw commented Nov 21, 2017

Rebased over the rotated text PR.

@kvark
Copy link
Member

kvark commented Nov 21, 2017

I really like where this is going! 👍
A few concerns need to be cleared out though.


Reviewed 14 of 14 files at r1.
Review status: all files reviewed at latest revision, 8 unresolved discussions.


webrender/res/prim_shared.glsl, line 652 at r1 (raw file):

    // Calculate a clip rect from local_rect + local clip + layer clip.
    RectWithEndpoint local_rect = to_rect_with_endpoint(instance_rect);
    local_rect.p0 = clamp_rect(local_rect.p0, local_clip_rect);

can we just clamp to clip_rect instead?


webrender/res/prim_shared.glsl, line 665 at r1 (raw file):

    // can do some math on the projection matrix to work out a variable
    // amount to extrude.
    float extrude_distance = 4.0;

I'm still a bit confused about 4 here. I'd prefer us either to be precise for the simple case only (of 1:1 scale with the screen, so that the extrude = 0.5), or for the general case, but not for an arbitrary point in-between.


webrender/res/prim_shared.glsl, line 665 at r1 (raw file):

    // can do some math on the projection matrix to work out a variable
    // amount to extrude.
    float extrude_distance = 4.0;

TODO (possibly, for myself): use clip_edge_mask here


webrender/res/prim_shared.glsl, line 688 at r1 (raw file):

    // Apply offsets for the render task to get correct screen location.
    gl_Position.xy += task.common_data.task_rect.p0 - task.content_origin;

interesting, so this is changing the semantics: before we had translation to the target space followed by uTransform, now we have the opposite order


webrender/res/prim_shared.glsl, line 704 at r1 (raw file):

        prim.local_rect,
        prim.local_clip_rect,
        vec4(1.0),

why is this changed?


webrender/res/prim_shared.glsl, line 823 at r1 (raw file):

}

float init_transform_fs(vec2 local_pos) {

sweeet!


webrender/res/ps_image.glsl, line 87 at r1 (raw file):

    // We clamp the texture coordinate calculation here to the local rectangle boundaries,
    // which makes the edge of the texture stretch instead of repeat.
    vec2 upper_bound_mask = step(vLocalRect.zw, vLocalPos);

hmm, this would give us a different position, wouldn't it?
previous code used perspective division here in FS, the new code uses non-perspective interpolated XY


wrench/reftests/transforms/perspective.png, line 0 at r1 (raw file):
so I assume you needed to change this because now it's no longer perspective...


Comments from Reviewable

@glennw
Copy link
Member Author

glennw commented Nov 21, 2017

Review status: 11 of 15 files reviewed at latest revision, 8 unresolved discussions.


webrender/res/prim_shared.glsl, line 652 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

can we just clamp to clip_rect instead?

Done.


webrender/res/prim_shared.glsl, line 665 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

I'm still a bit confused about 4 here. I'd prefer us either to be precise for the simple case only (of 1:1 scale with the screen, so that the extrude = 0.5), or for the general case, but not for an arbitrary point in-between.

It's a bit of extra work to determine if we have a super-simple case that needs a minimal extrude (this is only in the transform path, so a simple case with no rotation etc is already going through the path with no-extrude at all). I dropped it to 2 pixels for now, which seems to still give good results on weird perspective transforms, but reduce the extra edge pixels. I think a 2 pixel edge in the case of a rotation / perspective is OK to pay for now, as a conservative approximation, since we don't pay the cost for non-transformed primitives?


webrender/res/prim_shared.glsl, line 688 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

interesting, so this is changing the semantics: before we had translation to the target space followed by uTransform, now we have the opposite order

Oops, fixed.


webrender/res/prim_shared.glsl, line 704 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

why is this changed?

I think this was a bug - it meant that images weren't using the local rect to get AA edges for. This was causing the extra edge drawing on the perspective reftest below. Unless I'm misunderstanding something?


webrender/res/prim_shared.glsl, line 823 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

sweeet!

Done.


webrender/res/ps_image.glsl, line 87 at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

hmm, this would give us a different position, wouldn't it?
previous code used perspective division here in FS, the new code uses non-perspective interpolated XY

I don't think so - that value should now be perspective interpolated, right? Since we provide the W value from the vertex shader?


wrench/reftests/transforms/perspective.png, line at r1 (raw file):

Previously, kvark (Dzmitry Malyshau) wrote…

so I assume you needed to change this because now it's no longer perspective...

There's a few tiny differences in the pixel output, but mostly this was due to the fix of the default mask value you commented on above.


Comments from Reviewable

@glennw
Copy link
Member Author

glennw commented Nov 21, 2017

@kvark Thanks for the review. I've fixed up or answered those items. I'll hold off on a try run until the discussions above are resolved (not sure if those answer your questions or if more changes are needed). Once I get r=you, then I'll do a try run and merge if green.

gw3583 added 2 commits Nov 21, 2017
Instead, for vertex transform shaders we now write out:
 (world.xy, z * world.w, world.w)

This gives us constant Z across the polygon for draw ordering.

It also means we can use the hardware interpolators instead of
manually dividing by Z in the fragment shader for local_pos.

This is mostly preparation work for switching shaders over to
be brush primitives, but has the happy side effect of:

 * Fixing a small number of Gecko + Servo reftests.
 * Simpler and faster code.
@glennw glennw force-pushed the glennw:xf branch from d09d84e to 0aebe2b Nov 21, 2017
@glennw
Copy link
Member Author

glennw commented Nov 22, 2017

@kvark
Copy link
Member

kvark commented Nov 22, 2017

:lgtm:


Reviewed 4 of 4 files at r3.
Review status: all files reviewed at latest revision, 4 unresolved discussions.


webrender/res/prim_shared.glsl, line 665 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

It's a bit of extra work to determine if we have a super-simple case that needs a minimal extrude (this is only in the transform path, so a simple case with no rotation etc is already going through the path with no-extrude at all). I dropped it to 2 pixels for now, which seems to still give good results on weird perspective transforms, but reduce the extra edge pixels. I think a 2 pixel edge in the case of a rotation / perspective is OK to pay for now, as a conservative approximation, since we don't pay the cost for non-transformed primitives?

strictly speaking, sqrt(2)/2 should be enough for rotations only. We'll follow up with possibly better heuristic later, as discussed on IRC


webrender/res/prim_shared.glsl, line 704 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

I think this was a bug - it meant that images weren't using the local rect to get AA edges for. This was causing the extra edge drawing on the perspective reftest below. Unless I'm misunderstanding something?

1.0 means using instance rect for clipping, 0.0 means using the primitive rect
I believe I put 1.0 there for compatibility with the old code, so this is perfectly fine to fix/reconsider here


webrender/res/ps_image.glsl, line 87 at r1 (raw file):

Previously, glennw (Glenn Watson) wrote…

I don't think so - that value should now be perspective interpolated, right? Since we provide the W value from the vertex shader?

I forgot that old W==1, thanks for the explanation :)


Comments from Reviewable

@kvark
Copy link
Member

kvark commented Nov 22, 2017

Great stuff, and thanks for addressing the comments!
@bors-servo r+

@bors-servo
Copy link
Contributor

bors-servo commented Nov 22, 2017

📌 Commit 0aebe2b has been approved by kvark

@bors-servo
Copy link
Contributor

bors-servo commented Nov 22, 2017

Testing commit 0aebe2b with merge e83612d...

bors-servo added a commit that referenced this pull request Nov 22, 2017
Remove manual interpolation of local space in transform shaders.

Instead, for vertex transform shaders we now write out:
 (world.xy, z * world.w, world.w)

This gives us constant Z across the polygon for draw ordering.

It also means we can use the hardware interpolators instead of
manually dividing by Z in the fragment shader for local_pos.

This is mostly preparation work for switching shaders over to
be brush primitives, but has the happy side effect of:

 * Fixing a small number of Gecko + Servo reftests.
 * Simpler and faster code.

<!-- 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/2069)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Nov 22, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: kvark
Pushing e83612d to master...

@bors-servo bors-servo merged commit 0aebe2b into servo:master Nov 22, 2017
4 of 5 checks passed
4 of 5 checks passed
code-review/reviewable 4 discussions left (glennw, kvark)
Details
Taskcluster (pull_request) TaskGroup: success
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@staktrace
Copy link
Contributor

staktrace commented Nov 29, 2017

@glennw This PR caused some regressions on the gecko side, I confirmed the range for https://bugzilla.mozilla.org/show_bug.cgi?id=1420748 and https://bugzilla.mozilla.org/show_bug.cgi?id=1420754 but likely https://bugzilla.mozilla.org/show_bug.cgi?id=1421526 is also the same problem.

@kvark
Copy link
Member

kvark commented Nov 29, 2017

Thanks @staktrace ! I moved this into a separate issue #2133

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

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