Merge pull request #2033 from lightpanda-io/canvas_context_cache

Canvas context cache
This commit is contained in:
Karl Seguin
2026-03-30 12:27:04 +08:00
committed by GitHub
3 changed files with 42 additions and 8 deletions

View File

@@ -148,3 +148,13 @@
}
</script>
<script id=identity>
{
const element = document.createElement('canvas');
const ctx = element.getContext('2d');
testing.expectTrue(ctx === element.getContext('2d'));
testing.expectEqual(null, element.getContext('webgl'));
}
</script>

View File

@@ -85,3 +85,13 @@
loseContext.restoreContext();
}
</script>
<script id=identity>
{
const element = document.createElement('canvas');
const ctx = element.getContext('webgl');
testing.expectTrue(ctx === element.getContext('webgl'));
testing.expectEqual(null, element.getContext('2d'));
}
</script>

View File

@@ -29,6 +29,9 @@ const OffscreenCanvas = @import("../../canvas/OffscreenCanvas.zig");
const Canvas = @This();
_proto: *HtmlElement,
_cached: ?DrawingContext = null,
const ContextType = enum { none, @"2d", webgl };
pub fn asElement(self: *Canvas) *Element {
return self._proto._proto;
@@ -68,17 +71,28 @@ const DrawingContext = union(enum) {
};
pub fn getContext(self: *Canvas, context_type: []const u8, page: *Page) !?DrawingContext {
if (std.mem.eql(u8, context_type, "2d")) {
const ctx = try page._factory.create(CanvasRenderingContext2D{ ._canvas = self });
return .{ .@"2d" = ctx };
if (self._cached) |cached| {
const matches = switch (cached) {
.@"2d" => std.mem.eql(u8, context_type, "2d"),
.webgl => std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl"),
};
return if (matches) cached else null;
}
if (std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl")) {
const ctx = try page._factory.create(WebGLRenderingContext{});
return .{ .webgl = ctx };
}
const drawing_context: DrawingContext = blk: {
if (std.mem.eql(u8, context_type, "2d")) {
const ctx = try page._factory.create(CanvasRenderingContext2D{ ._canvas = self });
break :blk .{ .@"2d" = ctx };
}
return null;
if (std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl")) {
const ctx = try page._factory.create(WebGLRenderingContext{});
break :blk .{ .webgl = ctx };
}
return null;
};
self._cached = drawing_context;
return drawing_context;
}
/// Transfers control of the canvas to an OffscreenCanvas.