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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
//! Widget backbuffer types: caching specs, retained state, and compositing layers.
//!
//! Any widget can opt into a cached CPU backbuffer by returning `Some(&mut ...)`
//! from [`Widget::backbuffer_cache_mut`]. The framework's `paint_subtree`
//! handles caching transparently: when the widget is dirty (or has no bitmap
//! yet) it allocates a fresh `Framebuffer`, runs `widget.paint` + all children
//! into it via a software `GfxCtx`, and caches the resulting RGBA8 pixels as a
//! shared `Arc<Vec<u8>>`. Every subsequent frame that finds the widget clean
//! just blits the cached pixels through `ctx.draw_image_rgba_arc` — zero AGG
//! cost in steady state. On the GL backend the `Arc`'s pointer identity keys
//! the GPU texture cache (see `arc_texture_cache`), so the hardware texture
//! is also reused across frames and dropped when the bitmap drops.
//!
//! LCD subpixel rendering works naturally inside a backbuffer: the widget
//! paints its own background first (so text has a solid dst) and then any
//! `fill_text` call composites the per-channel coverage mask onto that
//! destination. No walk / sample / bg-declaration needed.
use ;
use Arc;
use crateInsets;
/// How a widget's backbuffer stores pixels.
///
/// The choice controls what the framework allocates as the render
/// target during `paint_subtree_backbuffered` and how the cached
/// bitmap is composited back onto the parent.
/// Unified backbuffer target kind requested by a widget.
/// Widget-owned backbuffer request. Windows use this for retained GL FBOs,
/// while existing label/text-field CPU caches map naturally to the software
/// variants.
/// A CPU bitmap owned by a widget that opts into backbuffer caching.
///
/// The framework re-rasterises when the cache's explicit dirty flag is set or
/// when global styling epochs change.
/// Monotone, process-global content-revision counter for backbuffer caches.
///
/// Every raster that changes a cache's published pixels stamps
/// [`BackbufferCache::content_version`] with a fresh value from here. Making it
/// *global* (rather than per-cache) means a `(buffer_ptr, version)` pair can
/// never collide across surface lifetimes — a freed buffer's address may be
/// reused by a different cache, but the version it carries will always differ.
/// That keeps a pointer-keyed GPU texture cache ABA-proof. Starts at 1 so `0`
/// stays reserved for "never rastered".
pub
static NEXT_BACKBUFFER_ID: AtomicU64 = new;
/// Retained widget backbuffer state shared by software and GL implementations.
/// Over-scan band request for a scrolling backbuffered widget.
///
/// Returned by [`crate::widget::Widget::backbuffer_band`]. It lets a widget
/// (today only [`crate::widgets::TextArea`]) raster a *band* of content taller
/// than its own viewport — the visible rect plus an extra `overscan_top` above
/// and `overscan_bottom` below — so that ordinary scrolling within the band
/// becomes a pure blit-offset change instead of a full backbuffer re-raster.
///
/// # Contract
///
/// * **Units.** `overscan_top` / `overscan_bottom` are extra logical pixels of
/// content rastered above / below the widget bounds. `blit_dy` is the
/// vertical blit offset in logical pixels (positive shifts the band's content
/// *up* in Y-up, revealing lower content). The band is anchored in content
/// space by the widget; `blit_dy` is the residual between the live scroll
/// offset and the anchor the band was rastered at.
/// * **Quantization.** The framework quantizes both the overscan extents and
/// `blit_dy` to whole *physical* pixels before sizing the buffer, translating
/// the raster, and translating the blit — so the LCD subpixel structure is
/// never resampled. The widget may pass raw (unquantized) logical values.
/// * **Who clips.** The framework clips the band blit to the widget's bounds on
/// every backend, so the over-scan margins never paint over sibling widgets.
/// The widget is responsible for painting opaque content across the *whole*
/// band (including the over-scan margins) so no gap shows through as the band
/// is scrolled, and for painting any fixed chrome (border) in `paint_overlay`
/// so it does not scroll with the band.
/// * **Invalidation.** The widget must keep the band's anchor (and hence the
/// rastered content) out of its backbuffer-cache signature, so scrolling
/// within the band does not invalidate the cache. It must re-anchor and
/// invalidate only when the live offset leaves the band (or the size /
/// content / style changes).
///
/// Returning `None` (the default) opts out entirely and keeps the byte-for-byte
/// original bounds-sized raster + 1:1 blit path.
/// Offscreen compositing layer requested by a widget for itself and its
/// descendants.