📄 webgl-debug-helper.js
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 13 |
📊 Variables & Constants | 27 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 manual/examples/resources/webgl-debug-helper.js
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
mappedContextTypes |
{} |
let/var | {} |
✗ |
glEnums |
any |
let/var | {} |
✗ |
enumStringToValue |
any |
let/var | {} |
✗ |
enumStrings |
any[] |
let/var | [] |
✗ |
orResult |
number |
let/var | 0 |
✗ |
orEnums |
any[] |
let/var | [] |
✗ |
enumValue |
any |
let/var | enumStringToValue[ enums[ i ] ] |
✗ |
glValidEnumContexts |
{ [x: number]: Function \| { [x: numb... |
let/var | { // Generic setters and getters 'enable': { 1: { 0: true } }, 'disable': { 1... |
✗ |
name |
any |
let/var | glEnums[ value ] |
✗ |
funcInfos |
any |
let/var | glValidEnumContexts[ functionName ] |
✗ |
funcInfo |
any |
let/var | funcInfos[ numArgs ] |
✗ |
argType |
any |
let/var | funcInfo[ argumentIndex ] |
✗ |
argStrs |
any[] |
let/var | [] |
✗ |
numArgs |
any |
let/var | args.length |
✗ |
errCtx |
any |
let/var | options.errCtx \|\| ctx |
✗ |
onFunc |
any |
let/var | options.funcFunc |
✗ |
sharedState |
any |
let/var | options.sharedState \|\| { numDrawCallsRemaining: options.maxDrawCalls \|\| -... |
✗ |
errorFunc |
any |
let/var | options.errorFunc \|\| function ( err, functionName, args ) { console.error( ... |
✗ |
glErrorShadow |
{} |
let/var | { } |
✗ |
wrapper |
{ getError(): string \| 0; } |
let/var | {} |
✗ |
pair |
any |
let/var | sharedState.wrappers[ name ] |
✗ |
wrapper |
any |
let/var | pair.wrapper |
✗ |
orig |
any |
let/var | pair.orig |
✗ |
check |
() => void |
let/var | functionName.substring( 0, 4 ) === 'draw' ? checkMaxDrawCalls : noop |
✗ |
extensionName |
any |
let/var | arguments[ 0 ] |
✗ |
ext |
any |
let/var | sharedState.wrappers[ extensionName ] |
✗ |
origExt |
any |
let/var | ext |
✗ |
Functions¶
addEnumsForContext(ctx: WebGLRenderingContext, type: any): void
¶
JSDoc:
/**
* Initializes this module. Safe to call more than once.
* @param {!WebGLRenderingContext} ctx A WebGL context. If
* you have more than one context it doesn't matter which one
* you pass in, it is only used to pull out constants.
*/
Parameters:
ctx
WebGLRenderingContext
type
any
Returns: void
Code
function addEnumsForContext( ctx, type ) {
if ( ! mappedContextTypes[ type ] ) {
mappedContextTypes[ type ] = true;
for ( const propertyName in ctx ) {
if ( typeof ctx[ propertyName ] === 'number' ) {
glEnums[ ctx[ propertyName ] ] = propertyName;
enumStringToValue[ propertyName ] = ctx[ propertyName ];
}
}
}
}
enumArrayToString(enums: any): string
¶
Parameters:
enums
any
Returns: string
Calls:
enums.push
glEnumToString
enumStrings.join
enumStrings.toString
Code
makeBitFieldToStringFunc(enums: any): (value: any) => string
¶
Parameters:
enums
any
Returns: (value: any) => string
Calls:
orEnums.push
glEnumToString
orEnums.join
Code
function makeBitFieldToStringFunc( enums ) {
return function ( value ) {
let orResult = 0;
const orEnums = [];
for ( let i = 0; i < enums.length; ++ i ) {
const enumValue = enumStringToValue[ enums[ i ] ];
if ( ( value & enumValue ) !== 0 ) {
orResult |= enumValue;
orEnums.push(glEnumToString(enumValue)); // eslint-disable-line
}
}
if ( orResult === value ) {
return orEnums.join( ' | ' );
} else {
return glEnumToString(value); // eslint-disable-line
}
};
}
glEnumToString(value: number): string
¶
JSDoc:
/**
* Gets an string version of an WebGL enum.
*
* Example:
* var str = WebGLDebugUtil.glEnumToString(ctx.getError());
*
* @param {number} value Value to return an enum for
* @return {string} The string version of the enum.
*/
Parameters:
value
number
Returns: string
Calls:
value.toString
Code
glFunctionArgToString(functionName: string, numArgs: number, argumentIndex: any, value: any): string
¶
JSDoc:
/**
* Returns the string version of a WebGL argument.
* Attempts to convert enum arguments to strings.
* @param {string} functionName the name of the WebGL function.
* @param {number} numArgs the number of arguments passed to the function.
* @param {number} argumentIndx the index of the argument.
* @param {*} value The value of the argument.
* @return {string} The value as a string.
*/
Parameters:
functionName
string
numArgs
number
argumentIndex
any
value
any
Returns: string
Calls:
argType
glEnumToString
value.toString
Code
function glFunctionArgToString( functionName, numArgs, argumentIndex, value ) {
const funcInfos = glValidEnumContexts[ functionName ];
if ( funcInfos !== undefined ) {
const funcInfo = funcInfos[ numArgs ];
if ( funcInfo !== undefined ) {
const argType = funcInfo[ argumentIndex ];
if ( argType ) {
if ( typeof argType === 'function' ) {
return argType( value );
} else {
return glEnumToString( value );
}
}
}
}
if ( value === null ) {
return 'null';
} else if ( value === undefined ) {
return 'undefined';
} else {
return value.toString();
}
}
glFunctionArgsToString(functionName: string, args: number): string
¶
JSDoc:
/**
* Converts the arguments of a WebGL function to a string.
* Attempts to convert enum arguments to strings.
*
* @param {string} functionName the name of the WebGL function.
* @param {number} args The arguments.
* @return {string} The arguments as a string.
*/
Parameters:
functionName
string
args
number
Returns: string
Calls:
argStrs.push
glFunctionArgToString
argStrs.join
Internal Comments:
Code
function glFunctionArgsToString( functionName, args ) {
// apparently we can't do args.join(",");
const argStrs = [];
const numArgs = args.length;
for ( let ii = 0; ii < numArgs; ++ ii ) {
argStrs.push( glFunctionArgToString( functionName, numArgs, ii, args[ ii ] ) );
}
return argStrs.join( ', ' );
}
makePropertyWrapper(wrapper: any, original: any, propertyName: any): void
¶
Parameters:
wrapper
any
original
any
propertyName
any
Returns: void
Calls:
wrapper.__defineGetter__
wrapper.__defineSetter__
Internal Comments:
Code
function makePropertyWrapper( wrapper, original, propertyName ) {
wrapper.__defineGetter__(propertyName, function() { // eslint-disable-line
return original[ propertyName ];
} );
// TODO(gmane): this needs to handle properties that take more than
// one value?
wrapper.__defineSetter__(propertyName, function(value) { // eslint-disable-line
original[ propertyName ] = value;
} );
}
makeDebugContext(ctx: WebGLRenderingContext, options: any): { getError(): string | 0; }
¶
JSDoc:
/**
* Given a WebGL context returns a wrapped context that calls
* gl.getError after every command and calls a function if the
* result is not gl.NO_ERROR.
*
* @param {!WebGLRenderingContext} ctx The webgl context to
* wrap.
* @param {!function(err, funcName, args): void} opt_onErrorFunc
* The function to call when gl.getError returns an
* error. If not specified the default function calls
* console.log with a message.
* @param {!function(funcName, args): void} opt_onFunc The
* function to call when each webgl function is called.
* You can use this to log all calls for example.
* @param {!WebGLRenderingContext} opt_err_ctx The webgl context
* to call getError on if different than ctx.
*/
Parameters:
ctx
WebGLRenderingContext
options
any
Returns: { getError(): string | 0; }
Calls:
console.error
glEnumToString
glFunctionArgsToString
Object.keys( sharedState.wrappers ).forEach
orig[ propertyName ].bind
removeChecks
functionName.substring
onFunc
ctx[ functionName ].apply
errCtx.getError
errorFunc
check
wrapped.apply
makeDebugContext
addEnumsForContext
makeErrorWrapper
makeGetExtensionWrapper
makePropertyWrapper
Object.keys
Internal Comments:
// Holds booleans for each GL error so after we get the error ourselves (x2)
// we can still return it to the client app. (x2)
// Makes a function that calls a WebGL function and then calls getError.
// Make an object that has a copy of every property of the WebGL context
// but wraps all functions.
// Override the getError function with one that returns our saved results.
Code
function makeDebugContext( ctx, options ) {
options = options || {};
const errCtx = options.errCtx || ctx;
const onFunc = options.funcFunc;
const sharedState = options.sharedState || {
numDrawCallsRemaining: options.maxDrawCalls || - 1,
wrappers: {},
};
options.sharedState = sharedState;
const errorFunc = options.errorFunc || function ( err, functionName, args ) {
console.error( `WebGL error ${glEnumToString( err )} in ${functionName}(${glFunctionArgsToString( functionName, args )})` ); /* eslint-disable-line no-console */
};
// Holds booleans for each GL error so after we get the error ourselves
// we can still return it to the client app.
const glErrorShadow = { };
const wrapper = {};
function removeChecks() {
Object.keys( sharedState.wrappers ).forEach( function ( name ) {
const pair = sharedState.wrappers[ name ];
const wrapper = pair.wrapper;
const orig = pair.orig;
for ( const propertyName in wrapper ) {
if ( typeof wrapper[ propertyName ] === 'function' ) {
wrapper[ propertyName ] = orig[ propertyName ].bind( orig );
}
}
} );
}
function checkMaxDrawCalls() {
if ( sharedState.numDrawCallsRemaining === 0 ) {
removeChecks();
}
-- sharedState.numDrawCallsRemaining;
}
function noop() {
}
// Makes a function that calls a WebGL function and then calls getError.
function makeErrorWrapper( ctx, functionName ) {
const check = functionName.substring( 0, 4 ) === 'draw' ? checkMaxDrawCalls : noop;
return function () {
if ( onFunc ) {
onFunc( functionName, arguments );
}
const result = ctx[ functionName ].apply( ctx, arguments );
const err = errCtx.getError();
if ( err !== 0 ) {
glErrorShadow[ err ] = true;
errorFunc( err, functionName, arguments );
}
check();
return result;
};
}
function makeGetExtensionWrapper( ctx, wrapped ) {
return function () {
const extensionName = arguments[ 0 ];
let ext = sharedState.wrappers[ extensionName ];
if ( ! ext ) {
ext = wrapped.apply( ctx, arguments );
if ( ext ) {
const origExt = ext;
ext = makeDebugContext( ext, { ...options, errCtx: ctx } );
sharedState.wrappers[ extensionName ] = { wrapper: ext, orig: origExt };
addEnumsForContext( origExt, extensionName );
}
}
return ext;
};
}
// Make an object that has a copy of every property of the WebGL context
// but wraps all functions.
for ( const propertyName in ctx ) {
if ( typeof ctx[ propertyName ] === 'function' ) {
if ( propertyName !== 'getExtension' ) {
wrapper[ propertyName ] = makeErrorWrapper( ctx, propertyName );
} else {
const wrapped = makeErrorWrapper( ctx, propertyName );
wrapper[ propertyName ] = makeGetExtensionWrapper( ctx, wrapped );
}
} else {
makePropertyWrapper( wrapper, ctx, propertyName );
}
}
// Override the getError function with one that returns our saved results.
if ( wrapper.getError ) {
wrapper.getError = function () {
for ( const err of Object.keys( glErrorShadow ) ) {
if ( glErrorShadow[ err ] ) {
glErrorShadow[ err ] = false;
return err;
}
}
return ctx.NO_ERROR;
};
}
if ( wrapper.bindBuffer ) {
sharedState.wrappers[ 'webgl' ] = { wrapper: wrapper, orig: ctx };
addEnumsForContext( ctx, ctx.bindBufferBase ? 'WebGL2' : 'WebGL' );
}
return wrapper;
}
removeChecks(): void
¶
Returns: void
Calls:
Object.keys( sharedState.wrappers ).forEach
orig[ propertyName ].bind
Code
function removeChecks() {
Object.keys( sharedState.wrappers ).forEach( function ( name ) {
const pair = sharedState.wrappers[ name ];
const wrapper = pair.wrapper;
const orig = pair.orig;
for ( const propertyName in wrapper ) {
if ( typeof wrapper[ propertyName ] === 'function' ) {
wrapper[ propertyName ] = orig[ propertyName ].bind( orig );
}
}
} );
}
checkMaxDrawCalls(): void
¶
Returns: void
Calls:
removeChecks
Code
noop(): void
¶
Returns: void
makeErrorWrapper(ctx: any, functionName: any): (...args: any[]) => any
¶
Parameters:
ctx
any
functionName
any
Returns: (...args: any[]) => any
Calls:
functionName.substring
onFunc
ctx[ functionName ].apply
errCtx.getError
errorFunc
check
Code
function makeErrorWrapper( ctx, functionName ) {
const check = functionName.substring( 0, 4 ) === 'draw' ? checkMaxDrawCalls : noop;
return function () {
if ( onFunc ) {
onFunc( functionName, arguments );
}
const result = ctx[ functionName ].apply( ctx, arguments );
const err = errCtx.getError();
if ( err !== 0 ) {
glErrorShadow[ err ] = true;
errorFunc( err, functionName, arguments );
}
check();
return result;
};
}
makeGetExtensionWrapper(ctx: any, wrapped: any): (...args: any[]) => any
¶
Parameters:
ctx
any
wrapped
any
Returns: (...args: any[]) => any
Calls:
wrapped.apply
makeDebugContext
addEnumsForContext
Code
function makeGetExtensionWrapper( ctx, wrapped ) {
return function () {
const extensionName = arguments[ 0 ];
let ext = sharedState.wrappers[ extensionName ];
if ( ! ext ) {
ext = wrapped.apply( ctx, arguments );
if ( ext ) {
const origExt = ext;
ext = makeDebugContext( ext, { ...options, errCtx: ctx } );
sharedState.wrappers[ extensionName ] = { wrapper: ext, orig: origExt };
addEnumsForContext( origExt, extensionName );
}
}
return ext;
};
}