dcp-client 4.2.6 → 4.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dcp-client-bundle.js +46 -47
- package/generated/sandbox-definitions.json +1 -1
- package/index.js +34 -15
- package/libexec/evaluator-node.js +1 -1
- package/libexec/sandbox/access-lists.js +2 -14
- package/libexec/sandbox/bootstrap.js +5 -4
- package/libexec/sandbox/bravojs-env.js +7 -12
- package/libexec/sandbox/calculate-capabilities.js +1 -36
- package/libexec/sandbox/event-loop-virtualization.js +26 -6
- package/libexec/sandbox/gpu-timers.js +68 -0
- package/libexec/sandbox/sa-ww-simulation.js +2 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"browser":["deny-node","kvin/kvin.js","script-load-wrapper","wrap-event-listeners","event-loop-virtualization","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap"],"node":["kvin/kvin.js","sa-ww-simulation","script-load-wrapper","wrap-event-listeners","event-loop-virtualization","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap"],"native":["deny-node","kvin/kvin.js","sa-ww-simulation","script-load-wrapper","native-event-loop","wrap-event-listeners","event-loop-virtualization","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap"],"webGpuNative":["deny-node","kvin/kvin.js","
|
|
1
|
+
{"browser":["deny-node","kvin/kvin.js","script-load-wrapper","wrap-event-listeners","event-loop-virtualization","gpu-timers","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap"],"node":["kvin/kvin.js","sa-ww-simulation","script-load-wrapper","wrap-event-listeners","event-loop-virtualization","gpu-timers","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap"],"native":["deny-node","kvin/kvin.js","sa-ww-simulation","script-load-wrapper","native-event-loop","wrap-event-listeners","event-loop-virtualization","webgpu-worker-environment","gpu-timers","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap"],"webGpuNative":["deny-node","kvin/kvin.js","bootstrap"],"nodeTesting":["kvin/kvin.js","sa-ww-simulation","script-load-wrapper","wrap-event-listeners","event-loop-virtualization","gpu-timers","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap","testing.js"],"testing":["deny-node","kvin/kvin.js","sa-ww-simulation","script-load-wrapper","native-event-loop","wrap-event-listeners","event-loop-virtualization","webgpu-worker-environment","gpu-timers","access-lists","bravojs-init","bravojs/bravo.js","bravojs-env","calculate-capabilities","bootstrap","testing.js"]}
|
package/index.js
CHANGED
|
@@ -32,10 +32,11 @@ const process = require('process');
|
|
|
32
32
|
const kvin = require('kvin');
|
|
33
33
|
const moduleSystem = require('module');
|
|
34
34
|
const { spawnSync } = require('child_process');
|
|
35
|
-
const
|
|
35
|
+
const vm = require('vm');
|
|
36
36
|
|
|
37
37
|
exports.debug = false;
|
|
38
38
|
let initInvoked = false; /* flag to help us detect use of Compute API before init */
|
|
39
|
+
let hadOriginalDcpConfig = globalThis.hasOwnProperty('dcpConfig'); /* flag to determine if the user set their own dcpConfig global variable before init */
|
|
39
40
|
|
|
40
41
|
function debugging(what = 'dcp-client') {
|
|
41
42
|
const debugSyms = []
|
|
@@ -107,6 +108,30 @@ const bundleSandbox = {
|
|
|
107
108
|
},
|
|
108
109
|
};
|
|
109
110
|
|
|
111
|
+
function runSandboxedCode(sandbox, code, options)
|
|
112
|
+
{
|
|
113
|
+
if (process.env.DCP_CLIENT_LEGACY_CONTEXT_SANDBOXING)
|
|
114
|
+
{
|
|
115
|
+
const script = new vm.Script(code, options);
|
|
116
|
+
return script.runInNewContext(vm.createContext(sandbox), options);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (typeof runSandboxedCode.extraGlobalProps === 'undefined')
|
|
120
|
+
runSandboxedCode.extraGlobalProps = {};
|
|
121
|
+
|
|
122
|
+
for (let prop in sandbox)
|
|
123
|
+
{
|
|
124
|
+
if (!globalThis.hasOwnProperty(prop) || runSandboxedCode.extraGlobalProps.hasOwnProperty(prop))
|
|
125
|
+
{
|
|
126
|
+
globalThis[prop] = sandbox[prop];
|
|
127
|
+
runSandboxedCode.extraGlobalProps[prop] = true; /* Memoize global prop list mutation to allow re-mutation */
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const script = new vm.Script(code, options);
|
|
132
|
+
return script.runInThisContext(options);
|
|
133
|
+
}
|
|
134
|
+
|
|
110
135
|
/** Evaluate a file in a sandbox without polluting the global object.
|
|
111
136
|
* @param filename {string} The name of the file to evaluate, relative to
|
|
112
137
|
* @param sandbox {object} A sandbox object, used for injecting 'global' symbols as needed
|
|
@@ -114,7 +139,6 @@ const bundleSandbox = {
|
|
|
114
139
|
*/
|
|
115
140
|
function evalScriptInSandbox(filename, sandbox, olFlag) {
|
|
116
141
|
var code
|
|
117
|
-
var context = createContext(sandbox)
|
|
118
142
|
try {
|
|
119
143
|
code = fs.readFileSync(path.resolve(distDir, filename), 'utf-8')
|
|
120
144
|
if (olFlag)
|
|
@@ -126,7 +150,8 @@ function evalScriptInSandbox(filename, sandbox, olFlag) {
|
|
|
126
150
|
throw e
|
|
127
151
|
}
|
|
128
152
|
|
|
129
|
-
|
|
153
|
+
|
|
154
|
+
return runSandboxedCode(sandbox, code, { filename, lineNumber: 0 });
|
|
130
155
|
}
|
|
131
156
|
|
|
132
157
|
/** Evaluate code in a secure sandbox; in this case, the code is the configuration
|
|
@@ -134,18 +159,12 @@ function evalScriptInSandbox(filename, sandbox, olFlag) {
|
|
|
134
159
|
* during config file processing.
|
|
135
160
|
*
|
|
136
161
|
* @param code {string} The code to eval
|
|
137
|
-
* @param
|
|
138
|
-
* that will act like the context's global object
|
|
162
|
+
* @param sandbox {object} A sandbox object, used for injecting 'global' symbols as needed
|
|
139
163
|
* @param filename {string} The name of the file we're evaluating for stack-
|
|
140
164
|
* trace purposes.
|
|
141
165
|
*/
|
|
142
|
-
function evalStringInSandbox(
|
|
143
|
-
|
|
144
|
-
sandbox,
|
|
145
|
-
filename = '(dcp-client$$evalStringInSandbox)',
|
|
146
|
-
) {
|
|
147
|
-
const context = createContext(sandbox);
|
|
148
|
-
|
|
166
|
+
function evalStringInSandbox(code, sandbox, filename = '(dcp-client$$evalStringInSandbox)')
|
|
167
|
+
{
|
|
149
168
|
/**
|
|
150
169
|
* Remove comments and then decide if this config file contains an IIFE. If
|
|
151
170
|
* not, we need to wrap it as an IIFE to avoid "SyntaxError: Illegal return
|
|
@@ -167,7 +186,7 @@ function evalStringInSandbox(
|
|
|
167
186
|
* printed.
|
|
168
187
|
*/
|
|
169
188
|
try {
|
|
170
|
-
result =
|
|
189
|
+
result = runSandboxedCode(sandbox, code, {
|
|
171
190
|
filename,
|
|
172
191
|
lineOffset,
|
|
173
192
|
/**
|
|
@@ -301,7 +320,7 @@ function addConfig (existing, neo) {
|
|
|
301
320
|
existing[prop] = new (existing[prop].constructor)(neo[prop]);
|
|
302
321
|
continue;
|
|
303
322
|
}
|
|
304
|
-
if (typeof neo[prop] === 'object' && !Array.isArray(neo[prop]) && ['Function','Object'].includes(neo[prop].constructor.name)) {
|
|
323
|
+
if (typeof neo[prop] === 'object' && neo[prop] !== null && !Array.isArray(neo[prop]) && ['Function','Object'].includes(neo[prop].constructor.name)) {
|
|
305
324
|
if (typeof existing[prop] === 'undefined') {
|
|
306
325
|
existing[prop] = {}
|
|
307
326
|
}
|
|
@@ -575,7 +594,7 @@ function initTail(aggrConfig, finalBundleCode, finalBundleURL) {
|
|
|
575
594
|
require('dcp/dcp-url').patchup(aggrConfig);
|
|
576
595
|
|
|
577
596
|
/* 3 */
|
|
578
|
-
if (
|
|
597
|
+
if (hadOriginalDcpConfig) {
|
|
579
598
|
/* dcpConfig was defined before dcp-client was initialized: assume dev knows what he/she is doing */
|
|
580
599
|
debugging() && console.debug('Dropping bundle dcp-config in favour of global dcpConfig')
|
|
581
600
|
Object.assign(require('dcp/dcp-config'), global.dcpConfig);
|
|
@@ -66,7 +66,7 @@ exports.Evaluator = function Evaluator(inputStream, outputStream, files) {
|
|
|
66
66
|
/* Add properties to sandbox global scope */
|
|
67
67
|
Object.assign(this.sandboxGlobal, {
|
|
68
68
|
self: this.sandboxGlobal,
|
|
69
|
-
die: (
|
|
69
|
+
die: () => { this.destroy(); },
|
|
70
70
|
writeln: (string) => { this.writeln(string) },
|
|
71
71
|
onreadln: (handler) => { this.onreadlnHandler = handler },
|
|
72
72
|
setTimeout,
|
|
@@ -23,6 +23,8 @@ self.wrapScriptLoading({ scriptName: 'access-lists', ringTransition: true }, fun
|
|
|
23
23
|
'AsyncFunction',
|
|
24
24
|
'Atomics',
|
|
25
25
|
'BigInt',
|
|
26
|
+
'BigInt64Array',
|
|
27
|
+
'BigUint64Array',
|
|
26
28
|
'Boolean',
|
|
27
29
|
'Blob',
|
|
28
30
|
'bravojs',
|
|
@@ -45,7 +47,6 @@ self.wrapScriptLoading({ scriptName: 'access-lists', ringTransition: true }, fun
|
|
|
45
47
|
'Float32Array',
|
|
46
48
|
'Float64Array',
|
|
47
49
|
'Function',
|
|
48
|
-
'getWebGLTimer',
|
|
49
50
|
'Headers',
|
|
50
51
|
'Infinity',
|
|
51
52
|
'Int16Array',
|
|
@@ -108,7 +109,6 @@ self.wrapScriptLoading({ scriptName: 'access-lists', ringTransition: true }, fun
|
|
|
108
109
|
'WeakSet',
|
|
109
110
|
'WebAssembly',
|
|
110
111
|
'WebGL2RenderingContext',
|
|
111
|
-
'webGLOffset',
|
|
112
112
|
'WebGLTexture',
|
|
113
113
|
'WorkerGlobalScope',
|
|
114
114
|
// Our own Webgpu symbols
|
|
@@ -123,18 +123,6 @@ self.wrapScriptLoading({ scriptName: 'access-lists', ringTransition: true }, fun
|
|
|
123
123
|
'flushLastLog'
|
|
124
124
|
]);
|
|
125
125
|
|
|
126
|
-
// webGL timer getter to be overwritten in calculate-capabilities
|
|
127
|
-
self.getWebGLTimer = (function monkeypatchWebGL() {
|
|
128
|
-
let timer = 0;
|
|
129
|
-
function getTimer() {
|
|
130
|
-
return timer;
|
|
131
|
-
}
|
|
132
|
-
return getTimer;
|
|
133
|
-
})();
|
|
134
|
-
|
|
135
|
-
// Offset time for webGL when sandbox is re-used
|
|
136
|
-
self.webGLOffset = 0;
|
|
137
|
-
|
|
138
126
|
// Origin time for performance polyfill
|
|
139
127
|
const pt0 = new Date().getTime();
|
|
140
128
|
|
|
@@ -131,15 +131,16 @@ self.wrapScriptLoading({ scriptName: 'bootstrap', finalScript: true }, function
|
|
|
131
131
|
return true;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
function workerBootstrap$work$emit(
|
|
135
|
-
if (typeof
|
|
136
|
-
throw new Error(`Event name passed to work.emit must be a string, not ${
|
|
134
|
+
function workerBootstrap$work$emit(customEvent, value) {
|
|
135
|
+
if (typeof customEvent !== 'string') {
|
|
136
|
+
throw new Error(`Event name passed to work.emit must be a string, not ${customEvent}.`);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
postMessage({
|
|
140
140
|
request: 'emitEvent',
|
|
141
141
|
payload: {
|
|
142
|
-
eventName,
|
|
142
|
+
eventName: 'custom',
|
|
143
|
+
customEvent,
|
|
143
144
|
data: value,
|
|
144
145
|
},
|
|
145
146
|
});
|
|
@@ -184,12 +184,9 @@ self.wrapScriptLoading({ scriptName: 'bravojs-env', ringTransition: true }, func
|
|
|
184
184
|
function reportRejectedGPUandTotal (t0) {
|
|
185
185
|
try
|
|
186
186
|
{
|
|
187
|
-
const webGLTimer = getWebGLTimer;
|
|
188
|
-
const offset = webGLOffset;
|
|
189
187
|
const total = performance.now() - t0;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
self.webGLOffset = offset + webGL;
|
|
188
|
+
const webGL = protectedStorage.getAndResetWebGLTimer();
|
|
189
|
+
protectedStorage.subtractWebGLTimeFromCPUTime(webGL);
|
|
193
190
|
ring3PostMessage({ request: 'measurement', total, webGL });
|
|
194
191
|
}
|
|
195
192
|
catch (error)
|
|
@@ -232,12 +229,9 @@ self.wrapScriptLoading({ scriptName: 'bravojs-env', ringTransition: true }, func
|
|
|
232
229
|
{
|
|
233
230
|
try
|
|
234
231
|
{
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
let webGL = webGLTimer() - offset;
|
|
240
|
-
self.webGLOffset = offset + webGL;
|
|
232
|
+
const total = performance.now() - t0 + 1; /* +1 to ensure we never have "0 second slices" */
|
|
233
|
+
const webGL = protectedStorage.getAndResetWebGLTimer();
|
|
234
|
+
protectedStorage.subtractWebGLTimeFromCPUTime(webGL); /* Because webGL is sync but doesn't use CPU */
|
|
241
235
|
ring3PostMessage({ request: 'measurement', total, webGL });
|
|
242
236
|
ring3PostMessage({ request: 'complete', result });
|
|
243
237
|
}
|
|
@@ -277,6 +271,7 @@ self.wrapScriptLoading({ scriptName: 'bravojs-env', ringTransition: true }, func
|
|
|
277
271
|
*/
|
|
278
272
|
try { await tryFlushMicroTaskQueue(); } catch(e) {};
|
|
279
273
|
try { flushLastLog(); } catch(e) {};
|
|
274
|
+
try { protectedStorage.markCPUTimeAsDone(); } catch(e) {};
|
|
280
275
|
|
|
281
276
|
if (rejection)
|
|
282
277
|
errorCallback(rejection);
|
|
@@ -301,6 +296,6 @@ self.wrapScriptLoading({ scriptName: 'bravojs-env', ringTransition: true }, func
|
|
|
301
296
|
* 1. shorten stack
|
|
302
297
|
* 2. initialize the event loop measurement code
|
|
303
298
|
*/
|
|
304
|
-
setTimeout(() => runWorkFunction_inner(datum, (result) => reportResult(t0, result), (rejection) => reportError(t0, rejection)));
|
|
299
|
+
protectedStorage.setTimeout(() => runWorkFunction_inner(datum, (result) => reportResult(t0, result), (rejection) => reportError(t0, rejection)));
|
|
305
300
|
}
|
|
306
301
|
}); /* end of fn */
|
|
@@ -91,47 +91,12 @@ self.wrapScriptLoading({ scriptName: 'calculate-capabilities' }, function calcul
|
|
|
91
91
|
|
|
92
92
|
// Destroy the WebGL context, from https://www.khronos.org/registry/webgl/extensions/WEBGL_lose_context/
|
|
93
93
|
// "This is the recommended mechanism for applications to programmatically halt their use of the WebGL API."
|
|
94
|
-
gl.getExtension('WEBGL_lose_context').loseContext();
|
|
94
|
+
// gl.getExtension('WEBGL_lose_context').loseContext();
|
|
95
95
|
|
|
96
96
|
bigTexture4096 = textureSize >= 4096;
|
|
97
97
|
bigTexture8192 = textureSize >= 8192;
|
|
98
98
|
bigTexture16384 = textureSize >= 16384;
|
|
99
99
|
bigTexture32768 = textureSize >= 32768;
|
|
100
|
-
|
|
101
|
-
// Monkeypatch webGL *after* capability check to verify getContext exists AND not charge every job for GPU checking
|
|
102
|
-
getWebGLTimer = (function monkeypatchWebGL() {
|
|
103
|
-
let timer = 0;
|
|
104
|
-
function getTimer() {
|
|
105
|
-
return timer;
|
|
106
|
-
}
|
|
107
|
-
let oldGetContext = OffscreenCanvas.prototype.getContext;
|
|
108
|
-
OffscreenCanvas.prototype.getContext = function(type, options){
|
|
109
|
-
let context = oldGetContext(type, options);
|
|
110
|
-
for (let key of Object.getOwnPropertyNames(context.__proto__)){
|
|
111
|
-
if (typeof context[key] === 'function'){
|
|
112
|
-
let func = context[key].bind(context);
|
|
113
|
-
context[key] = (...args) => {
|
|
114
|
-
let startTimer = performance.now();
|
|
115
|
-
// Try using .then (assuming async) and falling back to synchronous
|
|
116
|
-
try{
|
|
117
|
-
ret = func(...args).then((ret)=>{
|
|
118
|
-
let timeRes = performance.now() - startTimer;
|
|
119
|
-
timer += timeRes;
|
|
120
|
-
return ret;
|
|
121
|
-
});
|
|
122
|
-
}catch(err){
|
|
123
|
-
ret = func(...args);
|
|
124
|
-
let timeRes = performance.now() - startTimer;
|
|
125
|
-
timer += timeRes;
|
|
126
|
-
}
|
|
127
|
-
return ret;
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
return context;
|
|
132
|
-
};
|
|
133
|
-
return getTimer;
|
|
134
|
-
})();
|
|
135
100
|
}catch(err){
|
|
136
101
|
//it is possible on some machines, that offscreenCanvas is available but canvas.getContext('webgl' or 'webgl2') results in null
|
|
137
102
|
//Any error in this using an extensions should likely result in specifications for that capability being set to false.
|
|
@@ -32,6 +32,7 @@ self.wrapScriptLoading({ scriptName: 'event-loop-virtualization' }, function eve
|
|
|
32
32
|
serviceEvents.timeout = null;
|
|
33
33
|
serviceEvents.nextTimeout = null;
|
|
34
34
|
serviceEvents.servicing = true;
|
|
35
|
+
serviceEvents.sliceIsFinished = false;
|
|
35
36
|
|
|
36
37
|
const startTime = performance.now();
|
|
37
38
|
let now = Date.now();
|
|
@@ -58,15 +59,30 @@ self.wrapScriptLoading({ scriptName: 'event-loop-virtualization' }, function eve
|
|
|
58
59
|
function endOfRealEventCycle()
|
|
59
60
|
{
|
|
60
61
|
serviceEvents.servicing = false;
|
|
62
|
+
if (!serviceEvents.sliceIsFinished)
|
|
63
|
+
{
|
|
64
|
+
const endTime = performance.now();
|
|
65
|
+
totalCPUTime += endTime - startTime;
|
|
66
|
+
|
|
67
|
+
// Set timeout to rerun this function if there are events remaining that just can't be used yet
|
|
68
|
+
if (events.length > 0)
|
|
69
|
+
{
|
|
70
|
+
serviceEvents.nextTimeout = events[0].when
|
|
71
|
+
serviceEvents.timeout = realSetTimeout(serviceEvents, events[0].when - Date.now());
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
protectedStorage.markCPUTimeAsDone = function markCPUTimeAsDone()
|
|
77
|
+
{
|
|
61
78
|
const endTime = performance.now();
|
|
62
79
|
totalCPUTime += endTime - startTime;
|
|
80
|
+
serviceEvents.sliceIsFinished = true;
|
|
81
|
+
}
|
|
63
82
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
serviceEvents.nextTimeout = events[0].when
|
|
68
|
-
serviceEvents.timeout = realSetTimeout(serviceEvents, events[0].when - Date.now());
|
|
69
|
-
}
|
|
83
|
+
protectedStorage.subtractWebGLTimeFromCPUTime = function subtractCPUTime(time)
|
|
84
|
+
{
|
|
85
|
+
totalCPUTime -= time;
|
|
70
86
|
}
|
|
71
87
|
}
|
|
72
88
|
|
|
@@ -124,6 +140,9 @@ self.wrapScriptLoading({ scriptName: 'event-loop-virtualization' }, function eve
|
|
|
124
140
|
return timer;
|
|
125
141
|
}
|
|
126
142
|
|
|
143
|
+
/** Ensure our trampoline setTimeout in bravojs-env will have the proper setTimeout, don't allow clients to see or overwrite to prevent measuring time */
|
|
144
|
+
protectedStorage.setTimeout = setTimeout;
|
|
145
|
+
|
|
127
146
|
/** Remove a timeout from the list of pending timeouts, regardless of its current
|
|
128
147
|
* status.
|
|
129
148
|
*
|
|
@@ -215,6 +234,7 @@ self.wrapScriptLoading({ scriptName: 'event-loop-virtualization' }, function eve
|
|
|
215
234
|
serviceEvents.timeout = null;
|
|
216
235
|
serviceEvents.nextTimeout = null;
|
|
217
236
|
serviceEvents.servicing = false;
|
|
237
|
+
serviceEvents.sliceIsFinished = false;
|
|
218
238
|
}
|
|
219
239
|
|
|
220
240
|
addEventListener('message', async (event) => {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file gpu-timers.js
|
|
3
|
+
* Copyright (c) 2018, Kings Distributed Systems, Ltd. All Rights Reserved. @todo: is this correct lol?
|
|
4
|
+
*
|
|
5
|
+
* This file adds wrappers for webGL and webGPU functions so we can measure their GPU time
|
|
6
|
+
*
|
|
7
|
+
* @author Ryan Saweczko, ryansaweczko@kingsds.network
|
|
8
|
+
* @date July 2022
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/* global WebGPUWindow GPU */
|
|
12
|
+
// @ts-nocheck
|
|
13
|
+
|
|
14
|
+
self.wrapScriptLoading({ scriptName: 'gpu-timers' }, function gpuTimers$fn(protectedStorage, ring2PostMessage)
|
|
15
|
+
{
|
|
16
|
+
/* Default if we don't have webGL */
|
|
17
|
+
protectedStorage.getAndResetWebGLTimer = function defaultTimer()
|
|
18
|
+
{
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (self.OffscreenCanvas && new OffscreenCanvas(1,1))
|
|
23
|
+
{
|
|
24
|
+
let time = 0;
|
|
25
|
+
function getAndResetWebGLTimer()
|
|
26
|
+
{
|
|
27
|
+
const tmp = time;
|
|
28
|
+
time = 0;
|
|
29
|
+
return tmp;
|
|
30
|
+
}
|
|
31
|
+
protectedStorage.getAndResetWebGLTimer = getAndResetWebGLTimer;
|
|
32
|
+
|
|
33
|
+
/* Factory to wrap a function from a context with a timer */
|
|
34
|
+
function timeWebGLFactory(context, prop)
|
|
35
|
+
{
|
|
36
|
+
let originalFn = context[prop].bind(context);
|
|
37
|
+
|
|
38
|
+
context[prop] = function wrappedWebGLFunction(...args)
|
|
39
|
+
{
|
|
40
|
+
var returnValue;
|
|
41
|
+
const start = performance.now();
|
|
42
|
+
try
|
|
43
|
+
{
|
|
44
|
+
returnValue = originalFn(...args);
|
|
45
|
+
time += performance.now() - start;
|
|
46
|
+
}
|
|
47
|
+
catch(e)
|
|
48
|
+
{
|
|
49
|
+
time += performance.now() - start;
|
|
50
|
+
throw e;
|
|
51
|
+
}
|
|
52
|
+
return returnValue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Update all functions on the OffscreenCanvas getContext prototype to have timers */
|
|
57
|
+
let oldGetContext = OffscreenCanvas.prototype.getContext;
|
|
58
|
+
OffscreenCanvas.prototype.getContext = function(type, options)
|
|
59
|
+
{
|
|
60
|
+
let context = oldGetContext.bind(this)(type, options);
|
|
61
|
+
for (let key of Object.getOwnPropertyNames(context.__proto__))
|
|
62
|
+
if (typeof context[key] === 'function')
|
|
63
|
+
timeWebGLFactory(context, key);
|
|
64
|
+
return context;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
});
|
|
@@ -135,6 +135,7 @@ try {
|
|
|
135
135
|
serialize = newSerializer.serialize
|
|
136
136
|
deserialize = newSerializer.deserialize
|
|
137
137
|
outMsg = { type: 'nop', success: true }
|
|
138
|
+
send(outMsg);
|
|
138
139
|
break
|
|
139
140
|
case 'workerMessage':
|
|
140
141
|
// if (inMsg.message.request === 'main') {
|
|
@@ -145,6 +146,7 @@ try {
|
|
|
145
146
|
// }
|
|
146
147
|
emitEvent('message', {data: inMsg.message})
|
|
147
148
|
outMsg.success = true
|
|
149
|
+
send(outMsg)
|
|
148
150
|
break
|
|
149
151
|
case 'die':
|
|
150
152
|
writeln('DIE: ' + Date())
|
|
@@ -157,7 +159,6 @@ try {
|
|
|
157
159
|
outMsg.success = false
|
|
158
160
|
outMsg.exception = { name: e.name, message: e.message, fileName: e.fileName, lineNumber: e.lineNumber, stack: e.stack }
|
|
159
161
|
outMsg.e = e
|
|
160
|
-
} finally {
|
|
161
162
|
send(outMsg)
|
|
162
163
|
}
|
|
163
164
|
}) /* receiveLine */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dcp-client",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.9",
|
|
4
4
|
"description": "Core libraries for accessing DCP network",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dcp"
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@kingsds/eslint-config": "1.0.1",
|
|
54
54
|
"eslint": "7.30.0",
|
|
55
|
-
"
|
|
56
|
-
"
|
|
55
|
+
"express": "^4.17.1",
|
|
56
|
+
"peter": "^2.3.2"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"dcp-worker": "^3.0.0"
|