Conversation
7625468 to
8f61dd7
Compare
|
This was done with assistance from Codex (gpt-5.4, high). But the overall design is mine. (But probably still evolving ...) |
PoignardAzur
left a comment
There was a problem hiding this comment.
I'm going to be honest, I gave up halfway through subduction_presenter.rs, because at some point I don't even know if I'm giving feedback to Bruce or to some LLM, and this doesn't feel like a good use of my time.
Anyway, the guiding principle of Masonry is that we make a lot of effort to keep the code readable for complete beginners. This principle is relaxed for Masonry Winit because platform glue code is inherently messy, but even then, this PR does not remotely meet our standards.
There was a problem hiding this comment.
Let's keep all the examples in masonry/examples/.
There was a problem hiding this comment.
This one is here for now because parts of it are very specific to masonry_winit and with other stuff that I had locally, it was annoying to keep other things building ... but I'll move it before this lands.
There was a problem hiding this comment.
This test file should be moved to masonry/src/tests/.
There's a few reasons we do a lot of tests in masonry instead of masonry_core. The main one is that masonry defines a lot of widgets that are useful for tests. For instance, PaintLeaf, TripleRow, OffsetBox and MixedTripleRow could trivially be replaced by SizedBox and Flex.
Overall, tests are supposed to be a kind of maintainer-only documentation explaining what we expect from the code. You shouldn't need to read the implementation of four custom widgets to get to read a test.
There was a problem hiding this comment.
If we didn't have to implement a bunch of empty methods for every widget, this would've been a lot easier as well.
But the things that it is testing aren't as easily done with SizedBox / Flex given that they make things less easily deterministic ..
But I'll move it after other things are resolved.
| #[cfg(not(target_arch = "wasm32"))] | ||
| use std::fs::File; | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| use std::time::UNIX_EPOCH; |
There was a problem hiding this comment.
These seem like drive-by changes? I don't think they're needed for this PR.
There was a problem hiding this comment.
They were required to fix CI since with this, some stuff started getting compiled for Wasm in the existing CI that wasn't happening before.
They can probably be done in a separate PR at some point.
There was a problem hiding this comment.
Alright, so this file defines breathes in VisualLayerId, ExternalLayerKind, VisualLayerBoundary, VisualLayerKind, VisualLayer, SceneVisualLayer, ExternalVisualLayer, and VisualLayerPlan.
This is my problem with these AI-generated PRs. Even if all of the code is correct, they add a lot of API surface that you then need to learn and maintain.
Also, general comment: while this isn't documented anywhere (but it should be!), Masonry modules usually adhere to a coding style where all types are defined first, then implementations. This helps identify which types are composed of which other types, etc.
There was a problem hiding this comment.
Some of the are because I used to have support for actual child windows on Windows and macOS before, not just a single external layer. I've removed that though thinking I might add it back, but realistically, I'll probably never actually re-implement that within Masonry.
The problem here with these types isn't that it was AI generated, it is that at various points (over the last more than a week), this PR has been doing a lot of other things along the way that I removed.
Also, some parts of this are actually complex things to model and require some detail.
But the VisualLayerPlan is the actually important thing here and where most of the attention has gone.
| /// Where this visual layer boundary originated. | ||
| pub boundary: VisualLayerBoundary, |
There was a problem hiding this comment.
We've had a discussion about AI-generated doc lately, where Raph posted a parody of AI doc. Reading a lot of doc in this file reminds me of Raph's parody; this line is a good example.
When we have a type named VisualLayer with a field named boundary of type VisualLayerBoundary, a doc that says "Its the visual layer boundary" is extremely unhelpful.
There was a problem hiding this comment.
Would you rather the type be called Boundary?
It is fair to call out that the doc comment could use more work.
Or I guess we could mock the work that I'm doing instead of something productive.
| fn on_visual_layers( | ||
| &mut self, | ||
| window_id: WindowId, | ||
| ctx: &mut DriverCtx<'_, '_>, | ||
| layers: &VisualLayerPlan, | ||
| ) { |
There was a problem hiding this comment.
I'm not super clear on how this is supposed to be used, from reading documentation.
Is the expectation that apps with custom layers will render them to wgpu from this method? Or just update them?
Also, on_visual_layers is a confusing name.
There was a problem hiding this comment.
It is for letting a host inspect the frame without taking over presentation. I'll just remove it.
| pub trait SceneLayerRenderer { | ||
| /// Render the given scene layer into `target.view`. | ||
| fn render_scene_layer( | ||
| &mut self, | ||
| target: SceneLayerTarget<'_>, | ||
| layer: SceneVisualLayer<'_>, | ||
| ) -> Result<(), BoxError>; | ||
| } | ||
|
|
||
| /// Realize host-owned external layers into the textures allocated by the subduction presenter. | ||
| pub trait ExternalLayerRenderer { |
There was a problem hiding this comment.
I think at some point I'm going to put out an official moratorium on adding more traits to the Xilem codebase, because the trait inflation is getting way out of control.
I'm pretty sure these two could just be impl Fns.
| pub struct SceneLayerTarget<'a> { | ||
| /// Device used for rendering. | ||
| pub device: &'a wgpu::Device, | ||
| /// Queue used for uploads and submission. | ||
| pub queue: &'a wgpu::Queue, | ||
| /// Texture view owned by the compositor for this layer. | ||
| pub view: &'a wgpu::TextureView, | ||
| /// Output size in physical pixels. | ||
| pub output_size: winit::dpi::PhysicalSize<u32>, | ||
| /// Window scale factor used to convert logical layer geometry into pixels. | ||
| pub scale_factor: f64, | ||
| } |
There was a problem hiding this comment.
Okay, so this struct is exactly the same as ExternalLayerTarget, except without the format field. I suspect they could have been merged.
| /// Host-specific renderer for external layers with optional per-layer state. | ||
| pub trait ManagedExternalLayerRenderer { |
There was a problem hiding this comment.
Oh hey, a third trait!
| layer: Layer, | ||
| } | ||
|
|
||
| trait ExternalLayerStateDriver<Layer, State> { |
There was a problem hiding this comment.
Oh hey, a fourth trait!
It is fair to give up in parts of that version of the presenter. I've done a massive simplification on it now that I've removed some other things and will probably never re-implement them within Masonry (like OS child windows and a form of native control integration). |
8f61dd7 to
1d58c2b
Compare
This PR introduces
VisualLayerPlanas Masonry’s shared visual-layer model and uses it to carry explicit paint boundaries frommasonry_corethrough host presentation.The main outcome is that Masonry can now represent and preserve an ordered layer sequence like:
That gives us a cleaner path toward compositor-driven presentation, instead of flattening everything into one scene and treating external content as a special case.
This PR does not claim that the compositor model is finished.
In particular:
VisualLayerPlanis still a flat ordered plan, not a grouped/tree compositor modelsubductionpath is an early host integration, not the final cross-platform presentation architecture