UNPKG

3.37 kBPlain TextView Raw
1import GLErrors from './GLErrors';
2import { ExpoWebGLRenderingContext, GLLoggingOption } from './GLView.types';
3
4/**
5 * Maximum length of the strings printed to the console.
6 */
7const MAX_STRING_LENGTH = 20;
8
9/**
10 * Sets up `__expoSetLogging` method providing some logging options useful when debugging GL calls.
11 */
12export function configureLogging(gl: ExpoWebGLRenderingContext): void {
13 // Enable/disable logging of all GL function calls
14 let loggingOption = GLLoggingOption.DISABLED;
15
16 gl.__expoSetLogging = (option: GLLoggingOption): void => {
17 // If boolean values are the same, just change the internal value,
18 // there is no need to wrap/unwrap functions in this case.
19 if (!loggingOption === !option) {
20 loggingOption = option;
21 return;
22 }
23
24 // Turn off logging.
25 if (!option || option === GLLoggingOption.DISABLED) {
26 Object.entries(gl).forEach(([key, value]) => {
27 if (typeof value === 'function' && value.original) {
28 gl[key] = value.original;
29 }
30 });
31 loggingOption = option;
32 return;
33 }
34
35 // Turn on logging.
36 Object.entries(gl).forEach(([key, originalValue]) => {
37 if (typeof originalValue !== 'function' || key === '__expoSetLogging') {
38 return;
39 }
40
41 gl[key] = (...args) => {
42 if (loggingOption & GLLoggingOption.METHOD_CALLS) {
43 const params = args.map(arg => {
44 // If the type is `number`, then try to find name of the constant that has such value,
45 // so it's easier to read these logs. In some cases it might be misleading
46 // if the parameter is for example a width or height, so the number is still logged.
47 if (loggingOption & GLLoggingOption.RESOLVE_CONSTANTS && typeof arg === 'number') {
48 for (const prop in gl) {
49 if (gl[prop] === arg) {
50 return `${arg} (${prop})`;
51 }
52 }
53 }
54
55 // Truncate strings so they don't produce too much output and don't block the bridge.
56 // It mostly applies to shaders which might be very long...
57 if (loggingOption & GLLoggingOption.TRUNCATE_STRINGS && typeof arg === 'string') {
58 if (arg.length > MAX_STRING_LENGTH) {
59 const lastIndex = arg.lastIndexOf(' ', MAX_STRING_LENGTH);
60 return arg.substr(0, lastIndex >= 0 ? lastIndex : MAX_STRING_LENGTH) + '...';
61 }
62 }
63
64 // Just return the parameter as a string.
65 return '' + arg;
66 });
67 console.log(`ExpoGL: ${key}(${params.join(', ')})`);
68 }
69
70 const result = originalValue.apply(gl, args);
71
72 if (loggingOption & GLLoggingOption.METHOD_CALLS) {
73 console.log(`ExpoGL: = ${result}`);
74 }
75 if (loggingOption & GLLoggingOption.GET_ERRORS && key !== 'getError') {
76 // @ts-ignore We need to call into the original `getError`.
77 const error = gl.getError.original.call(gl);
78
79 if (error && error !== gl.NO_ERROR) {
80 // `console.error` would cause a red screen, so let's just log with red color.
81 console.log(`\x1b[31mExpoGL: Error ${GLErrors[error]}\x1b[0m`);
82 }
83 }
84 return result;
85 };
86 gl[key].original = originalValue;
87 });
88
89 loggingOption = option;
90 };
91}