mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-31 01:28:55 +00:00
Improve canvas context caching
Improve https://github.com/lightpanda-io/browser/pull/2022 to also cache webgl context and add tests.
This commit is contained in:
@@ -148,3 +148,13 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</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>
|
||||||
|
|||||||
@@ -85,3 +85,13 @@
|
|||||||
loseContext.restoreContext();
|
loseContext.restoreContext();
|
||||||
}
|
}
|
||||||
</script>
|
</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>
|
||||||
|
|||||||
@@ -29,11 +29,7 @@ const OffscreenCanvas = @import("../../canvas/OffscreenCanvas.zig");
|
|||||||
|
|
||||||
const Canvas = @This();
|
const Canvas = @This();
|
||||||
_proto: *HtmlElement,
|
_proto: *HtmlElement,
|
||||||
|
_cached: ?DrawingContext = null,
|
||||||
/// 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 };
|
const ContextType = enum { none, @"2d", webgl };
|
||||||
|
|
||||||
@@ -75,28 +71,28 @@ 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 (self._cached) |cached| {
|
||||||
// Return cached context if available.
|
const matches = switch (cached) {
|
||||||
if (self._ctx_2d) |cached| return .{ .@"2d" = cached };
|
.@"2d" => std.mem.eql(u8, context_type, "2d"),
|
||||||
// Per spec: return null if a different context type was already requested.
|
.webgl => std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl"),
|
||||||
if (self._context_type != .none) return null;
|
};
|
||||||
|
return if (matches) cached else null;
|
||||||
const ctx = try page._factory.create(CanvasRenderingContext2D{ ._canvas = self });
|
|
||||||
self._ctx_2d = ctx;
|
|
||||||
self._context_type = .@"2d";
|
|
||||||
return .{ .@"2d" = ctx };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl")) {
|
const drawing_context: DrawingContext = blk: {
|
||||||
// Per spec: return null if a different context type was already requested.
|
if (std.mem.eql(u8, context_type, "2d")) {
|
||||||
if (self._context_type != .none and self._context_type != .webgl) return null;
|
const ctx = try page._factory.create(CanvasRenderingContext2D{ ._canvas = self });
|
||||||
|
break :blk .{ .@"2d" = ctx };
|
||||||
|
}
|
||||||
|
|
||||||
const ctx = try page._factory.create(WebGLRenderingContext{});
|
if (std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl")) {
|
||||||
self._context_type = .webgl;
|
const ctx = try page._factory.create(WebGLRenderingContext{});
|
||||||
return .{ .webgl = ctx };
|
break :blk .{ .webgl = ctx };
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
return null;
|
};
|
||||||
|
self._cached = drawing_context;
|
||||||
|
return drawing_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transfers control of the canvas to an OffscreenCanvas.
|
/// Transfers control of the canvas to an OffscreenCanvas.
|
||||||
|
|||||||
Reference in New Issue
Block a user