-
Notifications
You must be signed in to change notification settings - Fork 143
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
Update piet-scene to depend on peniko #208
Conversation
This adds a new dependency on peniko, reintroduces kurbo for geometry (!), removes the now defunct types from piet-scene and updates all the test scenes to use the new types.
|
Right, thanks. To expand on this a bit, piet-scene currently contains a set of types for defining rendering and composition state (brushes, blend modes, stroke/fill styles, etc) along with it's own geometry types (point, matrix). This lifts the former set of types to the peniko crate which now depends on kurbo for the latter set. The goal of all this is to both reintroduce kurbo to piet-gpu and to provide a separate crate for these "styling" types that can be used across the ecosystem. At the very least, parley (text layout), the font enumeration library, and the oxidize glyph loader will make use of this. |
also removes some annoying lingering tabs from blend.wgsl
This is now ready to go. linebender/xilem#1 will need changes after this lands. Also depends on linebender/glazier#33 to sync kurbo versions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looks good, but I want to understand empty clip paths.
@@ -28,7 +28,6 @@ path = "../piet-gpu-types" | |||
|
|||
[dependencies.piet-scene] | |||
path = "../piet-scene" | |||
features = ["kurbo"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
piet-scene/src/scene/builder.rs
Outdated
use smallvec::SmallVec; | ||
|
||
/// Builder for constructing a scene or scene fragment. | ||
pub struct SceneBuilder<'a> { | ||
scene: &'a mut SceneData, | ||
layers: SmallVec<[BlendMode; 8]>, | ||
layers: SmallVec<[(BlendMode, bool); 8]>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally would find it useful to have a comment what the bool means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
E: Iterator, | ||
E::Item: Borrow<PathElement>, | ||
{ | ||
fn encode_path(&mut self, shape: &impl Shape, is_fill: bool) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is another place where I'd like a comment explaining the bool result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A further thought on this: when reading through kurbo code, I noticed that it treats a line/quad/curve at the start of a path as a move. This code currently assumes an implicit move to (0,0) in that case. Should I update this to be consistent with kurbo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm slightly confused what you're asking. In BezPath
builder methods, there's a debug assert against that (I consider it an invalid state). I think a reason to have an implicit move of (0, 0) is so you don't get an invalidly encoded path as output even when the input is wrong, but the exact value of what you get is not too important, people shouldn't be relying on it.
But perhaps I'm just misunderstanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It specifically noted for the Shape impl for slices here: https://github.com/linebender/kurbo/blob/fd839c25ea0c98576c7ce5789305822675a89938/src/bezpath.rs#L1177
The logic is implemented in the Segments iterator. FWIW, I think SVG does the same but I’d have to check the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, this behavior was changed in linebender/kurbo#98. That particular use case doesn't seem too important here, but probably having fewer different behaviors is better.
piet-scene/src/scene/builder.rs
Outdated
self.begin_clip(blend); | ||
self.layers.push((blend, true)); | ||
} else { | ||
// When the layer has an empty path, record an entry to prevent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm confused what the semantics should be for an empty path. Putting blends aside, clipping to an empty path should suppress rendering of the children altogether (not super useful, but it should do the right thing). Here it seems it renders the children without a clip.
For blends, the path given should enclose the content, so an empty path with nonempty content is a client bug. I'm less concerned about correct semantics in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I waffled on this as well but I agree with your reasoning here. I’ll encode a valid empty path here in the case of clips
return mix( | ||
screen(cb, 2.0 * cs - 1.0), | ||
cb * 2.0 * cs, | ||
return mix( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Completely unrelated, but I think these should be select
rather than mix
, as the selector really is boolean. I have a draft patch with this change, simplification of vec3
where it's not needed, and fixes to make it more wgsl-analyzer friendly, but haven't pushed the patch because wgsl-analyzer still has some trouble.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. This is mostly a direct port of the GLSL where ?: doesn’t work like that.
piet-gpu/src/samples.rs
Outdated
None, | ||
make_diamond(1024.0, 100.0), | ||
&&make_diamond(1024.0, 100.0)[..], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double-ampersands not needed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. Missed those when I was updating.
piet-gpu/src/samples.rs
Outdated
None, | ||
&path, | ||
&&path[..], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently the double-ampersand is needed here, but it looks very strange. I didn't investigate too deeply whether there's a more ergonomic way to write this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can impl Shape for Vec<PathEl>
in kurbo to fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm. The way I've dealt with this in the path is use BezPath
which is basically just a newtype for that, and I think I wanted to encourage people to use that rather than the raw vec. So I think the most idiomatic way to write this in this function is path = BezPath::new()
.
I don't want to rathole on this too much, but I do find that sample code often has a disproportionate impact, as people often use it as a starting point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough! I believe it’s just a drop in replacement anyway.
Very happy for this to go in once my review comments are addressed. I'll be around to do an approve quickly. |
This should be ready now. For the invalid layer shape case, I decided to encode an empty path regardless of whether it's a clip or blend. This makes sense since blends are also clips in the valid case. In the future, I'd also like to consider moving the blend mode syncing between BeginClip/EndClip to the clip_leaf shader where path_ix is copied over. This would remove the need for accounting on the encoding side. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
I think moving the blend mode syncing into clip_leaf makes sense but haven't thought it through in detail.
This adds a new dependency on peniko, reintroduces kurbo for geometry (!), removes the now defunct types from piet-scene and updates all the test scenes to use the new types.
There is unfortunately a lot of churn here, but most of the changes should be relatively simple.
Depends on linebender/peniko#1