@@ -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}
0 commit comments