diff options
Diffstat (limited to 'src/gl.zig')
| -rw-r--r-- | src/gl.zig | 40 |
1 files changed, 29 insertions, 11 deletions
@@ -355,17 +355,25 @@ pub const ShaderProgram = struct { }; pub const UniformCache = struct { - uniforms: std.AutoHashMap([*]const u8, CachedUniform), + allocator: *std.mem.Allocator, + uniforms: std.StringHashMap(CachedUniform), shader: *ShaderProgram, pub fn init(allocator: *std.mem.Allocator, shader: *ShaderProgram) UniformCache { return UniformCache{ - .uniforms = std.AutoHashMap([*]const u8, CachedUniform).init(allocator), + .allocator = allocator, + .uniforms = std.StringHashMap(CachedUniform).init(allocator), .shader = shader, }; } pub fn deinit(self: *UniformCache) void { + var it = self.uniforms.iterator(); + while (it.next()) |entry| { + self.allocator.free(entry.key); + } + + self.uniforms.clear(); self.uniforms.deinit(); } @@ -374,8 +382,10 @@ pub const UniformCache = struct { c.glGetProgramiv(self.shader.program_id, c.GL_ACTIVE_UNIFORMS, &uniform_count); const count = self.uniforms.count(); - var existing_names = try c_allocator.alloc([*]const u8, count); + var existing_names = try c_allocator.alloc([]const u8, count); defer c_allocator.free(existing_names); + var existing_names_c = try c_allocator.alloc([*]const u8, count); + defer c_allocator.free(existing_names_c); var existing_indices = try c_allocator.alloc(c.GLuint, count); defer c_allocator.free(existing_indices); @@ -384,30 +394,38 @@ pub const UniformCache = struct { var i: usize = 0; while (it.next()) |entry| { existing_names[i] = entry.key; + existing_names_c[i] = entry.key.ptr; i += 1; } } - c.glGetUniformIndices(self.shader.program_id, @intCast(c.GLsizei, count), existing_names.ptr, existing_indices.ptr); + c.glGetUniformIndices(self.shader.program_id, @intCast(c.GLsizei, count), existing_names_c.ptr, existing_indices.ptr); for (existing_indices) |index, i| { const name = existing_names[i]; if (index == c.GL_INVALID_INDEX) { - _ = self.uniforms.remove(name); - // @TODO: remove OSC link + if (self.uniforms.remove(name)) |removed| { + // @TODO: remove OSC link + self.allocator.free(removed.key); + } } else { var uniform = self.uniforms.get(name).?.value; - uniform.location = self.shader.uniformLocation(name) catch unreachable; + uniform.location = self.shader.uniformLocation(name.ptr) catch unreachable; uniform.setShaderValue(self.shader.*); } } } - pub fn get(self: *UniformCache, name: [*]const u8) !?*CachedUniform { - var result = try self.uniforms.getOrPut(name); + // name has to be zero-terminated! + pub fn get(self: *UniformCache, name: []const u8) !?*CachedUniform { + const cloned_name = try std.mem.dupe(self.allocator, u8, name); + errdefer self.allocator.free(cloned_name); + + var result = try self.uniforms.getOrPut(cloned_name); if (!result.found_existing) { - result.kv.value = CachedUniform.init(self.shader.*, name) catch { - _ = self.uniforms.remove(name); + result.kv.value = CachedUniform.init(self.shader.*, name.ptr) catch { + _ = self.uniforms.remove(cloned_name); + self.allocator.free(cloned_name); return null; }; // @TODO: add OSC link |
