-
Notifications
You must be signed in to change notification settings - Fork 7
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
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
6a0e267 to
0ea6c2a
Compare
| // If new formats are added upstream, prefer failing loudly until | ||
| // we define v0 behavior for them. | ||
| _ => sk::ColorType::RGBA8888, |
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.
Should "failing loudly" be an explicit panic? Handling the format wrong would likely cause panics further down the road.
understory_imaging/src/lib.rs
Outdated
| /// Set the current clip shape. | ||
| SetClip(ClipShape), |
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 may want an operation that says whether clipping is to be anti-aliased or not, for backends that make a distinction (like Skia), or we may want to say that backends should use the highest-quality clipping available.
understory_imaging_skia/src/lib.rs
Outdated
| let rect = sk::Rect::new(x0, y0, x1, y1); | ||
| let mut path = sk::Path::new(); | ||
| path.add_round_rect(rect, (radius_x, radius_y), None); | ||
| self.canvas.save(); | ||
| self.canvas.clip_path(&path, None, true); | ||
| self.clip_depth = self.clip_depth.saturating_add(1); |
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.
Skia supports rounded rectangle clips, so I think this can be something like the following.
| let rect = sk::Rect::new(x0, y0, x1, y1); | |
| let mut path = sk::Path::new(); | |
| path.add_round_rect(rect, (radius_x, radius_y), None); | |
| self.canvas.save(); | |
| self.canvas.clip_path(&path, None, true); | |
| self.clip_depth = self.clip_depth.saturating_add(1); | |
| let rect = sk::Rect::new(x0, y0, x1, y1); | |
| let rrect = sk::RRect::new_rect_xy(&rect, radius_x, radius_y); | |
| self.canvas.save(); | |
| self.canvas.clip_rrect(&rrect, None, true); | |
| self.clip_depth = self.clip_depth.saturating_add(1); |
3fa539d to
cc00e12
Compare
7b533e0 to
d374a23
Compare
3a2ff02 to
f79a77f
Compare
Introduce a backend-agnostic, POD-friendly imaging IR and initial backends. - Add `understory_imaging` crate: resources, state/draw ops, recordings, transform classes - Add backends: `understory_imaging_vello`, `understory_imaging_vello_cpu`, `understory_imaging_skia` - Add `understory_imaging_ref` for tests/experimentation - Add `understory_text_imaging` helpers for lowering text/COLRv1/bitmaps into imaging ops - Add imaging examples (basics/images/gradients/pictures) and repo-local font fixtures under `assets/` This is an initial v0 drop (0.0.1) and is expected to evolve as we integrate display/presentation.
f79a77f to
e272519
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.