Skip to documentation
SLOP

tiny.gui.paint.retained

Reference tiny.gui paint retained

Defined in paint.

API (12)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callspaintretained
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callspaint.RetainedCommandscommitprivate sourcelib.gui.src.paint.retained.CommandsindexCurrentFragmentspaint.RetainedCommandsinvalidatepaint.RetainedCommandscancelPrepared
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallspaint.RetainedCommandsretainpaint.RetainedCommandscancelPreparedprivate sourcelib.gui.src.paint.retained.CommandscurrentIsIndexedpaint.RetainedCommandscommit
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallsNo direct callstest sourcelib.gui.src.paint.retainedtest: retained baseline rejects dupli...test sourcelib.gui.src.paint.retainedtest: retained clip shrink damages pi...test sourcelib.gui.src.paint.retainedtest: retained command bookkeeping ne...test sourcelib.gui.src.paint.retainedtest: retained damage includes remove...test sourcelib.gui.src.paint.retainedtest: retained duplicate fragment ide...+8 morepaint.RetainedCommandsdeinit
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallstest sourcelib.gui.src.paint.retainedtest: retained clip shrink damages pi...test sourcelib.gui.src.paint.retainedtest: retained command bookkeeping ne...test sourcelib.gui.src.paint.retainedtest: retained damage includes remove...test sourcelib.gui.src.paint.retainedtest: retained duplicate fragment ide...test sourcelib.gui.src.paint.retainedtest: retained equal commands preserv...+7 morepaint.CommandBufferfragmentItemsprivate sourcelib.gui.src.paint.retained.CommandsfragmentDamageprivate sourcelib.gui.src.paint.retained.CommandsindexCurrentFragmentsprivate sourcelib.gui.src.paint.retainedcommandDamageprivate sourcelib.gui.src.paint.retainednarrowerDamage+2 morepaint.RetainedCommandsdiff
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callstest sourcelib.gui.src.paint.retainedtest: retained baseline rejects dupli...test sourcelib.gui.src.paint.retainedtest: retained duplicate fragment ide...test sourcelib.gui.src.paint.retainedtest: retained preflight failure pres...paint.RetainedCommandshasBaseline
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.gui.src.paint.retainedtest: retained baseline rejects dupli...test sourcelib.gui.src.paint.retainedtest: retained clip shrink damages pi...test sourcelib.gui.src.paint.retainedtest: retained command bookkeeping ne...test sourcelib.gui.src.paint.retainedtest: retained damage includes remove...test sourcelib.gui.src.paint.retainedtest: retained duplicate fragment ide...+8 morepaint.RetainedCommandsinit
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callerspaint.RetainedCommandscancelPreparedpaint.RetainedCommandsinvalidate
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallspaint.RetainedCommandsretaintest sourcelib.gui.src.paint.retainedtest: retained preflight failure pres...paint.CommandBufferensureFragmentCapacityprivate sourcelib.gui.src.paint.retained.CommandscurrentIsIndexedprivate sourcelib.gui.src.paint.retained.CommandsindexCurrentFragmentsprivate sourcelib.gui.src.paint.retainedrequireCompletepaint.RetainedCommandsprepare
Static calls · unresolved targets: 2 · external targets: 1.
Called byCallstest sourcelib.gui.src.paint.retainedtest: retained baseline rejects dupli...test sourcelib.gui.src.paint.retainedtest: retained clip shrink damages pi...test sourcelib.gui.src.paint.retainedtest: retained command bookkeeping ne...test sourcelib.gui.src.paint.retainedtest: retained damage includes remove...test sourcelib.gui.src.paint.retainedtest: retained duplicate fragment ide...+8 morepaint.RetainedCommandscommitpaint.RetainedCommandspreparepaint.RetainedCommandsretain
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/gui/src/paint/retained.zig

