Skip to content

sparse_strips: Add more new/refactored code into vello_common#1745

Open
LaurenzV wants to merge 14 commits into
laurenz/vello_hybrid_shift_part1from
laurenz/vello_hybrid_shift_part2
Open

sparse_strips: Add more new/refactored code into vello_common#1745
LaurenzV wants to merge 14 commits into
laurenz/vello_hybrid_shift_part1from
laurenz/vello_hybrid_shift_part2

Conversation

@LaurenzV

@LaurenzV LaurenzV commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

This PR is based on #1744 and introduces some actual changes, once again in preparation for the Vello Hybrid rewrite.

The first commit adds some utility types like Offset and Size, which will layer on be used by Vello Hybrid (they are currently partially duplicated there, but I will just remove them later on). In theory they could just live in Vello Hybrid, but since we already have RectU16 in vello_common I figured this is the best place.

The second commit resolved a TODO and creates a new generic method that allows generating fill/alpha-fill sequences from a slice of strips. We also use this for the existing strip_bbox function now. I'm aware that this will result in a slight slowdown since we will do the clipping even though it isn't necessary to clip anything since we are just calculating the bbox, but I think it's better to accept this cost for less code duplication.

The third commit extracts all of the transforms we currently have into a custom struct, so that, once again, they can more easily be used by Vello Hybrid.

Fourth commit introduces a new ViewportState abstraction, that abstracts all of the complexity of handling different viewport so that Vello Hybrid can use this as well.

Fifth commit adds a way of querying whether an encoded paint has any opacities directly.

PR train

  1. sparse_strips: Move some code from vello_cpu to vello_common #1744 — Move some code from vello_cpu to vello_common
  2. sparse_strips: Add more new/refactored code into vello_common #1745 — Add more new/refactored code into vello_common 👈
  3. vello_common: Generalize the command recorder abstraction and add more metadata #1746 — Generalize the command recorder abstraction and add more metadata
  4. sparse_strips: Introduce Padding type and streamline clip handling #1751 — Introduce Padding and streamline clip handling

// TODO: Remove these types once we've completely moved to u16 everywhere in Vello Hybrid.

/// An offset represented by two 32-bit unsigned integers.
#[repr(C)]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These types are likely temporary and we will use u16 where possible. Unfortunately, right now we kind of convert between u16 and u32 in all kinds of different places even though it could be more unified, but I want to leave this cleanup to the future.

@laurenz-canva
laurenz-canva force-pushed the laurenz/vello_hybrid_shift_part2 branch from 86cb568 to d10a407 Compare July 15, 2026 11:12
@laurenz-canva
laurenz-canva force-pushed the laurenz/vello_hybrid_shift_part2 branch from d10a407 to 3f61c40 Compare July 16, 2026 08:14
match self {
Self::Gradient(gradient) => !gradient.may_have_transparency,
Self::Image(image) => !image.may_have_transparency,
Self::ExternalTexture(_) => false,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Need to implement this for external textures as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have a single method here that indicates whether opaque paint optimizations can be used in cpu/hybrid?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? Isn't it the same across CPU/Hybrid? I just need to make sure to read the field from the external texture.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I presume you meant something like this? 😄 : 90705e6

#[derive(Copy, Clone, Debug, Pod, Zeroable, PartialEq, Eq)]
pub struct SizeU16(pub [u16; 2]);

impl SizeU16 {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it, the U32 types below will be removed later? If so, do you think it's still worth introducing generic Size<T> and Rect<T> types?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also considered this but probably not. For now it's easier to just keep it this way. 😄

/// Return this rectangle relative to `origin`, clamping negative coordinates to zero.
#[inline(always)]
pub const fn relative_to_origin(self, origin: (u16, u16)) -> Self {
pub fn relative_to_origin(self, origin: (u16, u16)) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a couple of small tests for this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add two tests.

type Output = Self;

fn add(self, rhs: Self) -> Self::Output {
Self::from_wh(self.width() + rhs.width(), self.height() + rhs.height())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should ever overflow in our cases, but in theory it could. Maybe it's worth adding a short comment noting that it wraps on overflow in release

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll turn it into a checked add.

match self {
Self::Gradient(gradient) => !gradient.may_have_transparency,
Self::Image(image) => !image.may_have_transparency,
Self::ExternalTexture(_) => false,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have a single method here that indicates whether opaque paint optimizations can be used in cpu/hybrid?

Comment thread sparse_strips/vello_common/src/strip.rs Outdated
}

/// Return the currently active root transform.
pub fn root_transform(&self) -> Affine {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think cumulative_transform would be a better name, wouldn't it? When I read root_transform, I think of a single fixed top-level transform. In reality, this represents the cumulative transform, so root_transform feels a bit misleading from that point of view. Would the Cumulative prefix make the intent clearer for this type?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I can change, but I think root_transform makes sense. It represents the root transform for the currently active filter viewport that should be used as the basis for any subsequent path/paint transforms.

Comment thread sparse_strips/vello_cpu/src/coarse/bucketer.rs Outdated
Comment thread sparse_strips/vello_hybrid/src/scene.rs Outdated
Comment thread sparse_strips/vello_hybrid/src/scene.rs Outdated
Comment thread sparse_strips/vello_common/src/transforms.rs
@grebmeg

grebmeg commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Thanks for your work! Everything looks much tidier now 🤩 I left a few comments, but they're mostly minor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants