-
Notifications
You must be signed in to change notification settings - Fork 6
understory_imaging #33
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
base: main
Are you sure you want to change the base?
Conversation
| PushClip { | ||
| /// Common header metadata. | ||
| header: OpHeader, | ||
| /// Identifier of the clip shape to push. | ||
| clip: ClipId, | ||
| }, | ||
| /// End a clip stack entry. | ||
| PopClip { | ||
| /// Common header metadata. | ||
| header: OpHeader, | ||
| }, | ||
| /// Begin a compositing group with optional opacity and blend mode. | ||
| Group { | ||
| /// Common header metadata. | ||
| header: OpHeader, | ||
| /// Optional opacity multiplier in [0, 1] for the group. | ||
| opacity: f32, | ||
| /// Blend mode used when compositing the group into its parent. | ||
| blend: BlendMode, | ||
| }, |
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 there should be a push group and a pop group and that clip is just an op that modifies a group. same thing with blend mode and opacity and things like alpha and luminance masks. these should be ops that affect a group. groups get pushed and popped. then when translating to backends, there can be optimization logic for the best api to use given the set of modifiers on a group.
maybe even have an op for group modifiers with a set
Group {
header: OpHeader,
modifiers: Set<GroupModifier>,
}
enum GroupModifier {
Clip(ClipId),
Opacity(f32),
AlphaMask(ImageId),
LuminanceMask(ImageId),
BlendMode(BlendMode),
Transform(Affine),
}
understory_imaging/src/lib.rs
Outdated
|
|
||
| /// Clip shape used by `StateOp::SetClip`. | ||
| /// | ||
| /// This will likely grow variants for rounded rects and more complex regions. |
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.
Indeed! ClipShape::RoundedRect is already in
| let transform = | ||
| imaging::Affine::translate((tx, ty)) * imaging::Affine::scale_non_uniform(w, h); | ||
|
|
||
| if (*opacity - 1.0).abs() > f32::EPSILON { |
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 wonder if opacity needs to be reset (back to 1.0) to avoid leaking state across display-list entries...the conditional SetOpacity only fires when opacity != 1, so an image can drop opacity and nothing bumps it back, leaving later ops dimmer than intended.
70e21a7 to
7b35fa7
Compare
Add understory_imaging imaging IR crate
This PR adds
understory_imaging, a backend‑agnostic imaging IR that sits between the presentation/display layer and concrete render backends (Vello CPU/Hybrid/Classic, Skia, etc.).The crate defines:
PathId,ImageId,PaintId,PictureId,FilterIdwithPathDesc,ImageDesc,PaintDesc,PictureDescdescriptors, managed via aResourceBackendtrait. IDs are small, stable handles reusedacross frames and recordings for the lifetime of each resource.
StateOp(transform, paint, stroke, clip, blend, opacity, groups) andDrawOp(fill/stroke path/rect, draw image/picture), combined into
ImagingOpas a POD‑friendly IR suitable for recordingand caching.
ImagingBackendtrait that extendsResourceBackendwith state/draw entry points and abasic recording API (
begin_record/end_record), plus helpersrecord_opsandrecord_pictureto capture shortsequences as reusable recordings or pictures.
RecordedOpswraps anArc<[ImagingOp]>plus optional backend‑specific acceleration andtransform metadata (
valid_under: TransformClass,original_ctm). Recordings are explicitly environment‑bound:all referenced resource IDs must exist and remain compatible when replayed.
TransformClassandtransform_diff_classprovide a conservative way to decide whencached/recorded content can be safely reused under a new transform (distinguishing exact, translate‑only, and
general affine differences).
The crate is no_std and currently targets the needs of early Vello/Skia backends. The overall goals, architecture, and future directions are documented in
docs/issue_understory_imaging.md; the crate‑level docs give a condensed overview and a minimal usage sketch for backend implementors.