diff options
Diffstat (limited to 'src/gui/Post.zig')
| -rw-r--r-- | src/gui/Post.zig | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/src/gui/Post.zig b/src/gui/Post.zig index 06310b7f..602b2790 100644 --- a/src/gui/Post.zig +++ b/src/gui/Post.zig @@ -94,6 +94,8 @@ pub const Pass = struct { pipeline: ?*Pipeline = null, /// The SPIR-V revision `pipeline` was made from (shader_build.Pass). revision: u32 = 0, + /// It moves on its own (shader_build.Pass). + animated: bool = false, }; passes: [max]Pass = @splat(.{}), @@ -140,7 +142,7 @@ pub fn sync(post: *Post, gpa: std.mem.Allocator, device: *c.SDL_GPUDevice, forma post.bloom_down = makePipeline(device, bloom_format, bloom_down_spv, 1, 1) catch null; post.bloom_up = makePipeline(device, bloom_format, bloom_up_spv, 1, 1) catch null; } - next[i] = .{ .scene = scene, .level = entry.level, .pipeline = post.bundled.get(scene) }; + next[i] = .{ .scene = scene, .level = entry.level, .pipeline = post.bundled.get(scene), .animated = entry.animated }; continue; } // A file already in the chain keeps its pipeline and its path. @@ -151,6 +153,7 @@ pub fn sync(post: *Post, gpa: std.mem.Allocator, device: *c.SDL_GPUDevice, forma break; } else next[i] = .{ .path = gpa.dupe(u8, entry.path) catch &.{} }; const pass = &next[i]; + pass.animated = entry.animated; if (pass.revision == entry.revision or entry.spirv.len == 0) continue; pass.revision = entry.revision; const made = makePipeline(device, format, entry.spirv, 1, 4) catch { @@ -200,8 +203,14 @@ pub fn ready(post: *const Post) bool { } /// The chain redraws on its own (level A) as ShaderAnimation says. +/// Only a pass that moves on its own (shader_build.Pass.animated) asks for +/// frames while idle: a still one (Bloom, Vignette, Grain, a file that reads +/// no clock) is drawn again only with a frame of the core's. pub fn animating(post: *const Post, mode: pardes.config.Runtime.ShaderAnimation) bool { - return post.ready() and switch (mode) { + const moving = for (post.passes[0..post.len]) |pass| { + if (pass.pipeline != null and pass.animated) break true; + } else false; + return moving and switch (mode) { .off => false, .on => post.uniforms.focus != 0, .always => true, @@ -664,3 +673,17 @@ test "a moved cursor becomes the previous one, stamped with the time of the move try std.testing.expectEqual([4]f32{ 1.0 / 255.0, 2.0 / 255.0, 3.0 / 255.0, 1 }, post.uniforms.selection_foreground_color); } + +test "a still pass asks for no idle frames; one that reads the clock does" { + var post: Post = .{}; + const fake: *Pipeline = @ptrFromInt(0x1000); + post.passes[0] = .{ .scene = .bloom, .level = 2, .pipeline = fake }; + post.len = 1; + try std.testing.expect(!post.animating(.on) and !post.animating(.always)); + post.passes[1] = .{ .scene = .crt, .level = 2, .pipeline = fake, .animated = true }; + post.len = 2; + try std.testing.expect(post.animating(.on) and post.animating(.always) and !post.animating(.off)); + // Unfocused, `on` rests. + post.uniforms.focus = 0; + try std.testing.expect(!post.animating(.on) and post.animating(.always)); +} |
