diff options
Diffstat (limited to 'src/server/headless/retained_surface.rs')
| -rw-r--r-- | src/server/headless/retained_surface.rs | 51 |
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); |