zig
const std = @import("std");const gui = @import("../root.zig");const paint = @import("root.zig");const Allocator = std.mem.Allocator;const Command = paint.command.Command;const CommandBuffer = paint.command.CommandBuffer;const Fragment = paint.command.Fragment;const FragmentId = paint.command.FragmentId;const Rect = gui.layout.Rect;const Region = paint.cpu.Region;const RegionSet = paint.regions.Set;pub const Damage = union(enum) {    semantic,    narrowed: RegionSet,};pub const Commands = struct {    pub const Error = Allocator.Error || error{        DuplicateFragmentId,        TooManyFragments,        UnfragmentedCommands,    };    allocator: Allocator,    previous: CommandBuffer,    previous_index: std.AutoHashMapUnmanaged(FragmentId, u32) = .empty,    current_index: std.AutoHashMapUnmanaged(FragmentId, u32) = .empty,    seen_previous: std.ArrayListUnmanaged(bool) = .empty,    indexed_current: ?*const CommandBuffer = null,    indexed_command_count: usize = 0,    indexed_fragment_count: usize = 0,    valid: bool = false,    pub fn init(allocator: Allocator) Commands {        return .{            .allocator = allocator,            .previous = CommandBuffer.init(allocator),        };    }    pub fn deinit(self: *Commands) void {        self.previous.deinit();        self.previous_index.deinit(self.allocator);        self.current_index.deinit(self.allocator);        self.seen_previous.deinit(self.allocator);        self.* = undefined;    }    pub fn invalidate(self: *Commands) void {        self.cancelPrepared();        self.valid = false;    }    pub fn hasBaseline(self: *const Commands) bool {        return self.valid;    }    pub fn diff(        self: *Commands,        current: *const CommandBuffer,        limits: []const Region,        width: u32,        height: u32,    ) Error!Damage {        if (!self.valid) return .semantic;        try requireComplete(&self.previous);        try requireComplete(current);        try self.indexCurrentFragments(current);        try self.seen_previous.resize(            self.allocator,            self.previous.fragmentItems().len,        );        @memset(self.seen_previous.items, false);        if (!orderedLikePrevious(            self.previous_index,            current.fragmentItems(),        )) return .semantic;        const fragment_damage = try self.fragmentDamage(            current,            limits,            width,            height,        );        const command_damage = commandDamage(            &self.previous,            current,            limits,            width,            height,        );        return narrowerDamage(fragment_damage, command_damage);    }    pub fn retain(        self: *Commands,        current: *CommandBuffer,    ) (CommandBuffer.Error || Error)!void {        try self.prepare(current);        self.commit(current);    }    pub fn prepare(        self: *Commands,        current: *const CommandBuffer,    ) Error!void {        try requireComplete(current);        if (!self.currentIsIndexed(current)) {            try self.indexCurrentFragments(current);        }        try self.previous.ensureCapacity(current.items().len);        try self.previous.ensureFragmentCapacity(current.fragmentItems().len);    }    pub fn commit(        self: *Commands,        current: *CommandBuffer,    ) void {        std.debug.assert(current.fragmentsComplete());        std.debug.assert(self.previous.commands.capacity >= current.items().len);        std.debug.assert(            self.previous.fragments.capacity >= current.fragmentItems().len,        );        std.debug.assert(self.currentIsIndexed(current));        std.mem.swap(            std.AutoHashMapUnmanaged(FragmentId, u32),            &self.previous_index,            &self.current_index,        );        self.cancelPrepared();        std.mem.swap(CommandBuffer, &self.previous, current);        current.reset();        self.valid = true;    }    pub fn cancelPrepared(self: *Commands) void {        self.indexed_current = null;        self.indexed_command_count = 0;        self.indexed_fragment_count = 0;    }    fn indexCurrentFragments(        self: *Commands,        current: *const CommandBuffer,    ) Error!void {        self.cancelPrepared();        try reserveMap(            &self.current_index,            self.allocator,            current.fragmentItems().len,        );        self.current_index.clearRetainingCapacity();        for (current.fragmentItems(), 0..) |fragment, index| {            const value = std.math.cast(u32, index) orelse                return error.TooManyFragments;            try insertUnique(                &self.current_index,                self.allocator,                fragment.id,                value,            );        }        self.indexed_current = current;        self.indexed_command_count = current.items().len;        self.indexed_fragment_count = current.fragmentItems().len;    }    fn currentIsIndexed(        self: *const Commands,        current: *const CommandBuffer,    ) bool {        return self.indexed_current == current and            self.indexed_command_count == current.items().len and            self.indexed_fragment_count == current.fragmentItems().len;    }    fn fragmentDamage(        self: *Commands,        current: *const CommandBuffer,        limits: []const Region,        width: u32,        height: u32,    ) Error!Damage {        var regions = RegionSet{};        var changed = false;        for (current.fragmentItems()) |fragment| {            const previous_index = self.previous_index.get(fragment.id);            if (previous_index == null) {                changed = true;                includeFragment(&regions, fragment, limits, width, height);                continue;            }            self.seen_previous.items[previous_index.?] = true;            const old = self.previous.fragmentItems()[previous_index.?];            if (fragmentsEqual(&self.previous, old, current, fragment)) {                continue;            }            changed = true;            includeChangedCommands(                &regions,                &self.previous,                old,                current,                fragment,                limits,                width,                height,            );        }        changed = includeRemoved(self, &regions, limits, width, height) or changed;        if (!changed) return .semantic;        return .{ .narrowed = regions };    }};fn reserveMap(    map: anytype,    allocator: Allocator,    count: usize,) Allocator.Error!void {    const capacity = std.math.cast(u32, count) orelse        return error.OutOfMemory;    try map.ensureTotalCapacity(allocator, capacity);}fn insertUnique(    map: anytype,    allocator: Allocator,    id: FragmentId,    value: anytype,) Commands.Error!void {    const entry = try map.getOrPut(allocator, id);    if (entry.found_existing) return error.DuplicateFragmentId;    entry.value_ptr.* = value;}fn orderedLikePrevious(    previous: std.AutoHashMapUnmanaged(FragmentId, u32),    current: []const Fragment,) bool {    var last: ?u32 = null;    for (current) |fragment| {        const index = previous.get(fragment.id) orelse continue;        if (last) |prior| {            if (index <= prior) return false;        }        last = index;    }    return true;}fn includeRemoved(    self: *Commands,    regions: *RegionSet,    limits: []const Region,    width: u32,    height: u32,) bool {    var changed = false;    for (self.previous.fragmentItems(), 0..) |fragment, index| {        if (self.seen_previous.items[index]) continue;        includeFragment(regions, fragment, limits, width, height);        changed = true;    }    return changed;}fn includeFragment(    regions: *RegionSet,    fragment: Fragment,    limits: []const Region,    width: u32,    height: u32,) void {    includeRect(regions, fragment.bounds, limits, width, height);}fn includeCommand(    regions: *RegionSet,    value: Command,    limits: []const Region,    width: u32,    height: u32,) void {    includeRect(        regions,        paint.command.visibleBounds(value),        limits,        width,        height,    );}fn includeRect(    regions: *RegionSet,    rect: Rect,    limits: []const Region,    width: u32,    height: u32,) void {    const raw = paint.regions.fromRect(rect, 1, width, height) orelse return;    for (limits) |limit| {        const clipped = paint.regions.intersect(raw, limit);        if (clipped.pixelCount() != 0) regions.append(clipped);    }}fn includeChangedCommands(    regions: *RegionSet,    previous: *const CommandBuffer,    old: Fragment,    current: *const CommandBuffer,    new: Fragment,    limits: []const Region,    width: u32,    height: u32,) void {    const old_commands = fragmentCommands(previous, old);    const new_commands = fragmentCommands(current, new);    const count = @max(old_commands.len, new_commands.len);    for (0..count) |index| {        const before = if (index < old_commands.len)            old_commands[index]        else            null;        const after = if (index < new_commands.len)            new_commands[index]        else            null;        if (before != null and            after != null and            paint.command.visuallyEqual(before.?, after.?))        {            continue;        }        if (before) |value| {            includeCommand(regions, value, limits, width, height);        }        if (after) |value| {            includeCommand(regions, value, limits, width, height);        }    }}fn commandDamage(    previous: *const CommandBuffer,    current: *const CommandBuffer,    limits: []const Region,    width: u32,    height: u32,) Damage {    var regions = RegionSet{};    var changed = false;    const count = @max(previous.items().len, current.items().len);    for (0..count) |index| {        const before = if (index < previous.items().len)            previous.items()[index]        else            null;        const after = if (index < current.items().len)            current.items()[index]        else            null;        if (before != null and            after != null and            paint.command.visuallyEqual(before.?, after.?))        {            continue;        }        changed = true;        if (before) |value| {            includeCommand(&regions, value, limits, width, height);        }        if (after) |value| {            includeCommand(&regions, value, limits, width, height);        }    }    if (!changed) return .semantic;    return .{ .narrowed = regions };}fn narrowerDamage(fragment: Damage, command: Damage) Damage {    if (command == .semantic) return .semantic;    if (fragment == .semantic) return command;    const fragment_area = damageArea(fragment.narrowed);    const command_area = damageArea(command.narrowed);    return if (fragment_area <= command_area) fragment else command;}fn damageArea(regions: RegionSet) usize {    return if (regions.bounding()) |region| region.pixelCount() else 0;}fn fragmentsEqual(    previous: *const CommandBuffer,    old: Fragment,    current: *const CommandBuffer,    new: Fragment,) bool {    if (old.command_count != new.command_count) return false;    const old_commands = fragmentCommands(previous, old);    const new_commands = fragmentCommands(current, new);    for (old_commands, new_commands) |left, right| {        if (!paint.command.visuallyEqual(left, right)) return false;    }    return true;}fn fragmentCommands(    buffer: *const CommandBuffer,    fragment: Fragment,) []const Command {    const start: usize = fragment.command_start;    const end = start + fragment.command_count;    std.debug.assert(end <= buffer.items().len);    return buffer.items()[start..end];}fn requireComplete(    buffer: *const CommandBuffer,) error{UnfragmentedCommands}!void {    if (!buffer.fragmentsComplete()) return error.UnfragmentedCommands;}fn testId(value: u64) FragmentId {    return .{        .root_id = 1,        .element_id = value,        .namespace = 99,        .part = 1,    };}fn appendTestFragment(    buffer: *CommandBuffer,    id: FragmentId,    x: f32,    color: u8,) !void {    const start = buffer.items().len;    try buffer.append(.{        .kind = .fill,        .rect = .{ .x = x, .width = 8, .height = 8 },        .clip = .{ .width = 128, .height = 32 },        .color = .{ .r = color, .a = 255 },    });    try buffer.commitFragment(id, start);}fn appendTestCommandFragment(    buffer: *CommandBuffer,    id: FragmentId,    value: Command,) !void {    const start = buffer.items().len;    try buffer.append(value);    try buffer.commitFragment(id, start);}fn appendTestPairFragment(    buffer: *CommandBuffer,    id: FragmentId,    second_color: u8,) !void {    const start = buffer.items().len;    try buffer.append(.{        .kind = .fill,        .rect = .{ .x = 4, .width = 8, .height = 8 },        .clip = .{ .width = 128, .height = 32 },        .color = .{ .r = 10, .a = 255 },    });    try buffer.append(.{        .kind = .fill,        .rect = .{ .x = 80, .width = 8, .height = 8 },        .clip = .{ .width = 128, .height = 32 },        .color = .{ .r = second_color, .a = 255 },    });    try buffer.commitFragment(id, start);}test "retained insertion damages only the inserted fragment" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestFragment(&current, testId(1), 20, 10);    try appendTestFragment(&current, testId(2), 40, 20);    try retained.retain(&current);    try appendTestFragment(&current, testId(9), 2, 90);    try appendTestFragment(&current, testId(1), 20, 10);    try appendTestFragment(&current, testId(2), 40, 20);    const damage = try retained.diff(        &current,        &.{Region.full(128, 32)},        128,        32,    );    try std.testing.expectEqual(        Region{ .x = 1, .width = 10, .height = 9 },        damage.narrowed.bounding().?,    );}test "retained matched fragment damages only changed commands" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestPairFragment(&current, testId(1), 20);    try retained.retain(&current);    try appendTestPairFragment(&current, testId(1), 30);    const damage = try retained.diff(        &current,        &.{Region.full(128, 32)},        128,        32,    );    try std.testing.expectEqual(        Region{ .x = 79, .width = 10, .height = 9 },        damage.narrowed.bounding().?,    );}test "retained identity churn keeps narrower positional command damage" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestPairFragment(&current, testId(1), 20);    try retained.retain(&current);    try appendTestPairFragment(&current, testId(2), 30);    const damage = try retained.diff(        &current,        &.{Region.full(128, 32)},        128,        32,    );    try std.testing.expectEqual(        Region{ .x = 79, .width = 10, .height = 9 },        damage.narrowed.bounding().?,    );}test "retained reorder preserves semantic damage" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestFragment(&current, testId(1), 0, 10);    try appendTestFragment(&current, testId(2), 4, 20);    try retained.retain(&current);    try appendTestFragment(&current, testId(2), 4, 20);    try appendTestFragment(&current, testId(1), 0, 10);    const damage = try retained.diff(        &current,        &.{Region.full(32, 16)},        32,        16,    );    try std.testing.expect(damage == .semantic);}test "retained duplicate fragment identities reject" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestFragment(&current, testId(1), 0, 10);    try retained.retain(&current);    try appendTestFragment(&current, testId(2), 0, 10);    try appendTestFragment(&current, testId(2), 16, 20);    try std.testing.expectError(        error.DuplicateFragmentId,        retained.diff(&current, &.{Region.full(32, 16)}, 32, 16),    );    current.reset();    try appendTestFragment(&current, testId(3), 8, 30);    try retained.retain(&current);    try std.testing.expect(retained.hasBaseline());}test "retained baseline rejects duplicate fragment identities" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestFragment(&current, testId(2), 0, 10);    try appendTestFragment(&current, testId(2), 16, 20);    try std.testing.expectError(        error.DuplicateFragmentId,        retained.retain(&current),    );    try std.testing.expect(!retained.hasBaseline());}test "retained damage includes removed effects and current geometry" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestCommandFragment(&current, testId(1), .{        .kind = .shadow,        .rect = .{ .x = 10, .y = 10, .width = 10, .height = 10 },        .clip = .{ .width = 64, .height = 64 },        .color = .{ .a = 255 },        .width = 4,    });    try retained.retain(&current);    try appendTestCommandFragment(&current, testId(1), .{        .kind = .fill,        .rect = .{ .x = 20, .y = 20, .width = 10, .height = 10 },        .clip = .{ .width = 64, .height = 64 },        .color = .{ .a = 255 },    });    const damage = try retained.diff(        &current,        &.{Region.full(64, 64)},        64,        64,    );    try std.testing.expectEqual(        Region{ .x = 5, .y = 5, .width = 26, .height = 26 },        damage.narrowed.bounding().?,    );}test "retained clip shrink damages pixels uncovered by the old clip" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestCommandFragment(&current, testId(1), .{        .kind = .fill,        .rect = .{ .width = 16, .height = 8 },        .clip = .{ .width = 16, .height = 8 },        .color = .{ .a = 255 },    });    try retained.retain(&current);    try appendTestCommandFragment(&current, testId(1), .{        .kind = .fill,        .rect = .{ .width = 16, .height = 8 },        .clip = .{ .x = 4, .width = 12, .height = 8 },        .color = .{ .a = 255 },    });    const damage = try retained.diff(        &current,        &.{Region.full(32, 16)},        32,        16,    );    try std.testing.expect(damage == .narrowed);    try std.testing.expectEqual(        Region{ .width = 17, .height = 9 },        damage.narrowed.bounding().?,    );}test "retained linear gradient changes damage its widget bounds" {    const base = Command{        .kind = .linear_gradient,        .rect = .{ .x = 8, .y = 4, .width = 24, .height = 12 },        .clip = .{ .width = 64, .height = 32 },        .color = .{ .r = 20, .g = 40, .b = 80, .a = 255 },        .color_end = .{ .r = 80, .g = 140, .b = 220, .a = 255 },        .gradient_start = .{ .x = 8, .y = 4 },        .gradient_end = .{ .x = 32, .y = 16 },        .radius = 4,    };    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestCommandFragment(&current, testId(1), base);    try retained.retain(&current);    var changed = base;    changed.color_end.g = 180;    changed.gradient_end.y = 4;    try appendTestCommandFragment(&current, testId(1), changed);    const damage = try retained.diff(        &current,        &.{Region.full(64, 32)},        64,        32,    );    try std.testing.expect(damage == .narrowed);    try std.testing.expectEqual(        Region{ .x = 7, .y = 3, .width = 26, .height = 14 },        damage.narrowed.bounding().?,    );}test "retained equal commands preserve caller semantic damage" {    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestFragment(&current, testId(1), 4, 10);    try retained.retain(&current);    try appendTestFragment(&current, testId(1), 4, 10);    const damage = try retained.diff(        &current,        &.{Region{ .x = 2, .width = 12, .height = 8 }},        32,        16,    );    try std.testing.expect(damage == .semantic);}test "retained semantic damage repaints changed image content" {    const red = [_]u32{paint.packRgba(.{ .r = 255, .a = 255 })};    const blue = [_]u32{paint.packRgba(.{ .b = 255, .a = 255 })};    const old_images = paint.ImageSet{        .images = &.{.{ .width = 1, .height = 1, .pixels = &red }},    };    const new_images = paint.ImageSet{        .images = &.{.{ .width = 1, .height = 1, .pixels = &blue }},    };    const image_command = Command{        .kind = .image,        .rect = .{ .width = 1, .height = 1 },        .clip = .{ .width = 1, .height = 1 },        .color = .{ .r = 255, .g = 255, .b = 255, .a = 255 },    };    var retained = Commands.init(std.testing.allocator);    defer retained.deinit();    var current = CommandBuffer.init(std.testing.allocator);    defer current.deinit();    try appendTestCommandFragment(&current, testId(1), image_command);    var actual = [_]u32{0};    try paint.renderCommandsPackedWithImages(        current.items(),        .{ .width = 1, .height = 1, .pixels = &actual },        .{ .a = 255 },        old_images,    );    try retained.retain(&current);    try appendTestCommandFragment(&current, testId(1), image_command);    const semantic = Region.full(1, 1);    const damage = try retained.diff(        &current,        &.{semantic},        1,        1,    );    try std.testing.expect(damage == .semantic);    try paint.renderCommandsPackedRegionWithImages(        current.items(),        .{ .width = 1, .height = 1, .pixels = &actual },        .{ .a = 255 },        new_images,        semantic,    );    var expected = [_]u32{0};    try paint.renderCommandsPackedWithImages(        current.items(),        .{ .width = 1, .height = 1, .pixels = &expected },        .{ .a = 255 },        new_images,    );    try std.testing.expectEqualSlices(u32, &expected, &actual);}test "retained preflight failure preserves a reusable baseline" {    var failing = std.testing.FailingAllocator.init(std.testing.allocator, .{});    const allocator = failing.allocator();    var retained = Commands.init(allocator);    defer retained.deinit();    var current = CommandBuffer.init(allocator);    defer current.deinit();    try appendTestFragment(&current, testId(1), 0, 10);    try retained.retain(&current);    for (0..16) |index| {        try appendTestFragment(            &current,            testId(@intCast(index + 2)),            @floatFromInt(index * 4),            @intCast(index + 20),        );    }    failing.fail_index = failing.alloc_index;    failing.resize_fail_index = failing.resize_index;    try std.testing.expectError(error.OutOfMemory, retained.prepare(&current));    try std.testing.expect(failing.has_induced_failure);    try std.testing.expect(retained.hasBaseline());    failing.fail_index = std.math.maxInt(usize);    failing.resize_fail_index = std.math.maxInt(usize);    const damage = try retained.diff(        &current,        &.{Region.full(128, 32)},        128,        32,    );    try std.testing.expect(damage == .narrowed);    try retained.retain(&current);    try std.testing.expect(retained.hasBaseline());}test "retained command bookkeeping needs no allocation after warmup" {    var failing = std.testing.FailingAllocator.init(std.testing.allocator, .{});    var retained = Commands.init(failing.allocator());    defer retained.deinit();    var current = CommandBuffer.init(failing.allocator());    defer current.deinit();    try appendTestFragment(&current, testId(1), 4, 10);    try appendTestFragment(&current, testId(2), 20, 20);    try retained.retain(&current);    try appendTestFragment(&current, testId(1), 4, 10);    try appendTestFragment(&current, testId(2), 20, 20);    _ = try retained.diff(&current, &.{Region.full(64, 16)}, 64, 16);    try retained.retain(&current);    failing.fail_index = failing.alloc_index;    failing.resize_fail_index = failing.resize_index;    for (0..8) |_| {        try appendTestFragment(&current, testId(1), 4, 10);        try appendTestFragment(&current, testId(2), 20, 20);        _ = try retained.diff(&current, &.{Region.full(64, 16)}, 64, 16);        try retained.retain(&current);    }    try std.testing.expect(!failing.has_induced_failure);}

Source: lib/gui/src/paint/root.zig:10

zig
pub const retained = @import("retained.zig");

Complete caller list for paint.RetainedCommands.deinit

13 direct callers.

Complete caller list for paint.RetainedCommands.diff

12 direct callers.

Complete call list for paint.RetainedCommands.diff

7 direct calls.

Complete caller list for paint.RetainedCommands.init

13 direct callers.

Complete caller list for paint.RetainedCommands.retain

13 direct callers.

Audit

Definitions13
Public names24
Members11
Version26.7.0
Revisiondaab053ee433