aboutsummaryrefslogtreecommitdiff
path: root/src/server/headless/retained_surface.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/headless/retained_surface.rs')
-rw-r--r--src/server/headless/retained_surface.rs51
1 files changed, 44 insertions, 7 deletions
diff --git a/src/server/headless/retained_surface.rs b/src/server/headless/retained_surface.rs
index 07d33ef5..bf98bc3e 100644
--- a/src/server/headless/retained_surface.rs
+++ b/src/server/headless/retained_surface.rs
@@ -203,6 +203,7 @@ struct RetainedRecipientUpdate {
graphics: Option<(
protocol::PaneSurfaceFrame,
crate::kitty_graphics::surface::DeliveryCache,
+ crate::kitty_graphics::surface::SourceFiles,
)>,
}
@@ -446,7 +447,7 @@ impl HeadlessServer {
let client = &self.clients[&client_id];
let mut next_surface = surface.clone();
crate::server::render_stream::apply_pane_surface_patch(&mut next_surface, &patch);
- let Some((graphics, delivery)) =
+ let Some((graphics, delivery, sources)) =
crate::server::client_shell_graphics::collect_retained(
&self.app,
&next_surface,
@@ -460,7 +461,7 @@ impl HeadlessServer {
};
graphics_changed = graphics != surface.graphics;
next_surface.graphics = graphics;
- Some((next_surface, delivery))
+ Some((next_surface, delivery, sources))
} else {
None
};
@@ -490,8 +491,17 @@ impl HeadlessServer {
let RetainedRecipientUpdate {
client_id,
patch,
- graphics,
+ mut graphics,
} = update;
+ if graphics.as_ref().is_some_and(|(surface, _, _)| {
+ self.defer_changed_native_geometry(client_id, &surface.graphics)
+ }) {
+ deferred += 1;
+ continue;
+ }
+ let native_upload = graphics.as_mut().and_then(|(surface, delivery, sources)| {
+ self.prepare_native_scene(client_id, &mut surface.graphics, delivery, sources)
+ });
let Some(client) = self.clients.get_mut(&client_id) else {
continue;
};
@@ -502,9 +512,11 @@ impl HeadlessServer {
};
// The published row patch cannot carry images. Reuse the retained text/layout
// in a graphics-capable surface message rather than invoking the full renderer.
- let (prepared, graphics_delivery) = if let Some((surface, delivery)) = graphics {
+ let (prepared, graphics_delivery) = if let Some((surface, delivery, _)) = graphics {
(
- client.render_state.prepare_pane_surface(surface),
+ client
+ .render_state
+ .prepare_pane_surface_with_file(surface, native_upload.is_some()),
Some(delivery),
)
} else {
@@ -520,7 +532,7 @@ impl HeadlessServer {
} else {
protocol::MAX_FRAME_SIZE
};
- let serialized =
+ let mut serialized =
match Self::frame_server_message_with_max(prepared.message(), max_frame_size) {
Ok(serialized) => serialized,
Err(error) => {
@@ -529,14 +541,39 @@ impl HeadlessServer {
%error,
"failed to serialize retained pane surface patch"
);
+ // A delta may own an encoded graphics payload that cannot be
+ // trimmed in place. Force the bounded full-surface recovery path.
+ client.render_state.request_repaint();
client.defer_full_render();
deferred += 1;
continue;
}
};
+ if let Some((_, message)) = &native_upload {
+ let Ok(file_frame) =
+ Self::frame_server_message_with_max(message, MAX_GRAPHICS_FRAME_SIZE)
+ else {
+ client.defer_full_render();
+ deferred += 1;
+ continue;
+ };
+ serialized.extend_from_slice(&file_frame);
+ }
crate::render_prof::counter("retained_surface.bytes", serialized.len() as u64);
- match writer.render.try_send(serialized) {
+ let send = if native_upload.is_some() || self.native_graphics.is_pending(client_id) {
+ writer.render.send_ordered(serialized)
+ } else {
+ writer.render.try_send(serialized)
+ };
+ match send {
Ok(()) => {
+ if let Some((graphics, inline_assets)) = prepared.queued_surface_graphics() {
+ self.native_graphics
+ .commit_scene(client_id, graphics, inline_assets);
+ }
+ if let Some((pending, _)) = native_upload {
+ self.native_graphics.commit(client_id, pending);
+ }
let graphics_pending = graphics_delivery
.as_ref()
.is_some_and(crate::kitty_graphics::surface::DeliveryCache::has_pending);