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
//! Public hook for user widgets to inject their own wgpu render pass(es)
//! into the agg-gui frame.
//!
//! # Why
//!
//! agg-gui paints 2-D widgets via deferred `DrawCommand`s that flush into a
//! single `wgpu::CommandEncoder` in [`WgpuGfxCtx::end_frame`](crate::WgpuGfxCtx::end_frame). A
//! 3-D viewport widget (e.g. AtomArtist's `Viewport3dWidget`) needs to run
//! its own render pass(es) interleaved with that 2-D stream so its output
//! ends up on the same surface or layer texture, with depth-correct
//! ordering relative to surrounding 2-D content.
//!
//! The demo's own `WgpuCubeWidget` used to push a hard-coded
//! `DrawCommand::DrawBarGrid` variant directly into the command list — which
//! worked but was not extensible, and it kept demo content inside the
//! renderer. This module generalises that pattern so any widget can plug in;
//! the cube now rides this path like everyone else.
//!
//! # How to use
//!
//! 1. Define a struct that implements [`WgpuCustomRender`].
//! 2. Hold it in `Rc<RefCell<dyn WgpuCustomRender>>` so the widget can
//! keep a clone (lazy-init / persistent buffers across frames).
//! 3. From your widget's `paint(ctx)`, downcast `ctx` to
//! [`WgpuGfxCtx`](crate::WgpuGfxCtx) via
//! [`DrawCtx::as_any_mut`](agg_gui::draw_ctx::DrawCtx::as_any_mut) and call
//! [`WgpuGfxCtx::push_custom_render`](crate::WgpuGfxCtx::push_custom_render).
//!
//! # Pass semantics
//!
//! When the executor reaches a `DrawCommand::Custom` entry, it:
//! 1. Ends the active 2-D render pass.
//! 2. Calls [`WgpuCustomRender::render`] with a [`WgpuCustomRenderCtx`]
//! pointing at the same encoder + active target view.
//! 3. Reopens a 2-D pass with `LoadOp::Load` so subsequent 2-D content
//! composites cleanly on top.
//!
//! The custom renderer may record any number of its own passes against
//! the encoder, including offscreen passes followed by a blit to
//! `target_view`. Conventionally the implementor should leave its target
//! state untouched after returning (no in-progress pass, no orphaned
//! buffer mappings).
use RefCell;
use Rc;
use crateWgpuPipelines;
/// Inputs handed to a [`WgpuCustomRender`] implementor at execution time.
///
/// Field invariants:
/// - `encoder` is borrowed for the duration of `render` only — record
/// into it but don't take ownership.
/// - `target_view` is the surface or active layer texture view; the 2-D
/// pass on either side of this call uses the same view.
/// - `target_size` matches the active target's full pixel dimensions.
/// - `screen_rect` is the widget's logical-pixel rect in **bottom-up
/// Y-up coords** (agg-gui convention). Convert to wgpu's top-down
/// Y-down convention as needed when computing scissor / viewport.
/// - `pipelines` is the shared 2-D pipeline collection. Implementors
/// that own an [`crate::ssaa::SsaaFramebuffer`] can call
/// [`crate::ssaa::SsaaFramebuffer::blit_to`] with this to composite
/// their offscreen output onto `target_view` through the same
/// textured-quad pipeline the 2-D path uses.
///
/// Only the renderer constructs this (from `end_frame`); implementors receive
/// one and read it. It is `#[non_exhaustive]` so further per-pass state can be
/// added without a breaking release.
/// Trait implemented by widgets that want to inject custom wgpu render
/// commands into the frame.
///
/// `render` is called from `end_frame()` once per matching
/// `DrawCommand::Custom` queued during
/// `paint()`. Implementations are typically held in
/// `Rc<RefCell<dyn WgpuCustomRender>>` so the widget can lazy-init GPU
/// state on first use and persist it across frames.
/// Convenience type alias for the boxed-trait pattern most callers use.
pub type SharedCustomRenderer = ;