@@ -611,76 +611,43 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
611
611
612
612
#if TRACE_WEBGL_CALLS
613
613
hookWebGLFunction: ( f , glCtx ) => {
614
- var realf = 'real_' + f ;
615
- glCtx [ realf ] = glCtx [ f ] ;
616
- var numArgs = glCtx [ realf ] . length ;
617
- if ( numArgs === undefined ) console . warn ( `Unexpected WebGL function ${ f } when binding TRACE_WEBGL_CALLS` ) ;
614
+ var orig = glCtx [ f ] ;
618
615
var contextHandle = glCtx . canvas . GLctxObject . handle ;
619
- var threadId = ( typeof _pthread_self != 'undefined' ) ? _pthread_self : ( ) => 1 ;
620
- // Accessing 'arguments' is super slow, so to avoid overhead, statically reason the number of arguments.
621
- switch ( numArgs ) {
622
- case 0 : glCtx [ f ] = ( ) => { var ret = glCtx [ realf ] ( ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } () -> ${ ret } ` ) ; return ret ; } ; break ;
623
- case 1 : glCtx [ f ] = ( a1 ) => { var ret = glCtx [ realf ] ( a1 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
624
- case 2 : glCtx [ f ] = ( a1 , a2 ) => { var ret = glCtx [ realf ] ( a1 , a2 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
625
- case 3 : glCtx [ f ] = ( a1 , a2 , a3 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } , ${ a3 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
626
- case 4 : glCtx [ f ] = ( a1 , a2 , a3 , a4 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
627
- case 5 : glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 , a5 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } , ${ a5 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
628
- case 6 : glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 , a6 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 , a5 , a6 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } , ${ a5 } , ${ a6 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
629
- case 7 : glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } , ${ a5 } , ${ a6 } , ${ a7 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
630
- case 8 : glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } (${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } , ${ a5 } , ${ a6 } , ${ a7 } , ${ a8 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
631
- case 9 : glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } , ${ a5 } , ${ a6 } , ${ a7 } , ${ a8 } , ${ a9 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
632
- case 10 : glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } (${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } , ${ a5 } , ${ a6 } , ${ a7 } , ${ a8 } , ${ a9 } , ${ a10 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
633
- case 11 : glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 ) => { var ret = glCtx [ realf ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 ) ; err ( `[Thread ${ threadId ( ) } , GL ctx: ${ contextHandle } ]: ${ f } ( ${ a1 } , ${ a2 } , ${ a3 } , ${ a4 } , ${ a5 } , ${ a6 } , ${ a7 } , ${ a8 } , ${ a9 } , ${ a10 } , ${ a11 } ) -> ${ ret } ` ) ; return ret ; } ; break ;
634
- default : console . warn ( 'hookWebGL failed! Unexpected length ' + glCtx [ realf ] . length ) ;
635
- }
616
+ glCtx [ f ] = function ( ... args ) {
617
+ var ret = orig . apply ( this , args ) ;
618
+ // Some GL functions take a view of the entire linear memory. Replace
619
+ // such arguments with the string 'HEAP' to avoid serializing all of
620
+ // memory.
621
+ for ( var i in args ) {
622
+ if ( ArrayBuffer . isView ( args [ i ] ) && args [ i ] . byteLength === HEAPU8 . byteLength ) {
623
+ args [ i ] = 'HEAP' ;
624
+ }
625
+ }
626
+ #if PTHREADS
627
+ err ( `[Thread ${ _pthread_self ( ) } , GL ctx: ${ contextHandle } ]: ${ f } (${ args } ) -> ${ ret } ` ) ;
628
+ #else
629
+ err ( `[ctx: ${ contextHandle } ]: ${ f } (${ args } ) -> ${ ret } ` ) ;
630
+ #endif
631
+ return ret ;
632
+ } ;
636
633
} ,
637
634
638
635
hookWebGL : function ( glCtx ) {
639
636
if ( ! glCtx ) glCtx = this . detectWebGLContext ( ) ;
640
637
if ( ! glCtx ) return ;
641
638
if ( ! ( ( typeof WebGLRenderingContext != 'undefined' && glCtx instanceof WebGLRenderingContext )
642
- || ( typeof WebGL2RenderingContext != 'undefined' && glCtx instanceof WebGL2RenderingContext ) ) ) {
639
+ || ( typeof WebGL2RenderingContext != 'undefined' && glCtx instanceof WebGL2RenderingContext ) ) ) {
643
640
return ;
644
641
}
645
642
646
643
if ( glCtx . webGlTracerAlreadyHooked ) return ;
647
644
glCtx . webGlTracerAlreadyHooked = true ;
648
645
649
- // Hot GL functions are ones that you'd expect to find during render loops
650
- // (render calls, dynamic resource uploads), cold GL functions are load
651
- // time functions (shader compilation, texture/mesh creation).
652
- // Distinguishing between these two allows pinpointing locations of
653
- // troublesome GL usage that might cause performance issues.
654
646
for ( var f in glCtx ) {
655
- if ( typeof glCtx [ f ] != 'function' || f . startsWith ( 'real_' ) ) continue ;
656
- this . hookWebGLFunction ( f , glCtx ) ;
647
+ if ( typeof glCtx [ f ] == 'function' ) {
648
+ this . hookWebGLFunction ( f , glCtx ) ;
649
+ }
657
650
}
658
- // The above injection won't work for texImage2D and texSubImage2D, which
659
- // have multiple overloads.
660
- glCtx [ 'texImage2D' ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) => {
661
- var ret = ( a7 !== undefined ) ? glCtx [ 'real_texImage2D' ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) : glCtx [ 'real_texImage2D' ] ( a1 , a2 , a3 , a4 , a5 , a6 ) ;
662
- return ret ;
663
- } ;
664
- glCtx [ 'texSubImage2D' ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) => {
665
- var ret = ( a8 !== undefined ) ? glCtx [ 'real_texSubImage2D' ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) : glCtx [ 'real_texSubImage2D' ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 ) ;
666
- return ret ;
667
- } ;
668
- glCtx [ 'texSubImage3D' ] = ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 ) => {
669
- var ret = ( a9 !== undefined ) ? glCtx [ 'real_texSubImage3D' ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 ) : glCtx [ 'real_texSubImage2D' ] ( a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ) ;
670
- return ret ;
671
- } ;
672
- glCtx [ 'bufferData' ] = ( a1 , a2 , a3 , a4 , a5 ) => {
673
- // WebGL1/2 versions have different parameters (not just extra ones)
674
- var ret = ( a4 !== undefined ) ? glCtx [ 'real_bufferData' ] ( a1 , a2 , a3 , a4 , a5 ) : glCtx [ 'real_bufferData' ] ( a1 , a2 , a3 ) ;
675
- return ret ;
676
- } ;
677
- const matrixFuncs = [ 'uniformMatrix2fv' , 'uniformMatrix3fv' , 'uniformMatrix4fv' ] ;
678
- matrixFuncs . forEach ( f => {
679
- glCtx [ f ] = ( a1 , a2 , a3 , a4 , a5 ) => {
680
- // WebGL2 version has 2 extra optional parameters, ensure we forward them
681
- return glCtx [ 'real_' + f ] ( a1 , a2 , a3 , a4 , a5 ) ;
682
- }
683
- } ) ;
684
651
} ,
685
652
#endif
686
653
// Returns the context handle to the new context.
0 commit comments