1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
//! App-owned GPU textures composited into the paint stream.
//!
//! Where [`crate::image::Image`] hands Aetna a CPU pixel buffer that the
//! backend uploads and content-hash caches, an [`AppTexture`] wraps a
//! GPU texture the *app* allocates, fills, and resizes itself. Aetna
//! samples it during paint — no upload, no per-frame copy.
//!
//! This is the affordance for content that doesn't fit the quad-instance
//! shader model: 3D viewports, video frames, externally rasterised
//! canvases. The widget that displays one is [`crate::tree::surface`].
//!
//! # Sizing contract
//!
//! The source texture's pixel dimensions are **independent of the
//! rendered size**. By default, `surface()` samples the full texture
//! across its resolved layout rect with bilinear filtering; use
//! [`crate::tree::El::surface_fit`] for `Contain`, `Cover`, or natural
//! size projection, and [`crate::tree::El::surface_transform`] for
//! destination-space affine transforms. See [`crate::tree::surface`]
//! for sizing strategies (pixel-accurate, viewport-driven
//! re-allocation, aspect-ratio wrappers).
//!
//! # Backend dispatch
//!
//! Backend-neutral: [`AppTexture`] is an `Arc<dyn AppTextureBackend>`,
//! and each Aetna backend (`aetna-wgpu`, `aetna-vulkano`) supplies its
//! own concrete impl plus a constructor (e.g. `aetna_wgpu::app_texture`).
//! The runtime downcasts in the backend's record path; everything above
//! the backend boundary stays neutral.
use Any;
use fmt;
use Arc;
use ;
/// Pixel format of an [`AppTexture`]. The widget composites by sampling
/// the texture; the backend picks a sampler / shader path that matches.
///
/// 0.3.1 ships the three RGBA8 variants below — enough for 3D viewport
/// output (typically a surface-format-matching `*Srgb`), video decoded
/// to RGBA, and rumble-style animated frames. Future variants (HDR,
/// YUV) slot in here without breaking the widget surface.
/// How an [`AppTexture`] composes with widgets painted underneath it.
///
/// The choice affects blend state and lets opaque content skip blend
/// math; it does *not* change z-order. Widgets above the surface in the
/// paint stream still paint over it, regardless of mode.
/// Stable identity for an [`AppTexture`]. Allocated by the constructor
/// that wraps the underlying GPU texture; backends cache their bind
/// groups / descriptor sets keyed on this id, so it must not be reused
/// for a different texture during the lifetime of the wrapping
/// `AppTexture`.
///
/// Apps that recreate their texture (resize, format change) get a fresh
/// id — the previous bind group falls off the cache after one frame,
/// like any other unused entry.
;
/// Allocate a fresh [`AppTextureId`]. Used by backend constructors. App
/// code should not call this directly — go through the backend's
/// `app_texture(...)` constructor instead.
/// Backend implementation of an [`AppTexture`]. Implemented by
/// `aetna-wgpu` and `aetna-vulkano` against their native texture types;
/// the runtime downcasts via [`Self::as_any`] in the backend's record
/// path.
/// An app-owned GPU texture handed to Aetna for compositing. Cheap
/// `Arc`-backed clone; pass into [`crate::tree::surface`] to display.
///
/// Construct via the backend constructor — `aetna_wgpu::app_texture` or
/// `aetna_vulkano::app_texture`. The wrapper is type-erased so the El
/// tree and paint stream stay backend-neutral.
/// Source of pixels for a [`crate::tree::Kind::Surface`] widget.
///
/// Today only [`Self::Texture`] is shipped. A `Callback(...)` variant
/// is planned as a future, more efficient path that hands the backend
/// encoder to the app during paint; the `Source` enum exists from day
/// one so that addition is non-breaking for callers.