mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
egui_inspection: PNG-encode screenshots on the wire; collapse protocol feature
- FrameScreenshot now carries PNG bytes instead of raw RGBA (PROTOCOL_VERSION 1→2); add a shared `encode_png` helper behind a new `png` feature so the live plugin and the kittest harness encode frames identically. - Make the protocol module unconditional: drop the `protocol` feature flag and the optional serde/serde_bytes/rmp-serde deps it gated. - plugin.rs: re-stamp screenshot-bearing frames with the current step (so inspectors waiting for step > prev don't reject them) and pump a tail-side repaint while awaiting the GPU readback.
This commit is contained in:
@@ -211,11 +211,26 @@ impl egui::Plugin for InspectionPlugin {
|
||||
if let Some(mut frame) = self.pending_frame.take() {
|
||||
let [w, h] = [image.size[0] as u32, image.size[1] as u32];
|
||||
let rgba: Vec<u8> = image.pixels.iter().flat_map(|c| c.to_array()).collect();
|
||||
frame.screenshot = Some(FrameScreenshot {
|
||||
width: w,
|
||||
height: h,
|
||||
rgba,
|
||||
});
|
||||
match crate::encode_png(w, h, &rgba) {
|
||||
Ok(png) => {
|
||||
frame.screenshot = Some(FrameScreenshot {
|
||||
width: w,
|
||||
height: h,
|
||||
png,
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("[INSP] PNG encode failed: {err}");
|
||||
}
|
||||
}
|
||||
// Re-stamp the frame with the *current* step. The stashed `step` was
|
||||
// captured when we dispatched the screenshot command; in the meantime
|
||||
// intervening frames (without screenshot) may have been emitted with
|
||||
// higher step numbers. Inspectors that wait for `step > prev_step` would
|
||||
// otherwise reject the screenshot-bearing frame because its step has
|
||||
// regressed.
|
||||
self.step = self.step.saturating_add(1);
|
||||
frame.step = self.step;
|
||||
self.send(HarnessMessage::Frame(Box::new(frame)));
|
||||
}
|
||||
break;
|
||||
@@ -296,6 +311,17 @@ impl egui::Plugin for InspectionPlugin {
|
||||
if !want_screenshot {
|
||||
// No screenshot needed — emit immediately.
|
||||
self.send(HarnessMessage::Frame(Box::new(frame)));
|
||||
// If we're still waiting on a screenshot from a previous dispatch, keep
|
||||
// pumping repaints from the end of the frame too. `input_hook` already
|
||||
// does this at frame start, but on reactive apps the GPU readback can
|
||||
// take several frames to fulfill — without a tail-side repaint the
|
||||
// integration may go idle between `input_hook` ticks once the captured
|
||||
// frame finishes presenting.
|
||||
if self.awaiting_screenshot {
|
||||
if let Some(ctx) = self.shared_ctx.get() {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user