// ==UserScript==
// @name 2D跨域优化 - HyperGPU Pro版 (Wasm深度协同) - 后台引擎
// @namespace http://tampermonkey.net/
// @version 1.0.1
// @description WebGPU与Wasm深度协同计算工具箱
// @author KiwiFruit
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @run-at document-end
// @license MIT
// ==/UserScript==
(function () {
'use strict';
/* global GPUMapMode,GPUBufferUsage,GPUShaderStage,SharedArrayBuffer,FinalizationRegistry */
// ==================== 核心常量与配置 ====================
const CONFIG = {
maxWorkers: navigator.hardwareConcurrency || 4,
logLevel: GM_getValue('hyperGpuLogLevel', 'info'),
wasmRetryCount: 3,
memoryPoolSize: 1024 * 1024 * 12, // 8MB内存池
minSuperResolutionSize: 50,
enablePerformanceMonitoring: GM_getValue('hyperGpuPerfMon', 1),
enableFinalizationRegistry: GM_getValue('hyperGpuFinReg', 1),
// 【需替换】Wasm文件的Base64编码(替换为新Wasm的Base64)
base64Wasm: `AGFzbQEAAAABowEYYAAAYAABf2ABfwBgAX8Bf2ACf38AYAJ/fwF/YAN/f38AYAN/f38Bf2AEf39/fwBgBH9/f38Bf2AFf39/f38AYAV/f39/fwF/YAZ/f39/f38AYAZ/f39/f38Bf2AEf39/fQBgBX9/fn9/AGAFf399f38AYAV/f3x/fwBgBH9+f38AYAR/fX9/AGAFf31/f38AYAR/fH9/AGABfQF9YAJ9fQF9AjkCA3diZxpfX3diZ19uZXdfYzY4ZDcyMDliZTc0NzM3OQAFA3diZxBfX3diaW5kZ2VuX3Rocm93AAQDe3oDBwwJBQ4CBwgEBQQFCgYEBQYICgQIBgQECAoKAwoUBAYMBAQCBAIECAoGDAwECAQEBggGFgoICAYHBAQEAgIGAgMDCQMDAwMDAwICAgICBAINDwoLCgsQChEIAgIHBQIXAgUEBAYFBQYGAgMFBQQDAAQABAQCAQEAAAQFAXABGhoFAwEAEQYJAX8BQYCAwAALB5QGJgZtZW1vcnkCABlfX3diZ19wcm9jZXNzZWRpbWFnZV9mcmVlAD0ScHJvY2Vzc2VkaW1hZ2VfcHRyAEYScHJvY2Vzc2VkaW1hZ2VfbGVuAEcUcHJvY2Vzc2VkaW1hZ2Vfd2lkdGgASBVwcm9jZXNzZWRpbWFnZV9oZWlnaHQASRdwcm9jZXNzZWRpbWFnZV9pc19lbXB0eQBDE3Byb2Nlc3NlZGltYWdlX2ZyZWUAUBlzdXBlcl9yZXNvbHV0aW9uX2JpbGluZWFyAC0TZW5oYW5jZV92aWRlb19mcmFtZQAuDm1hdHJpeF9kZXRfMngyACcObWF0cml4X2RldF8zeDMAGQ5tYXRyaXhfaW52XzJ4MgATDW11bHRpcGx5X21hdDQAOBBtYXRyaXhfdHJhbnNwb3NlAA8OcXVhZHJhdGljX2Zvcm0ACh1fX3diZ19wcm9jZXNzZWRwYXJ0aWNsZXNfZnJlZQA8FnByb2Nlc3NlZHBhcnRpY2xlc19wdHIAShZwcm9jZXNzZWRwYXJ0aWNsZXNfbGVuAEsbcHJvY2Vzc2VkcGFydGljbGVzX2lzX2VtcHR5AEQXcHJvY2Vzc2VkcGFydGljbGVzX2ZyZWUATxRwcmVwcm9jZXNzX3BhcnRpY2xlcwAHEG5vcm1hbGl6ZV92ZWN0b3IAFhhub3JtYWxp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IAdBBEYNAUMAAAAAIQpBACEEIAghCQJAA0AgBEEQRg0BIAogASAEaioCACAJKgIAlJIhCiAJQRBqIQkgBEEEaiEEDAALCyADIAcgBnJBAnRqIAo4AgAgCEEEaiEIIAdBAWohBwwACwsgAUEQaiEBIAVBAWohBQwACwsgACAENgIAC8wBAQN/IwBBIGsiAyQAAkACQAJAIAEgAmoiAiABTw0AQQAhBAwBC0EAIQQCQCACIAAoAgAiBUEBdCIBIAIgAUsbIgFBCCABQQhLGyIBQQBODQAMAQtBACECAkAgBUUNACADIAU2AhwgAyAAKAIENgIUQQEhAgsgAyACNgIYIANBCGogASADQRRqEDogAygCCEEBRw0BIAMoAhAhACADKAIMIQQLIAQgAEHIjMAAEGcACyADKAIMIQIgACABNgIAIAAgAjYCBCADQSBqJAALygECAn8FfSMAQSBrIgIkAAJAAkAgAQ0AQYCAgIB4IQEMAQsgAiABKgIIIAEqAhwiBCABKgIMIgWUIAEqAhAiBiABKgIYIgeUk5QgASoCACAGIAEqAiAiCJQgASoCFCIGIASUk5QgASoCBCAIIAWUIAYgB5STlJOSOAIQQYWAgIB4IQELIAIgATYCDCACQRhqIAJBDGoQLyAAIAIoAhgiATYCCCAAIAIoAhwiA0EAIAEbNgIEIABDAAAAACADviABGzgCACACQSBqJAALxAECBH8BfiMAQSBrIgIkACABEGwCQCABQXhqIgMoAgBBAUcNACACQQhqQRBqIgQgAUEUaigCADYCACACQQhqQQhqIgUgAUEMaikCADcDACABKQIEIQYgA0EANgIAIAIgBjcDCAJAIANBf0YNACABQXxqIgEgASgCAEF/aiIBNgIAIAENACADQSBBBBAzCyAAIAIpAwg3AgAgAEEQaiAEKAIANgIAIABBCGogBSkDADcCACACQSBqJAAPC0H0h8AAQT8QcwALvwEBAn8jAEEgayIEJABBgICAgHghBQJAIAFFDQAgAkUNACADRQ0AIAMgASoCBCACKgIIlCABKgIIIAIqAgSUkzgCACADIAEqAgggAioCAJQgASoCACACKgIIlJM4AgQgAyABKgIAIAIqAgSUIAEqAgQgAioCAJSTOAIIQYWAgIB4IQULIAQgBTYCFCAEQQhqIARBFGoQMiAEKAIMIQEgACAE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bSBGaWxlc1xSdXN0XC5ydXN0dXBcdG9vbGNoYWluc1xzdGFibGUteDg2XzY0LXBjLXdpbmRvd3MtbXN2Y1xsaWIvcnVzdGxpYi9zcmMvcnVzdFxsaWJyYXJ5L2NvcmUvc3JjL2l0ZXIvdHJhaXRzL2l0ZXJhdG9yLnJzAHNyY1xwYXJ0aWNsZS5ycwBzcmNcaW1hZ2UucnMARDpcUHJvZ3JhbSBGaWxlc1xSdXN0XC5ydXN0dXBcdG9vbGNoYWluc1xzdGFibGUteDg2XzY0LXBjLXdpbmRvd3MtbXN2Y1xsaWIvcnVzdGxpYi9zcmMvcnVzdFxsaWJyYXJ5L2FsbG9jL3NyYy9zbGljZS5ycwBEOlxQcm9ncmFtIEZpbGVzXFJ1c3RcLnJ1c3R1cFx0b29sY2hhaW5zXHN0YWJsZS14ODZfNjQtcGMtd2luZG93cy1tc3ZjXGxpYi9ydXN0bGliL3NyYy9ydXN0XGxpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMvbW9kLnJzAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjkvc3JjL2RsbWFsbG9jLnJzAEQ6XFByb2dyYW0gRmlsZXNcUnVzdFwuY2FyZ29ccmVnaXN0cnlcc3JjXGluZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmXG9uY2VfY2VsbC0xLjIxLjNcc3JjXGxpYi5ycwCdABAAhQAAAOsHAAAJAAAAtgEQAH0AAAAuAgAAEQAAAD8BEAB3AAAAwQEAAB0AAABOdWxsIHBvaW50ZXIgcHJvdmlkZWQAAAD0AhAAFQAAAEludmFsaWQgbGVuZ3RoIHBhcmFtZXRlciBvciBhcml0aG1ldGljIG92ZXJmbG93ABQDEAAvAAAAQXJpdGhtZXRpYyBvdmVyZmxvdyBkZXRlY3RlZEwDEAAcAAAATWF0cml4IGlzIHNpbmd1bGFyIChub3QgaW52ZXJ0aWJsZSkAcAMQACMAAABJbnZhbGlkIGlucHV0IGRhdGEgcHJvdmlkZWQAnAMQABsAAABJbnRlcm5hbCBlcnJvcjogwAMQABAAAABQcm9jZXNzaW5nIEVycm9yOiAAANgDEAASAAAAYXR0ZW1wdGVkIHRvIHRha2Ugb3duZXJzaGlwIG9mIFJ1c3QgdmFsdWUgd2hpbGUgaXQgd2FzIGJvcnJvd2VkADIBEAANAAAAagAAABsAAAAyARAADQAAAH8AAAAbAAAAMgEQAA0AAACCAAAAGwAAADIBEAANAAAAhQAAABsAAAAyARAADQAAAIgAAAAbAAAAMgEQAA0AAACSAAAAHAAAAEludmVyc2UgZGV0ZXJtaW5hbnQgaXMgaW52YWxpZAAAAAAQAA4AAADBAAAAJAAAAAAAEAAOAAAAwQAAAA0AAAAAABAADgAAAOgAAAASAAAAUXVhZHJhdGljIGZvcm0gcmVzdWx0ZWQgaW4gbm9uLWZpbml0ZSB2YWx1ZQAAABAADgAAAO4AAAAWAAAAIgEQABAAAACGAAAAOwAAAENhbGN1bGF0ZWQgbWFnbml0dWRlIGlzIGludmFsaWQgKE5hTiBvciBJbmYpTm9ybWFsaXphdGlvbiByZXN1bHRlZCBpbiBub24tZmluaXRlIHZhbHVlRG90IHByb2R1Y3QgcmVzdWx0ZWQgaW4gbm9uLWZpbml0ZSB2YWx1ZTAuMi4wV2ViR1BVIFdBU00gQ29yZSBMaWJyYXJ5IC0gSGlnaC1wZXJmb3JtYW5jZSBtYXRoZW1hdGljYWwgY29tcHV0YXRpb25zIGZvciB3ZWIgYXBwbGljYXRpb25zRXJyb3IAABQAAAAMAAAABAAAABUAAAAWAAAAFwAAAGNhcGFjaXR5IG92ZXJmbG93AAAALAYQABEAAAASAhAAIQAAAC4CAAARAAAAAAAAAAAAAAABAAAAGAAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90AAAOABAAGQAAAIoCAAAOAAAAaW5kZXggb3V0IG9mIGJvdW5kczogdGhlIGxlbiBpcyAgYnV0IHRoZSBpbmRleCBpcyAAANAGEAAgAAAA8AYQABIAAAA6IAAAAQAAAAAAAAAUBxAAAgAAADAwMDEwMjAzMDQwNTA2MDcwODA5MTAxMTEyMTMxNDE1MTYxNzE4MTkyMDIxMjIyMzI0MjUyNjI3MjgyOTMwMzEzMjMzMzQzNTM2MzczODM5NDA0MTQyNDM0NDQ1NDY0NzQ4NDk1MDUxNTI1MzU0NTU1NjU3NTg1OTYwNjE2MjYzNjQ2NTY2Njc2ODY5NzA3MTcyNzM3NDc1NzY3Nzc4Nzk4MDgxODI4Mzg0ODU4Njg3ODg4OTkwOTE5MjkzOTQ5NTk2OTc5ODk5JwAQAHYAAAAkAQAADgAAAGNsb3N1cmUgaW52b2tlZCByZWN1cnNpdmVseSBvciBhZnRlciBiZWluZyBkcm9wcGVkYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPj0gc2l6ZSArIG1pbl9vdmVyaGVhZDMCEAAqAAAAsAQAAAkAAABhc3NlcnRpb24gZmFpbGVkOiBwc2l6ZSA8PSBzaXplICsgbWF4X292ZXJoZWFkAAAzAhAAKgAAALYEAAANAAAAVHJpZWQgdG8gc2hyaW5rIHRvIGEgbGFyZ2VyIGNhcGFjaXR5sAgQACQAAAC2ARAAfQAAALkCAAAJAAAATGF6eSBpbnN0YW5jZSBoYXMgcHJldmlvdXNseSBiZWVuIHBvaXNvbmVkAADsCBAAKgAAAF0CEABnAAAACAMAABkAAAByZWVudHJhbnQgaW5pdAAAMAkQAA4AAABdAhAAZwAAAHoCAAANAAAAbnVsbCBwb2ludGVyIHBhc3NlZCB0byBydXN0cmVjdXJzaXZlIHVzZSBvZiBhbiBvYmplY3QgZGV0ZWN0ZWQgd2hpY2ggd291bGQgbGVhZCB0byB1bnNhZmUgYWxpYXNpbmcgaW4gcnVzdABBxJPAAAscAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAAAApBG5hbWUBIgFxH19fd2JpbmRnZW5fYWRkX3RvX3N0YWNrX3BvaW50ZXIAPAlwcm9kdWNlcnMBDHByb2Nlc3NlZC1ieQIGd2FscnVzBjAuMjMuMwx3YXNtLWJpbmRnZW4HMC4yLjEwMA==` // <--- 替换此处
};
// ==================== 工具函数模块 ====================
const Utils = {
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
generateId() {
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
},
findFreeMemory(memoryView, length) {
const usableLength = memoryView.length - length;
for (let i = 0; i < usableLength; i++) {
if (memoryView[i] === 0 && (i + length >= memoryView.length || memoryView[i + length] === 0)) {
let free = true;
for (let j = i; j < i + length; j++) {
if (memoryView[j] !== 0) {
free = false;
break;
}
}
if (free) return i;
}
}
return -1;
},
decodeWasmBase64() {
if (!CONFIG.base64Wasm || CONFIG.base64Wasm === 'base64代码替换') {
throw new Error('未替换Base64编码,请填入Wasm文件的Base64字符串。请确保使用正确的Wasm文件并将其转换为Base64编码粘贴在此处。');
}
const cleanBase64 = CONFIG.base64Wasm.replace(/\s+/g, '');
if (cleanBase64.length === 0) {
throw new Error('Base64编码为空');
}
const binaryString = atob(cleanBase64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
Log.info('Utils', `Wasm解码完成,大小:${(bytes.byteLength / 1024).toFixed(2)}KB`);
return bytes;
},
getStringFromWasm(ptr, len, memory) {
return new TextDecoder('utf-8').decode(new Uint8Array(memory.buffer, ptr, len));
}
};
// ==================== 日志模块 ====================
const Log = {
debug(tag, ...args) { if (['debug'].includes(CONFIG.logLevel)) console.debug(`[${tag}]`, ...args); },
info(tag, ...args) { if (['debug', 'info'].includes(CONFIG.logLevel)) console.info(`[${tag}]`, ...args); },
warn(tag, ...args) { if (['debug', 'info', 'warn'].includes(CONFIG.logLevel)) console.warn(`[${tag}]`, ...args); },
error(tag, ...args) { console.error(`[${tag}]`, ...args); }
};
// ==================== 错误处理 ====================
class FrameworkError extends Error {
constructor(message, context = {}) {
super(message);
this.name = 'FrameworkError';
this.context = context;
this.timestamp = Date.now();
}
}
// ==================== 状态管理模块 ====================
class StateManager {
static instance = null;
resources = new Map();
cleanupCallbacks = new Set();
static getInstance() {
if (!StateManager.instance) {
StateManager.instance = new StateManager();
}
return StateManager.instance;
}
registerResource(id, resource) {
this.resources.set(id, resource);
}
addCleanupCallback(callback) {
this.cleanupCallbacks.add(callback);
}
destroy() {
Log.info('StateManager', '开始销毁资源...');
this.resources.forEach(res => {
if (res.destroy) res.destroy();
});
this.cleanupCallbacks.forEach(cb => {
try { cb(); } catch (e) { Log.error('StateManager', '清理回调执行失败', e); }
});
this.resources.clear();
this.cleanupCallbacks.clear();
Log.info('StateManager', '资源销毁完成');
}
}
// ==================== 环境检测模块 ====================
class EnvironmentLayer {
report = {
webgpu: typeof navigator.gpu !== 'undefined',
webgl2: typeof WebGL2RenderingContext !== 'undefined',
wasm: typeof WebAssembly !== 'undefined',
sharedArrayBuffer: typeof SharedArrayBuffer !== 'undefined',
worker: typeof Worker !== 'undefined',
finalizationRegistry: typeof FinalizationRegistry !== 'undefined'
};
mode = this.determineMode();
determineMode() {
if (this.report.webgpu && this.report.wasm) return 'webgpu+wasm';
if (this.report.wasm && this.report.webgl2) return 'webgl+wasm';
if (this.report.wasm) return 'cpu+wasm';
return 'pure-js';
}
adaptEnvironment() {
if (!this.report.sharedArrayBuffer && this.mode.includes('wasm')) {
Log.warn('Environment', 'SharedArrayBuffer不可用,可能影响性能');
}
if (!this.report.finalizationRegistry) {
Log.warn('Environment', 'FinalizationRegistry不被支持,自动内存释放将不可用');
if (CONFIG.enableFinalizationRegistry) {
Log.info('Environment', '由于浏览器不支持,已强制关闭FinalizationRegistry');
CONFIG.enableFinalizationRegistry = 0;
GM_setValue('hyperGpuFinReg', 0);
}
} else {
Log.info('Environment', `FinalizationRegistry支持: ${CONFIG.enableFinalizationRegistry ? '已启用' : '已禁用'}`);
}
window.addEventListener('message', (e) => {
if (e.data.type === 'wasm-message') {
Log.debug('Environment', '收到Wasm消息', e.data.payload);
}
});
}
}
// ==================== 资源管理模块 ====================
class ResourceLayer {
constructor(envLayer) {
this.envLayer = envLayer;
this.wasmModule = null;
this.gpu = {
device: null,
queue: null,
context: null,
presentationFormat: null,
pipelines: new Map(),
buffers: new Map()
};
this.sharedMemory = null;
this.memoryPool = null;
// 为堆管理添加状态
this.heap = new Array(128).fill(undefined);
this.heap.push(undefined, null, true, false);
this.heap_next = this.heap.length;
}
async init() {
Log.info('Resource', '开始初始化资源层...');
try {
this.initMemoryPool();
await this.initWebGPU();
await this.loadWasmModule();
this.initSharedMemory();
Log.info('Resource', '资源层初始化完成');
} catch (error) {
throw new FrameworkError('资源层初始化失败', { error });
}
}
initMemoryPool() {
try {
this.memoryPool = new Uint8Array(new ArrayBuffer(CONFIG.memoryPoolSize));
Log.info('Resource', '内存池初始化完成');
} catch (error) {
Log.error('Resource', '内存池初始化失败', error);
}
}
async initWebGPU() {
if (!this.envLayer.report.webgpu) {
Log.info('Resource', 'WebGPU不被支持,跳过初始化');
return;
}
try {
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) throw new Error('无法获取GPU适配器');
const requiredFeatures = [];
const optionalFeatures = ['timestamp-query', 'texture-compression-bc', 'texture-compression-etc2', 'texture-compression-astc'];
for (const feature of optionalFeatures) {
if (adapter.features.has(feature)) {
requiredFeatures.push(feature);
}
}
this.gpu.device = await adapter.requestDevice({ requiredFeatures });
this.gpu.queue = this.gpu.device.queue;
Log.info('Resource', 'WebGPU初始化完成');
} catch (error) {
Log.error('Resource', 'WebGPU初始化失败', error);
this.gpu.device = null;
}
}
initSharedMemory() {
try {
const size = 1024 * 1024 * 6;
this.sharedMemory = this.envLayer.report.sharedArrayBuffer ?
new SharedArrayBuffer(size) :
new ArrayBuffer(size);
Log.info('Resource', '共享内存初始化完成');
} catch (error) {
this.sharedMemory = new ArrayBuffer(1024 * 1024);
Log.warn('Resource', '共享内存初始化失败,使用降级方案', error);
}
}
// --- Wasm 堆管理辅助函数 (模拟 wasm-bindgen) ---
addHeapObject(obj) {
if (this.heap_next === this.heap.length) this.heap.push(this.heap.length + 1);
const idx = this.heap_next;
this.heap_next = this.heap[idx];
this.heap[idx] = obj;
return idx;
}
getObject(idx) {
return this.heap[idx];
}
dropObject(idx) {
if (idx < 132) return;
this.heap[idx] = this.heap_next;
this.heap_next = idx;
}
// --- 结束 Wasm 堆管理辅助函数 ---
async loadWasmModule() {
if (!this.envLayer.report.wasm) {
Log.info('Resource', 'Wasm不被支持,跳过加载');
return;
}
let lastError = null;
for (let retry = 0; retry < CONFIG.wasmRetryCount; retry++) {
try {
Log.info('Resource', `Wasm模块加载尝试 ${retry + 1}/${CONFIG.wasmRetryCount}`);
const wasmBytes = Utils.decodeWasmBase64();
// --- 修复 Wasm 导入对象 ---
// 根据知识库文档5/6和错误信息,提供完整的 wbg 导入
const imports = {
env: {
// 保留原有的 env 导入
__wbindgen_malloc: (size) => {
if (this.wasmModule?.exports?.memory) {
if (this.wasmModule.exports.__wbindgen_malloc) {
return this.wasmModule.exports.__wbindgen_malloc(size);
}
// 备选方案:使用 memory.grow
const pages = Math.ceil((size + 0xFFFF) / 0x10000);
const oldPages = this.wasmModule.exports.memory.buffer.byteLength / 0x10000;
try {
this.wasmModule.exports.memory.grow(pages);
return oldPages * 0x10000;
} catch (e) {
Log.error('Wasm', '内存增长失败', e);
return 0;
}
}
return 0;
},
__wbindgen_free: (ptr, size) => {
if (this.wasmModule?.exports?.__wbindgen_free) {
this.wasmModule.exports.__wbindgen_free(ptr, size);
} else {
Log.debug('Wasm', `释放内存: ptr=${ptr}, size=${size}`);
}
},
wasm_alloc: (size) => {
// 优先使用 __wbindgen_malloc
if (imports.env.__wbindgen_malloc) {
return imports.env.__wbindgen_malloc(size);
}
if (this.wasmModule?.exports?.memory) {
// 备选方案
}
return 0;
},
free_memory: (ptr) => {
// 优先使用 __wbindgen_free
if (imports.env.__wbindgen_free) {
// 注意:可能需要 size 参数
}
Log.debug('Wasm', `释放内存 (free_memory): ptr=${ptr}`);
},
emscripten_console_log: (ptr, len) => {
if (this.wasmModule?.exports?.memory) {
const str = Utils.getStringFromWasm(ptr, len, this.wasmModule.exports.memory);
Log.debug('Wasm', `日志: ${str}`);
}
},
emscripten_console_error: (ptr, len) => {
if (this.wasmModule?.exports?.memory) {
const str = Utils.getStringFromWasm(ptr, len, this.wasmModule.exports.memory);
Log.error('Wasm', `错误: ${str}`);
}
}
},
// --- 修复并完善 wbg 导入 ---
wbg: {
// 根据知识库文档5/6添加缺失的导入函数
__wbindgen_object_drop_ref: (idx) => {
this.dropObject(idx);
},
// 根据错误信息和知识库添加
__wbg_new_c68d7209be747379: (arg0, arg1) => {
if (this.wasmModule?.exports?.memory) {
try {
const errorMessage = Utils.getStringFromWasm(arg0, arg1, this.wasmModule.exports.memory);
const error = new Error(errorMessage);
return this.addHeapObject(error);
} catch (e) {
Log.error('Wasm', '创建Error对象失败', e);
return this.addHeapObject(new Error("Wasm error creation failed"));
}
}
return this.addHeapObject(new Error("Wasm error (memory inaccessible)"));
},
__wbindgen_throw: (arg0, arg1) => {
if (this.wasmModule?.exports?.memory) {
const error = Utils.getStringFromWasm(arg0, arg1, this.wasmModule.exports.memory);
// 抛出 FrameworkError 以保持一致性
throw new FrameworkError(`Wasm绑定错误: ${error}`, { type: 'bindgen_throw', ptr: arg0, len: arg1 });
}
throw new FrameworkError('Wasm绑定错误 (内存不可访问)');
},
// 可能还需要其他 wbg 函数,根据实际 Wasm 模块的需求添加
// 例如,如果 Wasm 模块使用了字符串,可能需要 __wbindgen_string_new 等
__wbindgen_init_externref_table: () => {
// 简单实现或留空,具体取决于Wasm模块需求
Log.debug('Wasm', '调用 __wbindgen_init_externref_table');
}
// ... 根据需要添加更多 __wbg_* 函数 ...
}
};
// --- 结束修复 Wasm 导入对象 ---
const result = await WebAssembly.instantiate(wasmBytes, imports);
this.wasmModule = result.instance;
if (this.wasmModule.exports.__wbindgen_start) {
this.wasmModule.exports.__wbindgen_start();
}
if (this.wasmModule.exports.init_wasm) {
this.wasmModule.exports.init_wasm();
Log.info('Resource', 'Wasm init_wasm() 调用完成');
}
Log.info('Resource', 'Wasm模块加载成功');
Log.debug('Resource', '导出函数:', Object.keys(this.wasmModule.exports).filter(k => typeof this.wasmModule.exports[k] === 'function'));
return;
} catch (error) {
lastError = error;
Log.error('Resource', `Wasm模块加载失败(第${retry + 1}次重试)`, error);
// 特别检查是否是导入相关的 LinkError
if (error instanceof WebAssembly.LinkError) {
Log.error('Resource', 'Wasm LinkError 通常是导入对象不匹配导致的,请检查 imports.wbg 和 imports.env');
}
if (retry < CONFIG.wasmRetryCount - 1) {
await Utils.delay(1000 * (retry + 1));
}
}
}
throw new FrameworkError('Wasm模块加载失败(已达最大重试次数)', { error: lastError });
}
}
// ==================== 协作层模块 ====================
class CollaborationLayer {
constructor(envLayer, resourceLayer) {
this.envLayer = envLayer;
this.resourceLayer = resourceLayer;
this.taskQueue = [];
this.workerPool = [];
this.activeTasks = new Map();
this.stats = {
tasksProcessed: 0,
errors: 0,
wasmExecutionTimeMs: CONFIG.enablePerformanceMonitoring ? 0 : undefined,
memoryAllocatedBytes: CONFIG.enablePerformanceMonitoring ? 0 : undefined,
tasksByType: {}
};
}
async init() {
Log.info('Collaboration', '开始初始化协作层...');
await this.initWorkerPool();
Log.info('Collaboration', '协作层初始化完成');
}
async initWorkerPool() {
if (!this.envLayer.report.worker) {
Log.warn('Collaboration', '浏览器不支持Worker,禁用多线程');
return;
}
const workerCode = `
let wasmModule = null;
let wasmExports = null;
self.onmessage = async function(e) {
if (e.data.type === 'LOAD_WASM') {
try {
const base64Wasm = e.data.base64Wasm;
const binaryString = atob(base64Wasm);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// Worker 内部也需要完整的 imports 对象
const imports = {
env: {
__wbindgen_malloc: (size) => {
if (wasmExports?.memory) {
if (wasmExports.__wbindgen_malloc) {
return wasmExports.__wbindgen_malloc(size);
}
const pages = Math.ceil((size + 0xFFFF) / 0x10000);
const oldPages = wasmExports.memory.buffer.byteLength / 0x10000;
try {
wasmExports.memory.grow(pages);
return oldPages * 0x10000;
} catch (e) {
console.error('Worker Wasm', '内存增长失败', e);
return 0;
}
}
return 0;
},
__wbindgen_free: (ptr, size) => {
if (wasmExports?.__wbindgen_free) {
wasmExports.__wbindgen_free(ptr, size);
} else {
console.debug('Worker Wasm', \`释放内存: ptr=\${ptr}, size=\${size}\`);
}
},
wasm_alloc: (size) => {
if (imports.env.__wbindgen_malloc) {
return imports.env.__wbindgen_malloc(size);
}
// ... (备选)
return 0;
},
free_memory: (ptr) => {
if (imports.env.__wbindgen_free) { /* ... */ }
console.debug('Worker Wasm', \`释放内存 (free_memory): ptr=\${ptr}\`);
},
emscripten_console_log: (ptr, len) => {
if (wasmExports?.memory) {
const str = new TextDecoder('utf-8').decode(new Uint8Array(wasmExports.memory.buffer, ptr, len));
console.debug('Worker Wasm Log:', str);
}
},
emscripten_console_error: (ptr, len) => {
if (wasmExports?.memory) {
const str = new TextDecoder('utf-8').decode(new Uint8Array(wasmExports.memory.buffer, ptr, len));
console.error('Worker Wasm Error:', str);
}
}
},
wbg: {
__wbindgen_object_drop_ref: (idx) => {
// Worker 内部也需要堆管理逻辑,这里简化处理
console.debug('Worker Wasm', \`丢弃对象: idx=\${idx}\`);
},
__wbg_new_c68d7209be747379: (arg0, arg1) => {
if (wasmExports?.memory) {
try {
const errorMessage = new TextDecoder('utf-8').decode(new Uint8Array(wasmExports.memory.buffer, arg0, arg1));
const error = new Error(errorMessage);
// Worker 内部也需要堆管理逻辑,这里简化处理
console.warn('Worker Wasm 创建Error对象:', errorMessage);
return 0; // Simplified
} catch (e) {
console.error('Worker Wasm', '创建Error对象失败', e);
return 0;
}
}
return 0;
},
__wbindgen_throw: (arg0, arg1) => {
if (wasmExports?.memory) {
const error = new TextDecoder('utf-8').decode(new Uint8Array(wasmExports.memory.buffer, arg0, arg1));
throw new Error(\`Worker Wasm绑定错误: \${error}\`);
}
throw new Error('Worker Wasm绑定错误 (内存不可访问)');
},
__wbindgen_init_externref_table: () => {
console.debug('Worker Wasm', '调用 __wbindgen_init_externref_table');
}
}
};
const result = await WebAssembly.instantiate(bytes, imports);
wasmModule = result.instance;
wasmExports = wasmModule.exports;
if (wasmExports.__wbindgen_start) {
wasmExports.__wbindgen_start();
}
if (wasmExports.init_wasm) {
wasmExports.init_wasm();
}
self.postMessage({ type: 'WASM_LOADED' });
} catch (error) {
console.error('Worker 加载 Wasm 失败:', error);
self.postMessage({ type: 'WASM_LOAD_ERROR', error: error.message });
}
return;
}
if (e.data.type === 'PROCESS_TASK' && wasmExports) {
const { taskId, task } = e.data;
try {
// 这里需要实现与主脚本 processWithWasm 类似的逻辑
if (task.type === 'vector_normalize') {
const { vector } = task.input;
const sizeInBytes = vector.length * 4;
const ptr = (wasmExports.__wbindgen_malloc || wasmExports.wasm_alloc)(sizeInBytes);
if (!ptr) throw new Error('Worker Wasm内存分配失败');
new Float32Array(wasmExports.memory.buffer, ptr, vector.length).set(vector);
if (wasmExports.normalize_vector_generic) {
wasmExports.normalize_vector_generic(ptr, vector.length);
} else {
throw new Error('Worker Wasm缺少normalize_vector_generic函数');
}
const resultView = new Float32Array(wasmExports.memory.buffer, ptr, vector.length);
const resultData = Array.from(resultView);
wasmExports.__wbindgen_free ? wasmExports.__wbindgen_free(ptr, sizeInBytes) : wasmExports.free_memory(ptr);
self.postMessage({ type: 'TASK_RESULT', taskId, result: { status: 'success', data: { status: 'vector_normalized', data: resultData } } });
} else {
throw new Error(\`Worker 不支持的任务类型: \${task.type}\`);
}
} catch (error) {
console.error('Worker 处理任务失败:', error);
self.postMessage({ type: 'TASK_RESULT', taskId, result: { status: 'error', error: { message: error.message || '未知Worker错误' } } });
}
}
};
`;
const blob = new Blob([workerCode], { type: 'application/javascript' });
const workerUrl = URL.createObjectURL(blob);
StateManager.getInstance().addCleanupCallback(() => {
URL.revokeObjectURL(workerUrl);
this.workerPool.forEach(workerInfo => {
if (workerInfo.worker) workerInfo.worker.terminate();
});
});
for (let i = 0; i < CONFIG.maxWorkers; i++) {
const worker = new Worker(workerUrl);
const workerId = `worker-${i}`;
worker.onmessage = (e) => this.handleWorkerMessage(e, workerId);
worker.onerror = (e) => this.handleWorkerError(e, workerId);
this.workerPool.push({
id: workerId,
worker: worker,
busy: false,
currentTaskId: null
});
worker.postMessage({ type: 'LOAD_WASM', base64Wasm: CONFIG.base64Wasm });
}
Log.info('Collaboration', `Worker池初始化完成(容量: ${CONFIG.maxWorkers})`);
}
handleWorkerMessage(e, workerId) {
const workerInfo = this.workerPool.find(w => w.id === workerId);
if (!workerInfo) return;
const data = e.data;
if (data.type === 'WASM_LOADED') {
Log.info('Collaboration', `Worker ${workerId} Wasm加载成功`);
workerInfo.wasmLoaded = true;
} else if (data.type === 'WASM_LOAD_ERROR') {
Log.error('Collaboration', `Worker ${workerId} Wasm加载失败`, data.error);
workerInfo.wasmLoadError = true;
} else if (data.type === 'TASK_RESULT') {
const { taskId, result } = data;
const taskPromise = this.activeTasks.get(taskId);
if (taskPromise) {
if (result.status === 'success') {
taskPromise.resolve(result.data);
} else {
taskPromise.reject(result.error);
}
this.activeTasks.delete(taskId);
}
workerInfo.busy = false;
workerInfo.currentTaskId = null;
this.processTasks();
}
}
handleWorkerError(e, workerId) {
Log.error('Collaboration', `Worker ${workerId} 发生错误`, e);
const workerInfo = this.workerPool.find(w => w.id === workerId);
if (workerInfo && workerInfo.currentTaskId) {
const taskPromise = this.activeTasks.get(workerInfo.currentTaskId);
if (taskPromise) {
taskPromise.reject(new FrameworkError('Worker执行失败', { workerId, error: e.message }));
this.activeTasks.delete(workerInfo.currentTaskId);
}
workerInfo.busy = false;
workerInfo.currentTaskId = null;
}
}
submitTask(task, priority = 5) {
return new Promise((resolve, reject) => {
const taskId = Utils.generateId();
const taskWrapper = { ...task, priority, id: taskId };
this.taskQueue.push(taskWrapper);
if (CONFIG.enablePerformanceMonitoring) {
this.stats.tasksByType[task.type] = (this.stats.tasksByType[task.type] || 0) + 1;
}
this.activeTasks.set(taskId, { resolve, reject });
this.processTasks();
});
}
async processTasks() {
if (this.taskQueue.length === 0) return;
this.taskQueue.sort((a, b) => a.priority - b.priority);
const task = this.taskQueue.shift();
const workerInfo = this.workerPool.find(w => !w.busy && w.wasmLoaded);
if (workerInfo) {
workerInfo.busy = true;
workerInfo.currentTaskId = task.id;
workerInfo.worker.postMessage({ type: 'PROCESS_TASK', taskId: task.id, task });
return;
}
try {
let result;
const startTime = CONFIG.enablePerformanceMonitoring ? performance.now() : 0;
switch (this.envLayer.mode) {
case 'webgpu+wasm':
result = await this.processWithWebGpu(task);
break;
case 'webgl+wasm':
result = await this.processWithWebGl(task);
break;
case 'cpu+wasm':
result = await this.processWithWasm(task);
break;
default:
result = await this.processWithWasm(task);
}
const endTime = CONFIG.enablePerformanceMonitoring ? performance.now() : 0;
if (CONFIG.enablePerformanceMonitoring) {
this.stats.wasmExecutionTimeMs += (endTime - startTime);
}
const taskPromise = this.activeTasks.get(task.id);
if (taskPromise) {
taskPromise.resolve({ status: 'success', result });
this.activeTasks.delete(task.id);
}
this.stats.tasksProcessed++;
} catch (error) {
Log.error('Collaboration', `任务处理失败: ${task.id}`, error);
const taskPromise = this.activeTasks.get(task.id);
if (taskPromise) {
let standardizedError;
if (error instanceof FrameworkError) {
standardizedError = {
status: 'error',
error: {
message: error.message,
name: error.name,
context: error.context,
timestamp: error.timestamp
}
};
} else {
standardizedError = {
status: 'error',
error: {
message: error.message || '未知错误',
name: error.name || 'Error',
context: { originalError: error.toString() }
}
};
}
taskPromise.reject(standardizedError);
this.activeTasks.delete(task.id);
}
this.stats.errors++;
}
}
async processWithWebGpu(task) {
Log.info('Collaboration', `WebGPU处理任务: ${task.type}`);
await Utils.delay(10);
return { status: 'webgpu_processed', data: task.input };
}
async processWithWebGl(task) {
Log.info('Collaboration', `WebGL处理任务: ${task.type}`);
switch (task.type) {
case 'render':
await Utils.delay(50);
return { status: 'webgl_rendered', input: task.input }; // 修复语法错误
default:
return this.processWithWasm(task);
}
}
async processWithWasm(task) {
if (!this.resourceLayer.wasmModule) {
throw new FrameworkError('Wasm模块未初始化', { taskId: task.id });
}
const wasm = this.resourceLayer.wasmModule.exports;
Log.debug('Collaboration', `Wasm处理任务: ${task.type}`);
const allocAndFillF32 = (data) => {
const allocFn = wasm.__wbindgen_malloc || wasm.wasm_alloc;
if (!allocFn) throw new FrameworkError('Wasm缺少内存分配函数');
const sizeInBytes = data.length * 4;
const ptr = allocFn(sizeInBytes);
if (!ptr) throw new FrameworkError('Wasm内存分配失败');
new Float32Array(wasm.memory.buffer, ptr, data.length).set(data);
if (CONFIG.enablePerformanceMonitoring) {
this.stats.memoryAllocatedBytes += sizeInBytes;
}
return { ptr, size: sizeInBytes, length: data.length };
};
const allocAndFillU8 = (data) => {
const allocFn = wasm.__wbindgen_malloc || wasm.wasm_alloc;
if (!allocFn) throw new FrameworkError('Wasm缺少内存分配函数');
const sizeInBytes = data.length;
const ptr = allocFn(sizeInBytes);
if (!ptr) throw new FrameworkError('Wasm内存分配失败');
new Uint8Array(wasm.memory.buffer, ptr, data.length).set(data);
if (CONFIG.enablePerformanceMonitoring) {
this.stats.memoryAllocatedBytes += sizeInBytes;
}
return { ptr, size: sizeInBytes, length: data.length };
};
const safeFree = (ptr, size = 0) => {
try {
if (wasm.__wbindgen_free) {
wasm.__wbindgen_free(ptr, size);
} else if (wasm.free_memory) {
wasm.free_memory(ptr);
} else {
Log.debug('Wasm', `无法释放内存: ptr=${ptr}, size=${size}`);
}
if (CONFIG.enablePerformanceMonitoring) {
this.stats.memoryAllocatedBytes -= size;
}
} catch (e) {
Log.warn('Wasm', `释放内存时出错: ptr=${ptr}`, e);
}
};
switch (task.type) {
case 'preprocess_particles': {
const { particles, minMass } = task.input;
if (!wasm.preprocess_particles) {
throw new FrameworkError('Wasm缺少preprocess_particles函数', { taskId: task.id });
}
const input = allocAndFillF32(particles);
let resultPtr = 0;
try {
resultPtr = wasm.preprocess_particles(input.ptr, particles.length / 4, minMass);
const processedParticles = window.hyperGpuEngine.ProcessedParticles.__wrap(resultPtr);
const dataView = processedParticles.getData();
const count = processedParticles.len;
return { status: 'particles_processed', dataView, count, isView: true };
} finally {
safeFree(input.ptr, input.size);
}
}
case 'vector_normalize': {
const { vector } = task.input;
let normalizeFn;
if (vector.length === 3 && wasm.normalize_vector) {
normalizeFn = wasm.normalize_vector;
Log.debug('Collaboration', '使用3D专用向量归一化函数');
} else if (wasm.normalize_vector_generic) {
normalizeFn = wasm.normalize_vector_generic;
Log.debug('Collaboration', '使用通用向量归一化函数');
} else if (wasm.normalize_vector) {
normalizeFn = wasm.normalize_vector;
Log.warn('Collaboration', '使用3D向量归一化函数处理非3D向量');
} else {
throw new FrameworkError('Wasm缺少向量归一化函数', { taskId: task.id, vectorLength: vector.length });
}
const input = allocAndFillF32(vector);
try {
if (normalizeFn === wasm.normalize_vector) {
normalizeFn(input.ptr);
} else {
normalizeFn(input.ptr, vector.length);
}
const resultView = new Float32Array(wasm.memory.buffer, input.ptr, input.length);
return { status: 'vector_normalized', resultView, isView: true };
} finally {
safeFree(input.ptr, input.size);
}
}
case 'matrix_multiply_4x4': {
const { a, b } = task.input;
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== 16 || b.length !== 16) {
throw new FrameworkError('matrix_multiply_4x4 输入必须是两个长度为16的数组', { taskId: task.id });
}
const multiplyFn = wasm.multiply_mat4;
if (!multiplyFn) {
throw new FrameworkError('Wasm缺少矩阵乘法函数 (multiply_mat4)', { taskId: task.id });
}
const aMem = allocAndFillF32(a);
const bMem = allocAndFillF32(b);
const cPtr = (wasm.__wbindgen_malloc || wasm.wasm_alloc)(16 * 4);
if (!cPtr) {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
throw new FrameworkError('Wasm内存分配失败 (结果矩阵)');
}
try {
multiplyFn(aMem.ptr, bMem.ptr, cPtr);
const resultView = new Float32Array(wasm.memory.buffer, cPtr, 16);
return { status: 'matrix_multiplied_4x4', resultView, isView: true };
} finally {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
safeFree(cPtr, 16 * 4);
}
}
case 'matrix_multiply_generic': {
const { a, b } = task.input;
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
throw new FrameworkError('matrix_multiply_generic 输入数组长度必须相等', { taskId: task.id });
}
const multiplyFn = wasm.multiply_mat4_generic;
if (!multiplyFn) {
throw new FrameworkError('Wasm缺少通用矩阵乘法函数 (multiply_mat4_generic)', { taskId: task.id });
}
const aMem = allocAndFillF32(a);
const bMem = allocAndFillF32(b);
const cPtr = (wasm.__wbindgen_malloc || wasm.wasm_alloc)(a.length * 4);
if (!cPtr) {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
throw new FrameworkError('Wasm内存分配失败 (结果矩阵)');
}
try {
multiplyFn(aMem.ptr, bMem.ptr, cPtr);
const resultView = new Float32Array(wasm.memory.buffer, cPtr, a.length);
return { status: 'matrix_multiplied_generic', resultView, isView: true };
} finally {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
safeFree(cPtr, a.length * 4);
}
}
case 'super_resolution': {
const { imageData, inWidth, inHeight, outWidth, outHeight } = task.input;
if (inWidth < CONFIG.minSuperResolutionSize || inHeight < CONFIG.minSuperResolutionSize) {
Log.warn('Collaboration', `跳过超分:输入尺寸过小(${inWidth}x${inHeight})`);
return {
status: 'skipped',
reason: 'input_too_small',
imageData,
width: inWidth,
height: inHeight
};
}
if (!wasm.super_resolution_bicubic) {
throw new FrameworkError('Wasm缺少super_resolution_bicubic函数', { taskId: task.id });
}
const input = allocAndFillU8(imageData);
let resultPtr = 0;
try {
resultPtr = wasm.super_resolution_bicubic(input.ptr, inWidth, inHeight, outWidth, outHeight);
const processedImage = window.hyperGpuEngine.ProcessedImage.__wrap(resultPtr);
const outputView = processedImage.getData();
return {
status: 'super_resolution_done',
outputView,
width: outWidth,
height: outHeight,
isView: true
};
} finally {
safeFree(input.ptr, input.size);
}
}
case 'vector_dot': {
const { a, b } = task.input;
if (!wasm.vector_dot) {
throw new FrameworkError('Wasm缺少vector_dot函数', { taskId: task.id });
}
const aMem = allocAndFillF32(a);
const bMem = allocAndFillF32(b);
try {
const result = wasm.vector_dot(aMem.ptr, bMem.ptr, a.length);
return { status: 'vector_dot_done', result };
} finally {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
}
}
case 'vector_cross3': {
const { a, b } = task.input;
if (!wasm.vector_cross_3d) {
throw new FrameworkError('Wasm缺少vector_cross_3d函数', { taskId: task.id });
}
const aMem = allocAndFillF32(a);
const bMem = allocAndFillF32(b);
const resultPtr = (wasm.__wbindgen_malloc || wasm.wasm_alloc)(3 * 4);
if (!resultPtr) {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
throw new FrameworkError('Wasm内存分配失败 (叉积结果)');
}
try {
wasm.vector_cross_3d(aMem.ptr, bMem.ptr, resultPtr);
const resultView = new Float32Array(wasm.memory.buffer, resultPtr, 3);
return { status: 'vector_cross3_done', resultView, isView: true };
} finally {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
safeFree(resultPtr, 3 * 4);
}
}
case 'quadratic_form': {
const { x, A } = task.input;
if (!wasm.quadratic_form) {
throw new FrameworkError('Wasm缺少quadratic_form函数', { taskId: task.id });
}
const xMem = allocAndFillF32(x);
const AMem = allocAndFillF32(A);
try {
const result = wasm.quadratic_form(xMem.ptr, AMem.ptr, x.length);
return { status: 'quadratic_form_done', result };
} finally {
safeFree(xMem.ptr, xMem.size);
safeFree(AMem.ptr, AMem.size);
}
}
case 'determinant_2x2': {
const { matrix } = task.input;
if (!Array.isArray(matrix) || matrix.length !== 4) {
throw new FrameworkError('determinant_2x2 输入必须是长度为4的数组', { taskId: task.id });
}
if (!wasm.matrix_det_2x2) {
throw new FrameworkError('Wasm缺少matrix_det_2x2函数', { taskId: task.id });
}
const matMem = allocAndFillF32(matrix);
try {
const result = wasm.matrix_det_2x2(matMem.ptr);
return { status: 'determinant_2x2_done', result };
} finally {
safeFree(matMem.ptr, matMem.size);
}
}
case 'determinant_3x3': {
const { matrix } = task.input;
if (!Array.isArray(matrix) || matrix.length !== 9) {
throw new FrameworkError('determinant_3x3 输入必须是长度为9的数组', { taskId: task.id });
}
const detFn = wasm.matrix_det_3x3;
if (!detFn) {
throw new FrameworkError('Wasm缺少matrix_det_3x3函数', { taskId: task.id });
}
const matMem = allocAndFillF32(matrix);
try {
const result = detFn(matMem.ptr);
return { status: 'determinant_3x3_done', result };
} finally {
safeFree(matMem.ptr, matMem.size);
}
}
case 'matrix_inv_2x2': {
const { matrix } = task.input;
if (!Array.isArray(matrix) || matrix.length !== 4) {
throw new FrameworkError('matrix_inv_2x2 输入必须是长度为4的数组', { taskId: task.id });
}
const invFn = wasm.matrix_inv_2x2;
if (!invFn) {
throw new FrameworkError('Wasm缺少matrix_inv_2x2函数', { taskId: task.id });
}
const matMem = allocAndFillF32(matrix);
const resultPtr = (wasm.__wbindgen_malloc || wasm.wasm_alloc)(4 * 4);
if (!resultPtr) {
safeFree(matMem.ptr, matMem.size);
throw new FrameworkError('Wasm内存分配失败 (逆矩阵结果)');
}
try {
const success = invFn(matMem.ptr, resultPtr);
if (!success) {
safeFree(resultPtr, 4 * 4);
return { status: 'matrix_inv_2x2_done', success: false, result: null };
}
const resultView = new Float32Array(wasm.memory.buffer, resultPtr, 4);
return { status: 'matrix_inv_2x2_done', success: true, result: resultView, isView: true };
} finally {
safeFree(matMem.ptr, matMem.size);
}
}
case 'matrix_transpose': {
const { matrix, rows, cols } = task.input;
if (!wasm.matrix_transpose) {
throw new FrameworkError('Wasm缺少matrix_transpose函数', { taskId: task.id });
}
const matMem = allocAndFillF32(matrix);
const resultSize = rows * cols * 4;
const resultPtr = (wasm.__wbindgen_malloc || wasm.wasm_alloc)(resultSize);
if (!resultPtr) {
safeFree(matMem.ptr, matMem.size);
throw new FrameworkError('Wasm内存分配失败 (转置矩阵结果)');
}
try {
wasm.matrix_transpose(matMem.ptr, rows, cols, resultPtr);
const resultView = new Float32Array(wasm.memory.buffer, resultPtr, rows * cols);
return { status: 'matrix_transpose_done', resultView, isView: true };
} finally {
safeFree(matMem.ptr, matMem.size);
safeFree(resultPtr, resultSize);
}
}
case 'vector_sub': {
const { a, b } = task.input;
if (!wasm.vector_sub) {
throw new FrameworkError('Wasm缺少vector_sub函数', { taskId: task.id });
}
const aMem = allocAndFillF32(a);
const bMem = allocAndFillF32(b);
const resultPtr = (wasm.__wbindgen_malloc || wasm.wasm_alloc)(a.length * 4);
if (!resultPtr) {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
throw new FrameworkError('Wasm内存分配失败 (向量减法结果)');
}
try {
wasm.vector_sub(aMem.ptr, bMem.ptr, resultPtr, a.length);
const resultView = new Float32Array(wasm.memory.buffer, resultPtr, a.length);
return { status: 'vector_sub_done', resultView, isView: true };
} finally {
safeFree(aMem.ptr, aMem.size);
safeFree(bMem.ptr, bMem.size);
safeFree(resultPtr, a.length * 4);
}
}
case 'vector_scale': {
const { scalar, vector } = task.input;
if (!wasm.vector_scale) {
throw new FrameworkError('Wasm缺少vector_scale函数', { taskId: task.id });
}
const vecMem = allocAndFillF32(vector);
const resultPtr = (wasm.__wbindgen_malloc || wasm.wasm_alloc)(vector.length * 4);
if (!resultPtr) {
safeFree(vecMem.ptr, vecMem.size);
throw new FrameworkError('Wasm内存分配失败 (向量缩放结果)');
}
try {
wasm.vector_scale(scalar, vecMem.ptr, resultPtr, vector.length);
const resultView = new Float32Array(wasm.memory.buffer, resultPtr, vector.length);
return { status: 'vector_scale_done', resultView, isView: true };
} finally {
safeFree(vecMem.ptr, vecMem.size);
safeFree(resultPtr, vector.length * 4);
}
}
case 'enhance_video': {
const { imageData, inWidth, inHeight, outWidth, outHeight } = task.input;
if (!wasm.enhance_video_frame) {
throw new FrameworkError('Wasm缺少enhance_video_frame函数', { taskId: task.id });
}
const input = allocAndFillU8(imageData);
let resultPtr = 0;
try {
resultPtr = wasm.enhance_video_frame(input.ptr, inWidth, inHeight, outWidth, outHeight);
const processedImage = window.hyperGpuEngine.ProcessedImage.__wrap(resultPtr);
const outputView = processedImage.getData();
return {
status: 'video_enhanced',
outputView,
width: outWidth,
height: outHeight,
isView: true
};
} finally {
safeFree(input.ptr, input.size);
}
}
case 'get_wasm_info': {
const info = {};
try {
if (wasm.get_version) {
const versionRet = wasm.get_version();
info.version = Utils.getStringFromWasm(versionRet.ptr, versionRet.len, wasm.memory);
safeFree(versionRet.ptr, versionRet.len);
}
if (wasm.get_description) {
const descRet = wasm.get_description();
info.description = Utils.getStringFromWasm(descRet.ptr, descRet.len, wasm.memory);
safeFree(descRet.ptr, descRet.len);
}
if (wasm.is_wasm) info.isWasm = !!wasm.is_wasm();
if (wasm.get_max_safe_size) info.maxSafeSize = wasm.get_max_safe_size();
} catch (e) {
Log.warn('Collaboration', '获取Wasm元信息时出错', e);
}
return { status: 'wasm_info', data: info };
}
case 'get_description': {
if (!wasm.get_description) {
throw new FrameworkError('Wasm缺少get_description函数', { taskId: task.id });
}
try {
const description = wasm.get_description();
return { status: 'get_description_done', description };
} catch (e) {
Log.warn('Collaboration', '获取Wasm描述信息时出错', e);
throw new FrameworkError('获取Wasm描述信息失败', { taskId: task.id, originalError: e.message });
}
}
case 'get_max_safe_size': {
if (!wasm.get_max_safe_size) {
throw new FrameworkError('Wasm缺少get_max_safe_size函数', { taskId: task.id });
}
try {
const maxSize = wasm.get_max_safe_size();
return { status: 'get_max_safe_size_done', maxSize };
} catch (e) {
Log.warn('Collaboration', '获取Wasm最大安全大小时出错', e);
throw new FrameworkError('获取Wasm最大安全大小失败', { taskId: task.id, originalError: e.message });
}
}
default:
throw new FrameworkError(`不支持的任务类型: ${task.type}`, { taskId: task.id });
}
}
}
// ==================== API层模块 ====================
class APILayer {
constructor(collaborationLayer) {
this.collaborationLayer = collaborationLayer;
}
async init() {
Log.info('API', '开始初始化API层...');
Log.info('API', 'API层初始化完成');
}
preprocessParticles(particles, minMass) {
if (!Array.isArray(particles) || typeof minMass !== 'number') {
return Promise.reject({ status: 'error', error: { message: '参数类型错误' } });
}
return this.collaborationLayer.submitTask({
type: 'preprocess_particles',
input: { particles, minMass }
}, 5);
}
normalizeVector(vector) {
if (!Array.isArray(vector)) {
return Promise.reject({ status: 'error', error: { message: '输入必须是数组' } });
}
return this.collaborationLayer.submitTask({
type: 'vector_normalize',
input: { vector }
}, 5);
}
multiplyMat4(a, b) {
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== 16 || b.length !== 16) {
return Promise.reject({ status: 'error', error: { message: '输入必须是两个长度为16的数组 (4x4矩阵)' } });
}
return this.collaborationLayer.submitTask({
type: 'matrix_multiply_4x4',
input: { a, b }
}, 5);
}
multiplyMat4Generic(a, b) {
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
return Promise.reject({ status: 'error', error: { message: '输入必须是两个长度相等的数组' } });
}
return this.collaborationLayer.submitTask({
type: 'matrix_multiply_generic',
input: { a, b }
}, 5);
}
simulatePhysics(particles, deltaTime, gravity) {
return this.preprocessParticles(particles, 0.1);
}
superResolutionBicubic(imageData, inWidth, inHeight, scale = 2) {
if (!(imageData instanceof Uint8ClampedArray)) {
return Promise.reject({ status: 'error', error: { message: '输入必须是Uint8ClampedArray' } });
}
const outWidth = inWidth * scale;
const outHeight = inHeight * scale;
return this.collaborationLayer.submitTask({
type: 'super_resolution',
input: { imageData, inWidth, inHeight, outWidth, outHeight }
}, 5);
}
vectorDot(a, b) {
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
return Promise.reject({ status: 'error', error: { message: '输入必须是相同长度的数组' } });
}
return this.collaborationLayer.submitTask({
type: 'vector_dot',
input: { a, b }
}, 5);
}
vectorCross3(a, b) {
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== 3 || b.length !== 3) {
return Promise.reject({ status: 'error', error: { message: '输入必须是长度为3的数组' } });
}
return this.collaborationLayer.submitTask({
type: 'vector_cross3',
input: { a, b }
}, 5);
}
quadraticForm(x, A) {
if (!Array.isArray(x) || !Array.isArray(A) || A.length !== x.length * x.length) {
return Promise.reject({ status: 'error', error: { message: '输入维度不匹配' } });
}
return this.collaborationLayer.submitTask({
type: 'quadratic_form',
input: { x, A }
}, 5);
}
determinant2x2(matrix) {
if (!Array.isArray(matrix) || matrix.length !== 4) {
return Promise.reject({ status: 'error', error: { message: '输入必须是长度为4的数组' } });
}
return this.collaborationLayer.submitTask({
type: 'determinant_2x2',
input: { matrix }
}, 5);
}
determinant3x3(matrix) {
if (!Array.isArray(matrix) || matrix.length !== 9) {
return Promise.reject({ status: 'error', error: { message: '输入必须是长度为9的数组 (3x3矩阵)' } });
}
return this.collaborationLayer.submitTask({
type: 'determinant_3x3',
input: { matrix }
}, 5);
}
matrixInv2x2(matrix) {
if (!Array.isArray(matrix) || matrix.length !== 4) {
return Promise.reject({ status: 'error', error: { message: '输入必须是长度为4的数组 (2x2矩阵)' } });
}
return this.collaborationLayer.submitTask({
type: 'matrix_inv_2x2',
input: { matrix }
}, 5);
}
matrixTranspose(matrix, rows, cols) {
if (!Array.isArray(matrix) || matrix.length !== rows * cols) {
return Promise.reject({ status: 'error', error: { message: '输入矩阵维度不匹配' } });
}
return this.collaborationLayer.submitTask({
type: 'matrix_transpose',
input: { matrix, rows, cols }
}, 5);
}
vectorSub(a, b) {
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
return Promise.reject({ status: 'error', error: { message: '输入必须是相同长度的数组' } });
}
return this.collaborationLayer.submitTask({
type: 'vector_sub',
input: { a, b }
}, 5);
}
vectorScale(scalar, vector) {
if (typeof scalar !== 'number' || !Array.isArray(vector)) {
return Promise.reject({ status: 'error', error: { message: '参数类型错误' } });
}
return this.collaborationLayer.submitTask({
type: 'vector_scale',
input: { scalar, vector }
}, 5);
}
enhanceVideoFrame(imageData, inWidth, inHeight, outWidth, outHeight) {
if (!(imageData instanceof Uint8ClampedArray)) {
return Promise.reject({ status: 'error', error: { message: '输入必须是Uint8ClampedArray' } });
}
return this.collaborationLayer.submitTask({
type: 'enhance_video',
input: { imageData, inWidth, inHeight, outWidth, outHeight }
}, 5);
}
getWasmInfo() {
return this.collaborationLayer.submitTask({
type: 'get_wasm_info',
input: {}
}, 1);
}
getDescription() {
return this.collaborationLayer.submitTask({
type: 'get_description',
input: {}
}, 1);
}
getMaxSafeSize() {
return this.collaborationLayer.submitTask({
type: 'get_max_safe_size',
input: {}
}, 1);
}
}
// ==================== Wasm数据结构类 ====================
class ProcessedImage {
static __wrap(ptr) {
ptr = ptr >>> 0;
const obj = Object.create(ProcessedImage.prototype);
obj.__wbg_ptr = ptr;
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (wasmExports && CONFIG.enableFinalizationRegistry && typeof FinalizationRegistry !== 'undefined') {
const finalization = new FinalizationRegistry(heldValue => {
if (wasmExports.__wbg_processedimage_free) {
try {
wasmExports.__wbg_processedimage_free(heldValue, 1);
Log.debug('ProcessedImage', `Finalizer自动释放内存: ptr=${heldValue}`);
} catch (e) {
Log.warn('ProcessedImage', `Finalizer释放内存失败: ptr=${heldValue}`, e);
}
}
});
finalization.register(obj, obj.__wbg_ptr, obj);
obj.__finalizer = finalization;
} else if (!CONFIG.enableFinalizationRegistry || typeof FinalizationRegistry === 'undefined') {
Log.debug('ProcessedImage', `FinalizationRegistry已禁用或不支持,为ptr=${ptr}的对象创建实例`);
}
return obj;
}
__destroy_into_raw() {
const ptr = this.__wbg_ptr;
this.__wbg_ptr = 0;
if (this.__finalizer) {
this.__finalizer.unregister(this);
this.__finalizer = null;
}
return ptr;
}
free() {
const ptr = this.__destroy_into_raw();
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (wasmExports?.__wbg_processedimage_free) {
try {
wasmExports.__wbg_processedimage_free(ptr, 0);
Log.debug('ProcessedImage', `手动释放内存: ptr=${ptr}`);
} catch (e) {
Log.error('ProcessedImage', `手动释放内存失败: ptr=${ptr}`, e);
}
}
}
get ptr() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
const ret = wasmExports.processedimage_ptr(this.__wbg_ptr);
return ret;
}
get len() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
const ret = wasmExports.processedimage_len(this.__wbg_ptr);
return ret >>> 0;
}
getData() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
return new Uint8ClampedArray(wasmExports.memory.buffer, this.ptr, this.len);
}
is_empty() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
const ret = wasmExports.processedimage_is_empty(this.__wbg_ptr);
return ret !== 0;
}
}
class ProcessedParticles {
static __wrap(ptr) {
ptr = ptr >>> 0;
const obj = Object.create(ProcessedParticles.prototype);
obj.__wbg_ptr = ptr;
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (wasmExports && CONFIG.enableFinalizationRegistry && typeof FinalizationRegistry !== 'undefined') {
const finalization = new FinalizationRegistry(heldValue => {
if (wasmExports.__wbg_processedparticles_free) {
try {
wasmExports.__wbg_processedparticles_free(heldValue, 1);
Log.debug('ProcessedParticles', `Finalizer自动释放内存: ptr=${heldValue}`);
} catch (e) {
Log.warn('ProcessedParticles', `Finalizer释放内存失败: ptr=${heldValue}`, e);
}
}
});
finalization.register(obj, obj.__wbg_ptr, obj);
obj.__finalizer = finalization;
} else if (!CONFIG.enableFinalizationRegistry || typeof FinalizationRegistry === 'undefined') {
Log.debug('ProcessedParticles', `FinalizationRegistry已禁用或不支持,为ptr=${ptr}的对象创建实例`);
}
return obj;
}
__destroy_into_raw() {
const ptr = this.__wbg_ptr;
this.__wbg_ptr = 0;
if (this.__finalizer) {
this.__finalizer.unregister(this);
this.__finalizer = null;
}
return ptr;
}
free() {
const ptr = this.__destroy_into_raw();
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (wasmExports?.__wbg_processedparticles_free) {
try {
wasmExports.__wbg_processedparticles_free(ptr, 0);
Log.debug('ProcessedParticles', `手动释放内存: ptr=${ptr}`);
} catch (e) {
Log.error('ProcessedParticles', `手动释放内存失败: ptr=${ptr}`, e);
}
}
}
get ptr() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
const ret = wasmExports.processedparticles_ptr(this.__wbg_ptr);
return ret;
}
get len() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
const ret = wasmExports.processedparticles_len(this.__wbg_ptr);
return ret >>> 0;
}
getData() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
return new Float32Array(wasmExports.memory.buffer, this.ptr, this.len * 7);
}
is_empty() {
const wasmExports = window.hyperGpuEngine?.wasmModule?.exports;
if (!wasmExports) throw new Error("Wasm module not available");
const ret = wasmExports.processedparticles_is_empty(this.__wbg_ptr);
return ret !== 0;
}
}
// ==================== 主框架 ====================
class WebGPUWasmFramework {
constructor() {
this.envLayer = null;
this.resourceLayer = null;
this.collaborationLayer = null;
this.apiLayer = null;
this.stateManager = StateManager.getInstance();
this.init();
}
async init() {
try {
this.envLayer = new EnvironmentLayer();
this.envLayer.adaptEnvironment();
this.resourceLayer = new ResourceLayer(this.envLayer);
this.collaborationLayer = new CollaborationLayer(this.envLayer, this.resourceLayer);
this.apiLayer = new APILayer(this.collaborationLayer);
await this.resourceLayer.init();
await this.collaborationLayer.init();
await this.apiLayer.init();
this.exposeGlobalAPI();
Log.info('Framework', 'HyperGPU引擎 (迭代5 - Wasm导入修复) 初始化完成');
} catch (error) {
Log.error('Framework', 'HyperGPU引擎初始化失败', error);
this.stateManager.destroy();
}
}
exposeGlobalAPI() {
window.hyperGpuEngine = {
// API方法
preprocessParticles: (particles, minMass) => this.apiLayer.preprocessParticles(particles, minMass),
normalizeVector: (vector) => this.apiLayer.normalizeVector(vector),
multiplyMat4: (a, b) => this.apiLayer.multiplyMat4(a, b),
multiplyMat4Generic: (a, b) => this.apiLayer.multiplyMat4Generic(a, b),
simulatePhysics: (particles, deltaTime, gravity) => this.apiLayer.simulatePhysics(particles, deltaTime, gravity),
superResolutionBicubic: (imageData, inWidth, inHeight, scale) => this.apiLayer.superResolutionBicubic(imageData, inWidth, inHeight, scale),
vectorDot: (a, b) => this.apiLayer.vectorDot(a, b),
vectorCross3: (a, b) => this.apiLayer.vectorCross3(a, b),
quadraticForm: (x, A) => this.apiLayer.quadraticForm(x, A),
determinant2x2: (matrix) => this.apiLayer.determinant2x2(matrix),
determinant3x3: (matrix) => this.apiLayer.determinant3x3(matrix),
matrixInv2x2: (matrix) => this.apiLayer.matrixInv2x2(matrix),
matrixTranspose: (matrix, rows, cols) => this.apiLayer.matrixTranspose(matrix, rows, cols),
vectorSub: (a, b) => this.apiLayer.vectorSub(a, b),
vectorScale: (scalar, vector) => this.apiLayer.vectorScale(scalar, vector),
enhanceVideoFrame: (imageData, inWidth, inHeight, outWidth, outHeight) => this.apiLayer.enhanceVideoFrame(imageData, inWidth, inHeight, outWidth, outHeight),
getWasmInfo: () => this.apiLayer.getWasmInfo(),
getDescription: () => this.apiLayer.getDescription(),
getMaxSafeSize: () => this.apiLayer.getMaxSafeSize(),
// 状态和配置
getMode: function() { return this.envLayer.mode; }, // 修复 getMode 语法错误
getEnvironment: () => ({ ...this.envLayer.report }),
getStats: () => {
const baseStats = {
tasksProcessed: this.collaborationLayer.stats.tasksProcessed,
errors: this.collaborationLayer.stats.errors,
taskQueueLength: this.collaborationLayer.taskQueue.length,
workerPoolSize: this.collaborationLayer.workerPool.length,
activeWorkers: this.collaborationLayer.workerPool.filter(w => w.busy).length,
workersWasmLoaded: this.collaborationLayer.workerPool.filter(w => w.wasmLoaded).length
};
if (CONFIG.enablePerformanceMonitoring) {
baseStats.wasmExecutionTimeMs = this.collaborationLayer.stats.wasmExecutionTimeMs;
baseStats.memoryAllocatedBytes = this.collaborationLayer.stats.memoryAllocatedBytes;
baseStats.tasksByType = { ...this.collaborationLayer.stats.tasksByType };
}
return baseStats;
},
destroy: () => this.stateManager.destroy(),
setLogLevel: (level) => {
CONFIG.logLevel = level;
GM_setValue('hyperGpuLogLevel', level);
Log.info('Framework', `日志级别已设置为: ${level}`);
},
setPerformanceMonitoring: (enabled) => {
const isEnabled = !!enabled;
CONFIG.enablePerformanceMonitoring = isEnabled ? 1 : 0;
GM_setValue('hyperGpuPerfMon', CONFIG.enablePerformanceMonitoring);
Log.info('Framework', `性能监控已${isEnabled ? '启用' : '禁用'}`);
if (!isEnabled) {
this.collaborationLayer.stats.wasmExecutionTimeMs = 0;
this.collaborationLayer.stats.memoryAllocatedBytes = 0;
this.collaborationLayer.stats.tasksByType = {};
}
},
setFinalizationRegistry: (enabled) => {
const isEnabled = !!enabled && this.envLayer.report.finalizationRegistry;
if (!this.envLayer.report.finalizationRegistry) {
Log.warn('Framework', '浏览器不支持FinalizationRegistry,无法启用');
return;
}
CONFIG.enableFinalizationRegistry = isEnabled ? 1 : 0;
GM_setValue('hyperGpuFinReg', CONFIG.enableFinalizationRegistry);
Log.info('Framework', `FinalizationRegistry已${isEnabled ? '启用' : '禁用'}`);
},
version: '1.6.1',
wasmModule: this.resourceLayer.wasmModule,
ProcessedImage: ProcessedImage,
ProcessedParticles: ProcessedParticles
};
window.dispatchEvent(new CustomEvent('hyperGpuEngineReady', { detail: window.hyperGpuEngine }));
}
}
// ==================== 启动框架 ====================
new WebGPUWasmFramework();
})();