Skip to content

Use RenderContext to own resource lifecycle outside of scene rendering#45

Open
taj-p wants to merge 6 commits intoDioxusLabs:mainfrom
taj-p:tajp/renderContext2
Open

Use RenderContext to own resource lifecycle outside of scene rendering#45
taj-p wants to merge 6 commits intoDioxusLabs:mainfrom
taj-p:tajp/renderContext2

Conversation

@taj-p
Copy link
Collaborator

@taj-p taj-p commented Feb 12, 2026

Refactors RenderContext from being owned by renderer internals into a standalone, consumer-owned object passed by reference. This makes resource (image) lifetime management explicit and removes the burden of managing resource maps and ID counters from consumers.

Previously, Vello Hybrid would leak images. This changes enables consumers for explicitly managing image resource lifecycle.

Design Decisions

Deferred vs Eager Image Upload

There is a tension with the initial implementation and the introduction of RenderContext. The anyrender_svg crate was uploading images to the GPU as soon as it encountered an image node. It is likely preferential to bulk/batch upload images to the GPU rather than creating a per-image command encoder.

For now, we've stuck with the eager strategy, but I imagine there's an opportunity here to iterate the design to support deferred upload. I think this is a step in the right direction, regardless.

It should be noted that the current design supports both eager and deferred upload. To defer upload, simply register_image in Vello Hybrid prior to rendering some scene.

@taj-p taj-p changed the title [WIP] Use RenderContext to own resource lifecycle outside of scenes Use RenderContext to own resource lifecycle outside of scene rendering Feb 12, 2026
@taj-p taj-p requested a review from nicoburns February 12, 2026 17:50
Copy link
Contributor

@nicoburns nicoburns left a comment

Choose a reason for hiding this comment

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

This is not a fully comphrensive review, but I've left some thoughts

self.next_resource_id += 1;

let image_source = ImageSource::from_peniko_image_data(&image);
self.resource_map.insert(resource_id, image_source);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this ought to check whether the image is already registered (using the ImageData's id as a key). And avoid re-registering it in that case. That would save (each time an image is re-rendered):

  • An expensive premultiply and reallocate for Vello CPU
  • Texture upload for Vello Hybrid
  • Conversion to SkImage for Skia

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That would save (each time an image is re-rendered):

This part isn't quite true. This would only occur if a caller re-registers the same image duplicately - not for every render. The caller shouldn't be calling these duplicately (and to do so might imply incorrect usage).

Happy to add in a defensive layer. From my perspective of using AnyRender for testing/benchmarking, it doesn't impact my usage.

Comment on lines +54 to +56
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
&mut self,
ctx: &mut Self::Context,
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to have the WindowRenderer/ImageRenderer own the impl RenderContext rather than passing it in here? Then (with the current design), it wouldn't need to be in the API of these traits at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

Then (with the current design), it wouldn't need to be in the API of these traits at all.

Having said that, I wonder whether the "draw callback" (FnOnce(&mut Self::ScenePainter<'_>)) ought to be bounded by PaintScene + RenderContext rather than just PaintScene. Then it would be on callers to register resources rather than something handled internally by the ScenePainters...

But maybe that doesn't make sense if you then need a type that impl's PaintScene + RenderContext anyway?

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