renderer/opengl: clean up texture sync

This commit is contained in:
Mitchell Hashimoto
2024-04-06 09:34:34 -07:00
parent 45f518851d
commit a22ca8e4c1

View File

@ -1627,88 +1627,78 @@ pub fn setScreenSize(
/// Updates the font texture atlas if it is dirty. /// Updates the font texture atlas if it is dirty.
fn flushAtlas(self: *OpenGL) !void { fn flushAtlas(self: *OpenGL) !void {
const gl_state = self.gl_state orelse return; const gl_state = self.gl_state orelse return;
try flushAtlasSingle(
&self.font_grid.lock,
gl_state.texture,
&self.font_grid.atlas_greyscale,
&self.texture_greyscale_modified,
&self.texture_greyscale_resized,
.red,
.red,
);
try flushAtlasSingle(
&self.font_grid.lock,
gl_state.texture_color,
&self.font_grid.atlas_color,
&self.texture_color_modified,
&self.texture_color_resized,
.rgba,
.bgra,
);
}
texture: { /// Flush a single atlas, grabbing all necessary locks, checking for
// If the texture isn't modified we do nothing /// changes, etc.
const atlas = &self.font_grid.atlas_greyscale; fn flushAtlasSingle(
const modified = atlas.modified.load(.monotonic); lock: *std.Thread.RwLock,
if (modified <= self.texture_greyscale_modified) break :texture; texture: gl.Texture,
self.texture_greyscale_modified = modified; atlas: *font.Atlas,
modified: *usize,
resized: *usize,
interal_format: gl.Texture.InternalFormat,
format: gl.Texture.Format,
) !void {
// If the texture isn't modified we do nothing
const new_modified = atlas.modified.load(.monotonic);
if (new_modified <= modified.*) return;
// If it is modified we need to grab a read-lock // If it is modified we need to grab a read-lock
self.font_grid.lock.lockShared(); lock.lockShared();
defer self.font_grid.lock.unlockShared(); defer lock.unlockShared();
var texbind = try gl_state.texture.bind(.@"2D"); var texbind = try texture.bind(.@"2D");
defer texbind.unbind(); defer texbind.unbind();
const resized = atlas.resized.load(.monotonic); const new_resized = atlas.resized.load(.monotonic);
if (resized > self.texture_greyscale_resized) { if (new_resized > resized.*) {
self.texture_greyscale_resized = resized; try texbind.image2D(
try texbind.image2D( 0,
0, interal_format,
.red, @intCast(atlas.size),
@intCast(atlas.size), @intCast(atlas.size),
@intCast(atlas.size), 0,
0, format,
.red, .UnsignedByte,
.UnsignedByte, atlas.data.ptr,
atlas.data.ptr, );
);
} else { // Only update the resized number after successful resize
try texbind.subImage2D( resized.* = new_resized;
0, } else {
0, try texbind.subImage2D(
0, 0,
@intCast(atlas.size), 0,
@intCast(atlas.size), 0,
.red, @intCast(atlas.size),
.UnsignedByte, @intCast(atlas.size),
atlas.data.ptr, format,
); .UnsignedByte,
} atlas.data.ptr,
);
} }
texture: { // Update our modified tracker after successful update
// If the texture isn't modified we do nothing modified.* = atlas.modified.load(.monotonic);
const atlas = &self.font_grid.atlas_color;
const modified = atlas.modified.load(.monotonic);
if (modified <= self.texture_color_modified) break :texture;
self.texture_color_modified = modified;
// If it is modified we need to grab a read-lock
self.font_grid.lock.lockShared();
defer self.font_grid.lock.unlockShared();
var texbind = try gl_state.texture_color.bind(.@"2D");
defer texbind.unbind();
const resized = atlas.resized.load(.monotonic);
if (resized > self.texture_color_resized) {
self.texture_color_resized = resized;
try texbind.image2D(
0,
.rgba,
@intCast(atlas.size),
@intCast(atlas.size),
0,
.bgra,
.UnsignedByte,
atlas.data.ptr,
);
} else {
try texbind.subImage2D(
0,
0,
0,
@intCast(atlas.size),
@intCast(atlas.size),
.bgra,
.UnsignedByte,
atlas.data.ptr,
);
}
}
} }
/// Render renders the current cell state. This will not modify any of /// Render renders the current cell state. This will not modify any of