Merge remote-tracking branch 'evan108108/fix/canvas-getcontext-caching' into canvas_context_cache

This commit is contained in:
Karl Seguin
2026-03-30 11:58:45 +08:00

View File

@@ -30,6 +30,13 @@ const OffscreenCanvas = @import("../../canvas/OffscreenCanvas.zig");
const Canvas = @This(); const Canvas = @This();
_proto: *HtmlElement, _proto: *HtmlElement,
/// Cached context type. Once set, requesting a different type returns null (per spec).
_context_type: ContextType = .none,
/// Cached 2D rendering context (same object returned on repeated getContext("2d") calls).
_ctx_2d: ?*CanvasRenderingContext2D = null,
const ContextType = enum { none, @"2d", webgl };
pub fn asElement(self: *Canvas) *Element { pub fn asElement(self: *Canvas) *Element {
return self._proto._proto; return self._proto._proto;
} }
@@ -69,12 +76,23 @@ const DrawingContext = union(enum) {
pub fn getContext(self: *Canvas, context_type: []const u8, page: *Page) !?DrawingContext { pub fn getContext(self: *Canvas, context_type: []const u8, page: *Page) !?DrawingContext {
if (std.mem.eql(u8, context_type, "2d")) { if (std.mem.eql(u8, context_type, "2d")) {
// Return cached context if available.
if (self._ctx_2d) |cached| return .{ .@"2d" = cached };
// Per spec: return null if a different context type was already requested.
if (self._context_type != .none) return null;
const ctx = try page._factory.create(CanvasRenderingContext2D{ ._canvas = self }); const ctx = try page._factory.create(CanvasRenderingContext2D{ ._canvas = self });
self._ctx_2d = ctx;
self._context_type = .@"2d";
return .{ .@"2d" = ctx }; return .{ .@"2d" = ctx };
} }
if (std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl")) { if (std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl")) {
// Per spec: return null if a different context type was already requested.
if (self._context_type != .none and self._context_type != .webgl) return null;
const ctx = try page._factory.create(WebGLRenderingContext{}); const ctx = try page._factory.create(WebGLRenderingContext{});
self._context_type = .webgl;
return .{ .webgl = ctx }; return .{ .webgl = ctx };
} }