Skip to content

Commit 4083f02

Browse files
committed
chore: updates
1 parent 7cfee10 commit 4083f02

File tree

8 files changed

+234
-45
lines changed

8 files changed

+234
-45
lines changed

napi/canvas-napi/canvas.ts

+137-4
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class NSCCanvas extends NSView {
219219
mtlViewPtr?: interop.Pointer;
220220
glViewPtr?: interop.Pointer;
221221
gpuContext?: GPUCanvasContext;
222+
glContext: WebGLRenderingContext | WebGL2RenderingContext | undefined;
222223

223224
initWebGPUContext() {
224225
if (this.gpuContext) {
@@ -245,6 +246,7 @@ class NSCCanvas extends NSView {
245246
}
246247
if (this.engine == Engine.GL) {
247248
this.glkView?.openGLContext?.makeCurrentContext?.();
249+
this.glkView?.openGLContext?.update?.();
248250
}
249251
if (this.is2D) {
250252
(<any>this._canvas?.deref()?._2dContext)?.resize?.(this.surfaceWidth, this.surfaceHeight);
@@ -407,6 +409,100 @@ class CanvasReadyEvent extends Event {
407409
}
408410
}
409411

412+
const defaultOpts = {
413+
alpha: true,
414+
antialias: true,
415+
depth: true,
416+
failIfMajorPerformanceCaveat: false,
417+
powerPreference: 'default',
418+
premultipliedAlpha: true,
419+
preserveDrawingBuffer: false,
420+
stencil: false,
421+
desynchronized: false,
422+
xrCompatible: false,
423+
};
424+
425+
const defaultGLOptions = {
426+
alpha: true,
427+
antialias: true,
428+
depth: true,
429+
failIfMajorPerformanceCaveat: false,
430+
powerPreference: 'default',
431+
premultipliedAlpha: true,
432+
preserveDrawingBuffer: false,
433+
stencil: false,
434+
desynchronized: false,
435+
xrCompatible: false,
436+
};
437+
438+
const default2DOptions = {
439+
alpha: true,
440+
antialias: true,
441+
depth: false,
442+
failIfMajorPerformanceCaveat: false,
443+
powerPreference: 'default',
444+
premultipliedAlpha: true,
445+
preserveDrawingBuffer: false,
446+
stencil: false,
447+
desynchronized: false,
448+
xrCompatible: false,
449+
};
450+
451+
function parsePowerPreference(powerPreference: string) {
452+
switch (powerPreference) {
453+
case 'default':
454+
return 0;
455+
case 'high-performance':
456+
return 1;
457+
case 'low-power':
458+
return 2;
459+
default:
460+
return -1;
461+
}
462+
}
463+
464+
function handleContextOptions(type: '2d' | 'webgl' | 'webgl2' | 'experimental-webgl' | 'experimental-webgl2', contextAttributes) {
465+
if (!contextAttributes) {
466+
if (type === '2d') {
467+
return { ...default2DOptions, powerPreference: 0 };
468+
}
469+
if (type.indexOf('webgl') > -1) {
470+
return { ...defaultGLOptions, powerPreference: 0 };
471+
}
472+
}
473+
if (type === '2d') {
474+
if (contextAttributes.alpha !== undefined && typeof contextAttributes.alpha === 'boolean') {
475+
return { ...contextAttributes, powerPreference: 0 };
476+
} else {
477+
return { alpha: true, powerPreference: 0 };
478+
}
479+
}
480+
const glOptions = { ...defaultGLOptions };
481+
const setIfDefined = (prop: keyof typeof defaultGLOptions, value: unknown) => {
482+
if (value !== undefined) {
483+
if (prop === 'powerPreference') {
484+
// Handle specific conversion logic for 'powerPreference'
485+
glOptions[prop] = value as (typeof glOptions)[typeof prop];
486+
} else if (typeof value === typeof glOptions[prop]) {
487+
glOptions[prop] = value as (typeof glOptions)[typeof prop];
488+
}
489+
}
490+
};
491+
if (type.indexOf('webgl') > -1) {
492+
setIfDefined('alpha', contextAttributes.alpha);
493+
setIfDefined('antialias', contextAttributes.antialias);
494+
setIfDefined('depth', contextAttributes.depth);
495+
setIfDefined('failIfMajorPerformanceCaveat', contextAttributes.failIfMajorPerformanceCaveat);
496+
setIfDefined('powerPreference', parsePowerPreference(contextAttributes.powerPreference ?? 'default'));
497+
setIfDefined('premultipliedAlpha', contextAttributes.premultipliedAlpha);
498+
setIfDefined('preserveDrawingBuffer', contextAttributes.preserveDrawingBuffer);
499+
setIfDefined('stencil', contextAttributes.stencil);
500+
setIfDefined('desynchronized', contextAttributes.desynchronized);
501+
return glOptions;
502+
}
503+
return null;
504+
}
505+
410506
@view({
411507
name: 'HTMLCanvasElement',
412508
tagName: 'canvas',
@@ -557,11 +653,19 @@ export class Canvas extends ViewBase {
557653
if (this._2dContext) {
558654
return this._2dContext;
559655
}
656+
657+
const opts = {
658+
...defaultOpts,
659+
...handleContextOptions(contextType, options),
660+
fontColor: -16777216,
661+
};
662+
560663
const scale = NSScreen.mainScreen.backingScaleFactor;
561664

562665
if (Canvas.forceGL) {
563666
const handle = interop.handleof(this._canvas.glkView);
564-
this._2dContext = CanvasRenderingContext2D.withView(handle.toNumber(), this._canvas.surfaceWidth, this._canvas.surfaceHeight, scale, options?.alpha ?? true, 0, 90, 1);
667+
668+
this._2dContext = CanvasRenderingContext2D.withView(handle.toNumber(), this._canvas.surfaceWidth, this._canvas.surfaceHeight, scale, opts.alpha, opts.fontColor, 90, 1);
565669
this._canvas.glkView!.isHidden = false;
566670
this._contextType = ContextType.Canvas;
567671
this._canvas.engine = Engine.GL;
@@ -570,13 +674,17 @@ export class Canvas extends ViewBase {
570674
const mtlViewHandle = interop.handleof(this._canvas.mtlView);
571675
const deviceHandle = interop.handleof(this._canvas.mtlView!.device);
572676
const queueHandle = interop.handleof(this._canvas.mtlView!.queue);
573-
this._2dContext = CanvasRenderingContext2D.withMtlViewDeviceQueue(mtlViewHandle.toNumber(), deviceHandle.toNumber(), queueHandle.toNumber(), options?.alpha ?? true, scale, 1, 0, 90, 1);
677+
this._2dContext = CanvasRenderingContext2D.withMtlViewDeviceQueue(mtlViewHandle.toNumber(), deviceHandle.toNumber(), queueHandle.toNumber(), opts.alpha, scale, 1, opts.fontColor, 90, 1);
574678
this._canvas.mtlView!.isHidden = false;
575679
this._contextType = ContextType.Canvas;
576680
this._canvas.engine = Engine.GPU;
577681
this._canvas._is2D = true;
578682
}
579683

684+
if (this._2dContext) {
685+
(<any>this._2dContext).canvas = this;
686+
}
687+
580688
return this._2dContext;
581689
} else if (contextType === 'webgl' || contextType === 'experimental-webgl') {
582690
if (this._2dContext || this._webgl2Context || this._gpuContext) {
@@ -586,8 +694,19 @@ export class Canvas extends ViewBase {
586694
return this._webglContext;
587695
}
588696

697+
const opts = {
698+
...defaultOpts,
699+
...handleContextOptions(contextType, options),
700+
fontColor: -16777216,
701+
};
702+
589703
const handle = interop.handleof(this._canvas.glkView);
590-
this._webglContext = WebGLRenderingContext.withView(handle.toNumber(), true, false, false, false, 1, true, false, false, false, false);
704+
this._webglContext = WebGLRenderingContext.withView(handle.toNumber(), opts.alpha, opts.antialias, opts.depth, opts.failIfMajorPerformanceCaveat, opts.powerPreference, opts.premultipliedAlpha, opts.preserveDrawingBuffer, opts.stencil, opts.desynchronized, opts.xrCompatible);
705+
if (this._webglContext) {
706+
(<any>this._webglContext).canvas = this;
707+
}
708+
709+
this._canvas.glContext = this._webglContext;
591710
this._canvas.glkView!.isHidden = false;
592711
this._contextType = ContextType.WebGL;
593712
this._canvas.engine = Engine.GL;
@@ -599,9 +718,19 @@ export class Canvas extends ViewBase {
599718
if (this._webgl2Context) {
600719
return this._webgl2Context;
601720
}
721+
const opts = {
722+
...defaultOpts,
723+
...handleContextOptions(contextType, options),
724+
fontColor: -16777216,
725+
};
602726

603727
const handle = interop.handleof(this._canvas.glkView);
604-
this._webgl2Context = WebGL2RenderingContext.withView(handle.toNumber(), true, false, false, false, 1, true, false, false, false, false);
728+
this._webgl2Context = WebGL2RenderingContext.withView(handle.toNumber(), opts.alpha, opts.antialias, opts.depth, opts.failIfMajorPerformanceCaveat, opts.powerPreference, opts.premultipliedAlpha, opts.preserveDrawingBuffer, opts.stencil, opts.desynchronized, opts.xrCompatible);
729+
if (this._webgl2Context) {
730+
(<any>this._webgl2Context).canvas = this;
731+
}
732+
733+
this._canvas.glContext = this._webgl2Context;
605734
this._canvas.glkView!.isHidden = false;
606735
this._contextType = ContextType.WebGL2;
607736
this._canvas.engine = Engine.GL;
@@ -617,6 +746,10 @@ export class Canvas extends ViewBase {
617746
this._canvas.engine = Engine.GPU;
618747
}
619748

749+
if (this._gpuContext) {
750+
(<any>this._gpuContext).canvas = this;
751+
}
752+
620753
return this._gpuContext;
621754
}
622755
}

napi/canvas-napi/examples/node/main.mts

+13-15
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import '../app.ts';
66
import '../../canvas';
77
import installPolyfills from '../../polyfill';
88
import three from './three';
9-
const { webgpuCube } = three;
9+
const { webgpuCube, cube } = three;
1010

1111
// import { run as texturedCube } from './texturedCube';
1212
// import { run as twoCubes } from './twoCubes.ts';
@@ -538,18 +538,17 @@ function solarSystem(canvas) {
538538
}
539539

540540

541-
function swarm(canvas, width, height, nativeCanvas) {
541+
function swarm(canvas, width?: number, height?: number) {
542542
var requestAnimFrame = requestAnimationFrame;
543543

544544
function init() {
545545
//canvas.nativeView.setHandleInvalidationManually(true);
546546
// Initialize the context of the canvas
547547

548548
// canvas.nativeView.handleInvalidationManually = true
549-
550549
// Set the canvas width and height to occupy full window
551-
var W = width || canvas.clientWidth * window.devicePixelRatio,
552-
H = height || canvas.clientHeight * window.devicePixelRatio;
550+
var W = width ?? canvas.clientWidth * window.devicePixelRatio,
551+
H = height ?? canvas.clientHeight * window.devicePixelRatio;
553552

554553
canvas.width = W;
555554
canvas.height = H;
@@ -1395,12 +1394,10 @@ function doGL() {
13951394
}
13961395

13971396

1398-
const window = document.createElement('window') as HTMLElement & {
1399-
devicePixelRatio: number
1400-
};
1397+
const windowDoc = document.createElement('window');
14011398

1402-
window.style.width = `${NSScreen.mainScreen.frame.size.width * .66}`;
1403-
window.style.height = `${NSScreen.mainScreen.frame.size.height * .66}`;
1399+
windowDoc.style.width = `${NSScreen.mainScreen.frame.size.width * .66}`;
1400+
windowDoc.style.height = `${NSScreen.mainScreen.frame.size.height * .66}`;
14041401

14051402
installPolyfills(globalThis.window);
14061403

@@ -1534,24 +1531,25 @@ canvas.addEventListener('ready', (event) => {
15341531
// twoCubes(canvas);
15351532
// computeBoids(canvas);
15361533
// wireframe(canvas);
1537-
renderBundles(canvas);
1534+
// renderBundles(canvas);
15381535
//webgpuCube(canvas);
15391536
//cubeMap(canvas);
1537+
cube(canvas);
15401538
});
15411539

15421540
canvas.width = NSScreen.mainScreen.frame.size.width;
15431541
canvas.height = NSScreen.mainScreen.frame.size.height;
15441542

1545-
window.setAttribute('styleMask', (
1543+
windowDoc.setAttribute('styleMask', (
15461544
NSWindowStyleMask.Titled | NSWindowStyleMask.Closable | NSWindowStyleMask.Miniaturizable | NSWindowStyleMask.Resizable | NSWindowStyleMask.FullSizeContentView
15471545
) as never);
15481546

15491547
const color = NSColor.colorWithCalibratedHueSaturationBrightnessAlpha(0,0,0.2, 0.5);
15501548
const background = `rgba(${color.redComponent * 255}, ${color.greenComponent * 255}, ${color.blueComponent * 255}, ${color.alphaComponent})`;
1551-
window.style.backgroundColor = background;
1552-
window.appendChild(canvas);
1549+
// window.style.backgroundColor = background;
1550+
windowDoc.appendChild(canvas);
15531551

1554-
document.body.appendChild(window);
1552+
document.body.appendChild(windowDoc);
15551553

15561554
globalThis.NativeScriptApplication.launch();
15571555

napi/canvas-napi/examples/node/three.ts

+61-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
let isAvailable = typeof navigator !== 'undefined' && navigator.gpu !== undefined;
22
console.log('isAvailable', isAvailable);
33

4-
import * as THREE from 'three/webgpu';
4+
// import * as THREE from 'three';
5+
// import * as THREEWebGPU from 'three/webgpu';
6+
57
async function webgpuCube(canvas) {
68
// const adapter = await navigator.gpu?.requestAdapter();
79
// const device: GPUDevice = (await adapter?.requestDevice()) as never;
10+
/*
811
912
var camera, scene, renderer;
1013
var geometry, material, mesh;
@@ -39,21 +42,75 @@ async function webgpuCube(canvas) {
3942
mesh = new THREE.Mesh(geometry, material);
4043
scene.add(mesh);
4144
42-
renderer = new THREE.WebGPURenderer({ canvas });
45+
renderer = new THREEWebGPU.WebGPURenderer({ canvas });
4346
4447
await renderer.init();
4548
renderer.setPixelRatio(window.devicePixelRatio);
4649
renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
4750
48-
console.log(canvas.getContext('webgpu'), canvas.getContext('webgl'), canvas.getContext('webgl2'));
49-
5051
context = canvas.getContext('webgpu');
5152
renderer.setAnimationLoop(animate);
5253
}
5354
5455
init();
56+
57+
*/
58+
}
59+
60+
function cube(canvas) {
61+
// const adapter = await navigator.gpu?.requestAdapter();
62+
// const device: GPUDevice = (await adapter?.requestDevice()) as never;
63+
64+
var camera, scene, renderer;
65+
var geometry, material, mesh;
66+
var context;
67+
68+
function animate() {
69+
mesh.rotation.x += 0.01;
70+
mesh.rotation.y += 0.02;
71+
72+
renderer.render(scene, camera);
73+
74+
context.render();
75+
}
76+
77+
function init() {
78+
canvas.width = canvas.clientWidth * window.devicePixelRatio;
79+
canvas.height = canvas.clientHeight * window.devicePixelRatio;
80+
const innerWidth = canvas.clientWidth;
81+
const innerHeight = canvas.clientHeight;
82+
83+
// camera = new THREE.PerspectiveCamera(50, innerWidth / innerHeight, 0.1, 10);
84+
// camera.position.z = 1;
85+
//
86+
// scene = new THREE.Scene();
87+
//
88+
// geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
89+
// material = new THREE.MeshNormalMaterial();
90+
//
91+
// mesh = new THREE.Mesh(geometry, material);
92+
// scene.add(mesh);
93+
//
94+
// renderer = new THREE.WebGLRenderer({ canvas });
95+
//
96+
// renderer.setPixelRatio(window.devicePixelRatio);
97+
// renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
98+
99+
context = canvas.getContext('webgl2');
100+
context.clearColor(1, 0, 0, 1);
101+
context.clear(context.COLOR_BUFFER_BIT);
102+
context.flush();
103+
console.log(context.toDataURL());
104+
const ctx = context.canvas._canvas.glkView?.openGLContext as NSOpenGLContext;
105+
106+
//context.render();
107+
//renderer.setAnimationLoop(animate);
108+
}
109+
110+
init();
55111
}
56112

57113
export default {
58114
webgpuCube,
115+
cube,
59116
};

napi/canvas-napi/index.d.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,12 @@ export declare class WEBGL_compressed_texture_s3tc {}
11491149
export declare class WEBGL_lose_context {}
11501150
export declare class WEBGL_depth_texture {}
11511151
export declare class WEBGL_draw_buffers {}
1152-
export declare class WebGLShaderPrecisionFormat {}
1152+
export type web_g_l_shader_precision_format = WebGLShaderPrecisionFormat;
1153+
export declare class WebGLShaderPrecisionFormat {
1154+
get precision(): number;
1155+
get rangeMin(): number;
1156+
get rangeMax(): number;
1157+
}
11531158
export declare class WebGLUniformLocation {}
11541159
export type web_g_l_rendering_context = WebGLRenderingContext;
11551160
export declare class WebGLRenderingContext {

0 commit comments

Comments
 (0)