const std = @import("std");const builtin = @import("builtin");const debug_trace = @import("../../core/shared/debug_trace.zig");const types = @import("../../core/shared/types.zig");const ui_terminal = @import("../terminal/terminal.zig");const vt_emulator = @import("../../core/terminal/engine.zig");const frame_cell_match = @import("frame_cell_match.zig");const frame_scroll_plan = @import("frame_scroll_plan.zig");const frame_surface = @import("frame_surface.zig");const paint_plan = @import("paint_plan.zig"); const Allocator = std.mem.Allocator;const Metrics = types.Metrics; pub const ShadowCommitState = enum { committed, terminal_partial_write, shadow_feed_failed, pub fn is_committed(self: ShadowCommitState) bool { return self == .committed; }}; pub const FrameSinkWriteResult = union(enum) { complete, partial: struct { accepted_bytes: usize, err: anyerror, },}; pub const FrameSink = struct { ctx: *anyopaque, write_frame: *const fn (ctx: *anyopaque, metrics: *Metrics, bytes: []const u8) FrameSinkWriteResult,}; pub const FrameTerminalTransition = union(enum) { none, restore_normal_screen: struct { mouse_tracking_active: bool, }, fn sequence(self: FrameTerminalTransition) []const u8 { return switch (self) { .none => "", .restore_normal_screen => |restore| ui_terminal.alternateScreenFrameRestoreSequence( restore.mouse_tracking_active, ), }; }}; pub const FrameCommitInput = struct { previous: *vt_emulator.Grid, surface: *const frame_surface.FrameSurface, repaint_window: paint_plan.FrameRepaintWindow, synchronized_update: bool, history_reset_uses_ris: bool = false, scroll_plan: frame_scroll_plan.FrameScrollPlan, document_append: frame_scroll_plan.FrameDocumentAppend = .{}, terminal_transition: FrameTerminalTransition = .none, prepared_movement: ?*const PreparedTerminalMovement = null, sink: FrameSink, metrics: *Metrics,}; pub const TerminalMovementSegment = struct { start: usize = 0, end: usize = 0, scroll_rows: u16 = 0, pub fn hasBytes(self: TerminalMovementSegment) bool { return self.end > self.start; } fn absolute(self: TerminalMovementSegment, base: usize) TerminalMovementSegment { return .{ .start = base + self.start, .end = base + self.end, .scroll_rows = self.scroll_rows, }; }}; pub const TerminalMovementSegments = struct { terminal_transition: TerminalMovementSegment = .{}, document_append: TerminalMovementSegment = .{}, alignment_scroll: TerminalMovementSegment = .{},}; pub const FrameScrollAttribution = struct { control_prefix_scroll_rows: u16 = 0, document_append_scroll_rows: u16 = 0, alignment_scroll_rows: u16 = 0, movement_gap_scroll_rows: u16 = 0, paint_tail_scroll_rows: u16 = 0, pub fn movementScrollRows(self: FrameScrollAttribution) u16 { return self.document_append_scroll_rows +| self.alignment_scroll_rows; } pub fn neutralScrollRows(self: FrameScrollAttribution) u16 { return self.control_prefix_scroll_rows +| self.movement_gap_scroll_rows +| self.paint_tail_scroll_rows; } pub fn totalScrollRows(self: FrameScrollAttribution) u16 { return self.movementScrollRows() +| self.neutralScrollRows(); }}; pub const PreparedTerminalMovement = struct { bytes: []u8, post_movement: vt_emulator.Grid, document_append_start: usize = 0, document_append_end: usize = 0, segments: TerminalMovementSegments = .{}, scroll_rows: frame_scroll_plan.TerminalMovementRows = .{ .planned_scroll_rows = 0, .materialized_scroll_rows = 0, .alignment_scroll_rows = 0, .expected_scroll_rows = 0, }, terminal_transition: FrameTerminalTransition = .none, reset_replay: bool = false, source_rows: u16, source_cols: u16, target_rows: u16, target_cols: u16, pub fn deinit(self: *PreparedTerminalMovement, alloc: Allocator) void { if (self.bytes.len > 0) alloc.free(self.bytes); self.post_movement.deinit(); self.* = undefined; } pub fn hasDocumentAppend(self: PreparedTerminalMovement) bool { return self.segments.document_append.hasBytes(); } fn validateForCommit( self: *const PreparedTerminalMovement, source: *const vt_emulator.Grid, target_cols: u16, target_rows: u16, planned_scroll_rows: u16, non_deferable_scroll_rows: u16, terminal_transition: FrameTerminalTransition, reset_replay: bool, ) !void { const expected_rows = try resolveTerminalMovementRows( planned_scroll_rows, self.scroll_rows.materialized_scroll_rows, non_deferable_scroll_rows, reset_replay, source.cols, source.rows, target_cols, target_rows, ); if (self.source_rows != source.rows or self.source_cols != source.cols or self.target_rows != target_rows or self.target_cols != target_cols or !std.meta.eql(self.scroll_rows, expected_rows) or !std.meta.eql(self.terminal_transition, terminal_transition) or self.reset_replay != reset_replay or self.segments.terminal_transition.scroll_rows != 0 or self.segments.document_append.scroll_rows != self.scroll_rows.materialized_scroll_rows or self.segments.alignment_scroll.scroll_rows != self.scroll_rows.alignment_scroll_rows) { return error.InvalidFrameScrollPlan; } } fn validateCompleteWrite( self: *const PreparedTerminalMovement, accepted_bytes: usize, frame_bytes: usize, scroll_attribution: FrameScrollAttribution, ) !void { if (accepted_bytes != frame_bytes) return; if (scroll_attribution.neutralScrollRows() != 0 or scroll_attribution.document_append_scroll_rows != self.scroll_rows.materialized_scroll_rows or scroll_attribution.alignment_scroll_rows != self.scroll_rows.alignment_scroll_rows or scroll_attribution.totalScrollRows() != self.scroll_rows.emittedScrollRows()) { return error.InvalidFrameScrollPlan; } } fn documentAppendWireRange(self: *const PreparedTerminalMovement, prefix_len: usize) DocumentAppendWireRange { if (!self.hasDocumentAppend()) return .{}; return .{ .start = prefix_len + self.document_append_start, .end = prefix_len + self.document_append_end, }; }}; pub const FrameCommitResult = struct { bytes_written: usize, changed_cells: usize, full_repaint: bool, terminal_scroll_rows_committed: u16 = 0, scroll_commit_receipt: ?frame_scroll_plan.FrameScrollCommit = null, scroll_attribution: FrameScrollAttribution = .{}, document_append_committed: bool = false, committed_cursor_row: u16, committed_cursor_col: u16, committed_cursor_visible: bool = true, shadow_state: ShadowCommitState, next_invalidation: paint_plan.FrameInvalidationSet, pub fn state(self: FrameCommitResult) ShadowCommitState { return self.shadow_state; } pub fn is_committed(self: FrameCommitResult) bool { return self.state().is_committed(); } pub fn terminal_scroll_rows_applied(self: FrameCommitResult) u16 { return self.terminal_scroll_rows_committed; } pub fn document_append_applied(self: FrameCommitResult) bool { return self.document_append_committed; } pub fn committed_cursor(self: FrameCommitResult) ?paint_plan.FrameCursorTarget { if (!self.is_committed()) return null; return .{ .row = self.committed_cursor_row, .col = self.committed_cursor_col, .visible = self.committed_cursor_visible, }; } pub fn retry_invalidation(self: FrameCommitResult) ?paint_plan.FrameInvalidationRange { if (self.is_committed()) return null; std.debug.assert(self.next_invalidation.len <= 1); if (self.next_invalidation.isEmpty()) return null; return self.next_invalidation.ranges()[0]; } pub fn scrollCommit( self: FrameCommitResult, scroll_plan: frame_scroll_plan.FrameScrollPlan, ) frame_scroll_plan.FrameScrollCommit { if (self.scroll_commit_receipt) |receipt| { std.debug.assert(receipt.matchesPlan(scroll_plan)); return receipt; } std.debug.assert(builtin.is_test); return scroll_plan.commit(self.terminal_scroll_rows_committed); }}; const CleanupState = enum { none, complete, failed,}; const DocumentAppendWireRange = struct { start: usize = 0, end: usize = 0, fn isEmpty(self: DocumentAppendWireRange) bool { return self.end == 0; } fn committed(self: DocumentAppendWireRange, accepted_bytes: usize) bool { return !self.isEmpty() and accepted_bytes >= self.end; } fn interrupted(self: DocumentAppendWireRange, accepted_bytes: usize) bool { return !self.isEmpty() and accepted_bytes > self.start and !self.committed(accepted_bytes); }}; const AcceptedFrameWrite = struct { accepted_bytes: usize, applied_scroll_rows: u16, scroll_attribution: FrameScrollAttribution, document_append_committed: bool, document_append_interrupted: bool,}; const DocumentAppendMovement = struct { segment: TerminalMovementSegment = .{},}; const FrameMovementSegments = struct { movement_start: usize = 0, movement_end: usize = 0, document_append: TerminalMovementSegment = .{}, alignment_scroll: TerminalMovementSegment = .{}, fn none() FrameMovementSegments { return .{}; } fn fromPreparedMovement(prefix_len: usize, movement: PreparedTerminalMovement) FrameMovementSegments { return .{ .movement_start = prefix_len, .movement_end = prefix_len + movement.bytes.len, .document_append = movement.segments.document_append.absolute(prefix_len), .alignment_scroll = movement.segments.alignment_scroll.absolute(prefix_len), }; }}; const ScrollAttributionBucket = enum { control_prefix, document_append, alignment_scroll, movement_gap, paint_tail,}; const ShadowTestFault = enum { none, normal_clone_feed, normal_clone_invalid, repair_resize, repair_canonical_feed,}; var shadow_test_fault: if (builtin.is_test) ShadowTestFault else void = if (builtin.is_test) .none else {}; pub fn flushFrame(input: FrameCommitInput) !FrameCommitResult { try input.surface.plan.validate(); try input.surface.validate(); const alloc = input.surface.alloc; var target = try input.surface.copyToTargetGrid(alloc); defer target.deinit(); try input.scroll_plan.validate(target.rows); try input.repaint_window.validate(input.surface.plan); const repaint_window = input.repaint_window; const terminal_scroll_rows = input.scroll_plan.terminal_scroll_rows; if (input.document_append.reset_replay and !input.surface.plan.reset_terminal) { return error.InvalidFrameScrollPlan; } var local_movement: ?PreparedTerminalMovement = null; defer if (local_movement) |*movement| movement.deinit(alloc); const movement = if (input.prepared_movement) |prepared| prepared else blk: { local_movement = try prepareTerminalMovementForFrame( alloc, input.previous, input.document_append, terminal_scroll_rows, input.scroll_plan.preserved_release_rows, target.cols, target.rows, 0, input.terminal_transition, ); break :blk &local_movement.?; }; try movement.validateForCommit( input.previous, target.cols, target.rows, terminal_scroll_rows, input.scroll_plan.preserved_release_rows, input.terminal_transition, input.document_append.reset_replay, ); const terminal_scroll_bytes = movement.bytes; if (terminal_scroll_rows > 0 or movement.hasDocumentAppend()) { debug_trace.logf( "frame_commit", "terminal_movement planned_rows={d} materialized_rows={d} alignment_rows={d} append_bytes={d} append_wire_bytes={d}", .{ terminal_scroll_rows, movement.scroll_rows.materialized_scroll_rows, movement.scroll_rows.alignment_scroll_rows, input.document_append.bytes.len, movement.document_append_end -| movement.document_append_start, }, ); } const dimensions_changed = input.previous.rows != target.rows or input.previous.cols != target.cols; const previous_for_diff = movement.post_movement; const changed_cells = countChangedCells(previous_for_diff, target, repaint_window); const full_repaint = input.surface.plan.reset_terminal or dimensions_changed or terminal_scroll_rows > 0 or invalidationRequiresFullRepaint(input.surface.plan.invalidation); if (terminal_scroll_bytes.len == 0 and terminal_scroll_rows == 0 and !full_repaint and changed_cells == 0 and cursorMatches(previous_for_diff, target)) { debug_trace.logf( "frame_commit", "skipped_noop bytes=0 changed_cells=0 band={d}..{d} cursor={d},{d}", .{ firstRepaintRow(repaint_window), lastRepaintRow(repaint_window), target.cursor_row, target.cursor_col }, ); return committed_result( 0, 0, false, input.scroll_plan.commit(0), .{}, false, &target, ); } var wire_frame: std.Io.Writer.Allocating = .init(alloc); defer wire_frame.deinit(); const prefix_len = try composeWireFrame( &wire_frame, input, &previous_for_diff, &target, repaint_window, full_repaint, terminal_scroll_bytes, ); const wire_frame_bytes = wire_frame.written(); const document_append_range = movement.documentAppendWireRange(prefix_len); const frame_movement_segments = FrameMovementSegments.fromPreparedMovement(prefix_len, movement.*); const complete_scroll_attribution = try validateFrameScrollAttribution( alloc, input.previous, target.cols, target.rows, wire_frame_bytes, frame_movement_segments, movement.scroll_rows, ); const sink_result = input.sink.write_frame(input.sink.ctx, input.metrics, wire_frame_bytes); const accepted_write = try acceptedFrameWrite( alloc, input.previous, target.cols, target.rows, wire_frame_bytes, sink_result, document_append_range, frame_movement_segments, complete_scroll_attribution, ); try movement.validateCompleteWrite( accepted_write.accepted_bytes, wire_frame_bytes.len, accepted_write.scroll_attribution, ); const scroll_commit = input.scroll_plan.commitWithExpectedRows( accepted_write.applied_scroll_rows, movement.scroll_rows.expected_scroll_rows, ); switch (sink_result) { .complete => {}, .partial => |partial| { debug_trace.logf( "frame_commit", "wire_frame bytes={d} accepted_bytes={d} applied_scroll_rows={d} cleanup={s} err={s}", .{ wire_frame_bytes.len, accepted_write.accepted_bytes, accepted_write.applied_scroll_rows, @tagName(CleanupState.none), @errorName(partial.err) }, ); return recoverPartialFrame( input, changed_cells, full_repaint, wire_frame_bytes, accepted_write, scroll_commit, ); }, } var fed_shadow = cloneAuthoritativeShadow(alloc, input.previous, target.cols, target.rows) catch |err| { return shadowFeedFailedWithRepair(input, changed_cells, full_repaint, accepted_write.accepted_bytes, scroll_commit, accepted_write.scroll_attribution, accepted_write.document_append_committed, err); }; var fed_shadow_initialized = true; defer if (fed_shadow_initialized) fed_shadow.deinit(); if (consumeShadowTestFault(.normal_clone_feed)) { return shadowFeedFailedWithRepair( input, changed_cells, full_repaint, accepted_write.accepted_bytes, scroll_commit, accepted_write.scroll_attribution, accepted_write.document_append_committed, error.TestShadowFeedFailure, ); } fed_shadow.feed(wire_frame_bytes) catch |err| { return shadowFeedFailedWithRepair(input, changed_cells, full_repaint, accepted_write.accepted_bytes, scroll_commit, accepted_write.scroll_attribution, accepted_write.document_append_committed, err);Lines 1–500 of 4061. Load more
const std = @import("std"); const builtin = @import("builtin"); const debug_trace = @import("../../core/shared/debug_trace.zig"); const types = @import("../../core/shared/types.zig"); const ui_terminal = @import("../terminal/terminal.zig"); const vt_emulator = @import("../../core/terminal/engine.zig"); const frame_cell_match = @import("frame_cell_match.zig"); const frame_scroll_plan = @import("frame_scroll_plan.zig"); const frame_surface = @import("frame_surface.zig"); const paint_plan = @import("paint_plan.zig"); const Allocator = std.mem.Allocator; const Metrics = types.Metrics; pub const ShadowCommitState = enum { committed, terminal_partial_write, shadow_feed_failed, pub fn is_committed(self: ShadowCommitState) bool { return self == .committed; } }; pub const FrameSinkWriteResult = union(enum) { complete, partial: struct { accepted_bytes: usize, err: anyerror, }, }; pub const FrameSink = struct { ctx: *anyopaque, write_frame: *const fn (ctx: *anyopaque, metrics: *Metrics, bytes: []const u8) FrameSinkWriteResult, }; pub const FrameTerminalTransition = union(enum) { none, restore_normal_screen: struct { mouse_tracking_active: bool, }, fn sequence(self: FrameTerminalTransition) []const u8 { return switch (self) { .none => "", .restore_normal_screen => |restore| ui_terminal.alternateScreenFrameRestoreSequence( restore.mouse_tracking_active, ), }; } }; pub const FrameCommitInput = struct { previous: *vt_emulator.Grid, surface: *const frame_surface.FrameSurface, repaint_window: paint_plan.FrameRepaintWindow, synchronized_update: bool, history_reset_uses_ris: bool = false, scroll_plan: frame_scroll_plan.FrameScrollPlan, document_append: frame_scroll_plan.FrameDocumentAppend = .{}, terminal_transition: FrameTerminalTransition = .none, prepared_movement: ?*const PreparedTerminalMovement = null, sink: FrameSink, metrics: *Metrics, }; pub const TerminalMovementSegment = struct { start: usize = 0, end: usize = 0, scroll_rows: u16 = 0, pub fn hasBytes(self: TerminalMovementSegment) bool { return self.end > self.start; } fn absolute(self: TerminalMovementSegment, base: usize) TerminalMovementSegment { return .{ .start = base + self.start, .end = base + self.end, .scroll_rows = self.scroll_rows, }; } }; pub const TerminalMovementSegments = struct { terminal_transition: TerminalMovementSegment = .{}, document_append: TerminalMovementSegment = .{}, alignment_scroll: TerminalMovementSegment = .{}, }; pub const FrameScrollAttribution = struct { control_prefix_scroll_rows: u16 = 0, document_append_scroll_rows: u16 = 0, alignment_scroll_rows: u16 = 0, movement_gap_scroll_rows: u16 = 0, paint_tail_scroll_rows: u16 = 0, pub fn movementScrollRows(self: FrameScrollAttribution) u16 { return self.document_append_scroll_rows +| self.alignment_scroll_rows; } pub fn neutralScrollRows(self: FrameScrollAttribution) u16 { return self.control_prefix_scroll_rows +| self.movement_gap_scroll_rows +| self.paint_tail_scroll_rows; } pub fn totalScrollRows(self: FrameScrollAttribution) u16 { return self.movementScrollRows() +| self.neutralScrollRows(); } }; pub const PreparedTerminalMovement = struct { bytes: []u8, post_movement: vt_emulator.Grid, document_append_start: usize = 0, document_append_end: usize = 0, segments: TerminalMovementSegments = .{}, scroll_rows: frame_scroll_plan.TerminalMovementRows = .{ .planned_scroll_rows = 0, .materialized_scroll_rows = 0, .alignment_scroll_rows = 0, .expected_scroll_rows = 0, }, terminal_transition: FrameTerminalTransition = .none, reset_replay: bool = false, source_rows: u16, source_cols: u16, target_rows: u16, target_cols: u16, pub fn deinit(self: *PreparedTerminalMovement, alloc: Allocator) void { if (self.bytes.len > 0) alloc.free(self.bytes); self.post_movement.deinit(); self.* = undefined; } pub fn hasDocumentAppend(self: PreparedTerminalMovement) bool { return self.segments.document_append.hasBytes(); } fn validateForCommit( self: *const PreparedTerminalMovement, source: *const vt_emulator.Grid, target_cols: u16, target_rows: u16, planned_scroll_rows: u16, non_deferable_scroll_rows: u16, terminal_transition: FrameTerminalTransition, reset_replay: bool, ) !void { const expected_rows = try resolveTerminalMovementRows( planned_scroll_rows, self.scroll_rows.materialized_scroll_rows, non_deferable_scroll_rows, reset_replay, source.cols, source.rows, target_cols, target_rows, ); if (self.source_rows != source.rows or self.source_cols != source.cols or self.target_rows != target_rows or self.target_cols != target_cols or !std.meta.eql(self.scroll_rows, expected_rows) or !std.meta.eql(self.terminal_transition, terminal_transition) or self.reset_replay != reset_replay or self.segments.terminal_transition.scroll_rows != 0 or self.segments.document_append.scroll_rows != self.scroll_rows.materialized_scroll_rows or self.segments.alignment_scroll.scroll_rows != self.scroll_rows.alignment_scroll_rows) { return error.InvalidFrameScrollPlan; } } fn validateCompleteWrite( self: *const PreparedTerminalMovement, accepted_bytes: usize, frame_bytes: usize, scroll_attribution: FrameScrollAttribution, ) !void { if (accepted_bytes != frame_bytes) return; if (scroll_attribution.neutralScrollRows() != 0 or scroll_attribution.document_append_scroll_rows != self.scroll_rows.materialized_scroll_rows or scroll_attribution.alignment_scroll_rows != self.scroll_rows.alignment_scroll_rows or scroll_attribution.totalScrollRows() != self.scroll_rows.emittedScrollRows()) { return error.InvalidFrameScrollPlan; } } fn documentAppendWireRange(self: *const PreparedTerminalMovement, prefix_len: usize) DocumentAppendWireRange { if (!self.hasDocumentAppend()) return .{}; return .{ .start = prefix_len + self.document_append_start, .end = prefix_len + self.document_append_end, }; } }; pub const FrameCommitResult = struct { bytes_written: usize, changed_cells: usize, full_repaint: bool, terminal_scroll_rows_committed: u16 = 0, scroll_commit_receipt: ?frame_scroll_plan.FrameScrollCommit = null, scroll_attribution: FrameScrollAttribution = .{}, document_append_committed: bool = false, committed_cursor_row: u16, committed_cursor_col: u16, committed_cursor_visible: bool = true, shadow_state: ShadowCommitState, next_invalidation: paint_plan.FrameInvalidationSet, pub fn state(self: FrameCommitResult) ShadowCommitState { return self.shadow_state; } pub fn is_committed(self: FrameCommitResult) bool { return self.state().is_committed(); } pub fn terminal_scroll_rows_applied(self: FrameCommitResult) u16 { return self.terminal_scroll_rows_committed; } pub fn document_append_applied(self: FrameCommitResult) bool { return self.document_append_committed; } pub fn committed_cursor(self: FrameCommitResult) ?paint_plan.FrameCursorTarget { if (!self.is_committed()) return null; return .{ .row = self.committed_cursor_row, .col = self.committed_cursor_col, .visible = self.committed_cursor_visible, }; } pub fn retry_invalidation(self: FrameCommitResult) ?paint_plan.FrameInvalidationRange { if (self.is_committed()) return null; std.debug.assert(self.next_invalidation.len <= 1); if (self.next_invalidation.isEmpty()) return null; return self.next_invalidation.ranges()[0]; } pub fn scrollCommit( self: FrameCommitResult, scroll_plan: frame_scroll_plan.FrameScrollPlan, ) frame_scroll_plan.FrameScrollCommit { if (self.scroll_commit_receipt) |receipt| { std.debug.assert(receipt.matchesPlan(scroll_plan)); return receipt; } std.debug.assert(builtin.is_test); return scroll_plan.commit(self.terminal_scroll_rows_committed); } }; const CleanupState = enum { none, complete, failed, }; const DocumentAppendWireRange = struct { start: usize = 0, end: usize = 0, fn isEmpty(self: DocumentAppendWireRange) bool { return self.end == 0; } fn committed(self: DocumentAppendWireRange, accepted_bytes: usize) bool { return !self.isEmpty() and accepted_bytes >= self.end; } fn interrupted(self: DocumentAppendWireRange, accepted_bytes: usize) bool { return !self.isEmpty() and accepted_bytes > self.start and !self.committed(accepted_bytes); } }; const AcceptedFrameWrite = struct { accepted_bytes: usize, applied_scroll_rows: u16, scroll_attribution: FrameScrollAttribution, document_append_committed: bool, document_append_interrupted: bool, }; const DocumentAppendMovement = struct { segment: TerminalMovementSegment = .{}, }; const FrameMovementSegments = struct { movement_start: usize = 0, movement_end: usize = 0, document_append: TerminalMovementSegment = .{}, alignment_scroll: TerminalMovementSegment = .{}, fn none() FrameMovementSegments { return .{}; } fn fromPreparedMovement(prefix_len: usize, movement: PreparedTerminalMovement) FrameMovementSegments { return .{ .movement_start = prefix_len, .movement_end = prefix_len + movement.bytes.len, .document_append = movement.segments.document_append.absolute(prefix_len), .alignment_scroll = movement.segments.alignment_scroll.absolute(prefix_len), }; } }; const ScrollAttributionBucket = enum { control_prefix, document_append, alignment_scroll, movement_gap, paint_tail, }; const ShadowTestFault = enum { none, normal_clone_feed, normal_clone_invalid, repair_resize, repair_canonical_feed, }; var shadow_test_fault: if (builtin.is_test) ShadowTestFault else void = if (builtin.is_test) .none else {}; pub fn flushFrame(input: FrameCommitInput) !FrameCommitResult { try input.surface.plan.validate(); try input.surface.validate(); const alloc = input.surface.alloc; var target = try input.surface.copyToTargetGrid(alloc); defer target.deinit(); try input.scroll_plan.validate(target.rows); try input.repaint_window.validate(input.surface.plan); const repaint_window = input.repaint_window; const terminal_scroll_rows = input.scroll_plan.terminal_scroll_rows; if (input.document_append.reset_replay and !input.surface.plan.reset_terminal) { return error.InvalidFrameScrollPlan; } var local_movement: ?PreparedTerminalMovement = null; defer if (local_movement) |*movement| movement.deinit(alloc); const movement = if (input.prepared_movement) |prepared| prepared else blk: { local_movement = try prepareTerminalMovementForFrame( alloc, input.previous, input.document_append, terminal_scroll_rows, input.scroll_plan.preserved_release_rows, target.cols, target.rows, 0, input.terminal_transition, ); break :blk &local_movement.?; }; try movement.validateForCommit( input.previous, target.cols, target.rows, terminal_scroll_rows, input.scroll_plan.preserved_release_rows, input.terminal_transition, input.document_append.reset_replay, ); const terminal_scroll_bytes = movement.bytes; if (terminal_scroll_rows > 0 or movement.hasDocumentAppend()) { debug_trace.logf( "frame_commit", "terminal_movement planned_rows={d} materialized_rows={d} alignment_rows={d} append_bytes={d} append_wire_bytes={d}", .{ terminal_scroll_rows, movement.scroll_rows.materialized_scroll_rows, movement.scroll_rows.alignment_scroll_rows, input.document_append.bytes.len, movement.document_append_end -| movement.document_append_start, }, ); } const dimensions_changed = input.previous.rows != target.rows or input.previous.cols != target.cols; const previous_for_diff = movement.post_movement; const changed_cells = countChangedCells(previous_for_diff, target, repaint_window); const full_repaint = input.surface.plan.reset_terminal or dimensions_changed or terminal_scroll_rows > 0 or invalidationRequiresFullRepaint(input.surface.plan.invalidation); if (terminal_scroll_bytes.len == 0 and terminal_scroll_rows == 0 and !full_repaint and changed_cells == 0 and cursorMatches(previous_for_diff, target)) { debug_trace.logf( "frame_commit", "skipped_noop bytes=0 changed_cells=0 band={d}..{d} cursor={d},{d}", .{ firstRepaintRow(repaint_window), lastRepaintRow(repaint_window), target.cursor_row, target.cursor_col }, ); return committed_result( 0, 0, false, input.scroll_plan.commit(0), .{}, false, &target, ); } var wire_frame: std.Io.Writer.Allocating = .init(alloc); defer wire_frame.deinit(); const prefix_len = try composeWireFrame( &wire_frame, input, &previous_for_diff, &target, repaint_window, full_repaint, terminal_scroll_bytes, ); const wire_frame_bytes = wire_frame.written(); const document_append_range = movement.documentAppendWireRange(prefix_len); const frame_movement_segments = FrameMovementSegments.fromPreparedMovement(prefix_len, movement.*); const complete_scroll_attribution = try validateFrameScrollAttribution( alloc, input.previous, target.cols, target.rows, wire_frame_bytes, frame_movement_segments, movement.scroll_rows, ); const sink_result = input.sink.write_frame(input.sink.ctx, input.metrics, wire_frame_bytes); const accepted_write = try acceptedFrameWrite( alloc, input.previous, target.cols, target.rows, wire_frame_bytes, sink_result, document_append_range, frame_movement_segments, complete_scroll_attribution, ); try movement.validateCompleteWrite( accepted_write.accepted_bytes, wire_frame_bytes.len, accepted_write.scroll_attribution, ); const scroll_commit = input.scroll_plan.commitWithExpectedRows( accepted_write.applied_scroll_rows, movement.scroll_rows.expected_scroll_rows, ); switch (sink_result) { .complete => {}, .partial => |partial| { debug_trace.logf( "frame_commit", "wire_frame bytes={d} accepted_bytes={d} applied_scroll_rows={d} cleanup={s} err={s}", .{ wire_frame_bytes.len, accepted_write.accepted_bytes, accepted_write.applied_scroll_rows, @tagName(CleanupState.none), @errorName(partial.err) }, ); return recoverPartialFrame( input, changed_cells, full_repaint, wire_frame_bytes, accepted_write, scroll_commit, ); }, } var fed_shadow = cloneAuthoritativeShadow(alloc, input.previous, target.cols, target.rows) catch |err| { return shadowFeedFailedWithRepair(input, changed_cells, full_repaint, accepted_write.accepted_bytes, scroll_commit, accepted_write.scroll_attribution, accepted_write.document_append_committed, err); }; var fed_shadow_initialized = true; defer if (fed_shadow_initialized) fed_shadow.deinit(); if (consumeShadowTestFault(.normal_clone_feed)) { return shadowFeedFailedWithRepair( input, changed_cells, full_repaint, accepted_write.accepted_bytes, scroll_commit, accepted_write.scroll_attribution, accepted_write.document_append_committed, error.TestShadowFeedFailure, ); } fed_shadow.feed(wire_frame_bytes) catch |err| { return shadowFeedFailedWithRepair(input, changed_cells, full_repaint, accepted_write.accepted_bytes, scroll_commit, accepted_write.scroll_attribution, accepted_write.document_append_committed, err);