@@ -611,76 +611,43 @@ for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
611611
612612#if TRACE_WEBGL_CALLS
613613 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 ] ;
618615 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+ } ;
636633 } ,
637634
638635 hookWebGL : function ( glCtx ) {
639636 if ( ! glCtx ) glCtx = this . detectWebGLContext ( ) ;
640637 if ( ! glCtx ) return ;
641638 if ( ! ( ( typeof WebGLRenderingContext != 'undefined' && glCtx instanceof WebGLRenderingContext )
642- || ( typeof WebGL2RenderingContext != 'undefined' && glCtx instanceof WebGL2RenderingContext ) ) ) {
639+ || ( typeof WebGL2RenderingContext != 'undefined' && glCtx instanceof WebGL2RenderingContext ) ) ) {
643640 return ;
644641 }
645642
646643 if ( glCtx . webGlTracerAlreadyHooked ) return ;
647644 glCtx . webGlTracerAlreadyHooked = true ;
648645
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.
654646 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+ }
657650 }
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- } ) ;
684651 } ,
685652#endif
686653 // Returns the context handle to the new context.
0 commit comments