How should Blitz consume renderer-owned textures through AnyRender's resource API?
- Dominant language
- Rust
- Stars
- 4.1k
- Forks
- 203
- Avg merge
- 8h 58m
- Merged PRs (30d)
- 112
Description
## Use case
I am using Blitz with a custom AnyRender backend. The host application already owns and manages its textures on the GPU.
HTML and CSS should continue to use ordinary image URLs:
```html
```
```css
.panel {
background-image: url("./b.jpg");
}
```
These URLs should go through Blitz's normal URL resolution. After a URL has been resolved, I need the host application to be able to map it to an existing renderer-owned texture. I do not want to introduce a custom URI scheme, custom element, custom attribute, or rewritten image URL.
The important point is that the resolved URL identifies an image resource, but the host may already have that image as a GPU texture. Requiring encoded image bytes would force the host to copy texture data back to the CPU, let Blitz decode it, and then upload a duplicate texture.
## What I found
My understanding of the current standard image path is:
```text
ordinary image URL
-> NetProvider / NetHandler
-> encoded CPU bytes
-> Blitz decodes the image
-> CPU-backed raster image
-> AnyRender image paint
```
This works well as the default behavior for PNG, JPEG, WebP, and other encoded image files.
AnyRender also appears to support renderer-owned resources through `RenderContext::try_register_custom_resource()`, `ResourceId`, and `Paint::Resource`. The `wgpu_texture` example demonstrates that a custom widget can register a native texture and paint it as an AnyRender resource.
What I could not find is a way to use this resource-backed path for Blitz's normal image handling. In particular, I want ordinary URLs used by ``, CSS backgrounds, and CSS masks to retain their normal Blitz layout and painting behavior while resolving to `Paint::Resource` rather than requiring CPU image bytes.
## Desired extension point
Would it be possible for Blitz to provide a replaceable image provider that is called for a normally resolved image URL?
The default provider could preserve the existing behavior: load encoded bytes, decode them on the CPU, and produce the normal raster image.
A custom provider could instead resolve the same ordinary URL to a renderer-owned image resource. Such a result would need to expose enough information for Blitz to perform normal image layout and invalidation, including:
- the AnyRender `ResourceId` used for painting;
- intrinsic width and height;
- a revision or equivalent invalidation mechanism for dynamic content;
- a way to release the resource when Blitz no longer retains it.
Conceptually, the desired flow is:
```text
./a.png
-> Blitz performs normal URL resolution
-> configurable image provider receives the resolved URL
-> provider returns a renderer-owned image resource
-> Blitz keeps its standard / background / mask behavior
-> Blitz paints the image through Paint::Resource
-> custom AnyRender backend resolves ResourceId to the native texture
```
I am not proposing a particular Rust trait or ownership implementation here. I would like to understand which existing layer is intended to provide this extension point, or what abstraction would fit the current Blitz and AnyRender architecture.
## Questions
1. Is there already a supported way for Blitz's standard image pipeline to resolve an ordinary URL to `Paint::Resource` instead of CPU-backed raster data?
2. If not, would a replaceable image provider at Blitz's normal image-resolution boundary be the appropriate abstraction?
3. Is AnyRender's `ResourceId` / `Paint::Resource` mechanism intended to represent renderer-owned textures in this situation, or is it only intended for custom widget rendering?
4. Can the same resource-backed image representation participate in all of Blitz's existing image behavior, including intrinsic sizing, `object-fit`, CSS backgrounds, masks, clipping, filters, opacity, transforms, and normal paint ordering?
5. Where should resource registration and release be owned when the image originates from a Blitz URL but the texture itself is owned by the host renderer?
6. What is the recommended invalidation mechanism when the contents of an existing renderer-owned texture change without changing the image URL?
This is not a request for custom URI-scheme support. The document should continue to contain ordinary paths such as `./a.png`, `./b.jpg`, and `../images/c.png`.
It is also not specific to a graphics API or application framework. The goal is to preserve Blitz's standard HTML/CSS image semantics while allowing a custom AnyRender backend to draw an existing GPU texture without CPU readback, duplicate decoding, or duplicate upload.
Contributor guide
Research direction
Start by tracing Blitz's standard image path from NetProvider/NetHandler through image painting, then read AnyRender's try_register_custom_resource(), ResourceId, Paint::Resource, and the wgpu_texture example. The issue is complete when the project has an agreed image-provider extension point and clear ownership, sizing, invalidation, and release behavior for renderer-owned resources.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100