From b2e4fb8a8a93d6002b9b5e5b5614922f50463e1e Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Mon, 25 Mar 2024 01:36:56 +0800 Subject: [PATCH] save --- public/vcd.css | 108 ----- src/components/render/index.vue | 112 ++++- src/hook/global.js | 6 - src/hook/render.js | 7 - src/hook/wave-view/dom-container.js | 38 +- src/hook/wave-view/gen-render-waves-gl.js | 502 +++++++++++---------- src/hook/wave-view/plugin-render-values.js | 18 +- src/hook/wave-view/render-cursor.js | 2 + src/hook/wave-view/render-values.js | 199 ++++---- 9 files changed, 487 insertions(+), 505 deletions(-) diff --git a/public/vcd.css b/public/vcd.css index 5e12dc9..2fbc8d9 100644 --- a/public/vcd.css +++ b/public/vcd.css @@ -90,112 +90,4 @@ body::-webkit-scrollbar { a { color: var(--main-color); -} - -.vcd-container { - --right-panel-width: 0px; - width: calc(100% - var(--right-panel-width)); - transition: width .3s ease-out; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.vcd-vline { - position: absolute; -} - -.vcd-view { - position: absolute; - top: 24px; - bottom: 24px; -} - -.vcd-values { - position: absolute; - top: 24px; - bottom: 24px; -} - -.wd-waveql { - position: absolute; - top: 24px; - bottom: 24px; - width: 100%; - transition: width .3s ease-out; -} - -.vcd-cursor { - position: absolute; - pointer-events: none; -} - -.vcd-values text { - font-size: 14px; - text-anchor: middle; - fill: #fff; -} - - -line.wd-cursor-line { - stroke-dasharray: 12 4; - stroke: var(--main-color); - stroke-width: 1px; -} - -line.wd-grid-time { - stroke: #333; - stroke-width: 1px; -} - -line.gap { - stroke: #fff; - stroke-dasharray: 4 3; -} - -text.wd-grid-time { - text-anchor: middle; - fill: var(--sidebar-item-text); -} - - -text.wd-cursor-time { - font-size: 20px; - fill: var(--sidebar); - text-anchor: middle; - z-index: 55; -} - -rect.wd-cursor-time { - fill: var(--main-color); -} - - -.wd-progress { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - -text.xred { - fill: hsl(0, 100%, 50%); -} - -text.zxviolet { - fill: hsl(287, 100%, 67%); -} - -text.pc { - text-anchor: start; -} - -tspan.pc-addr { - fill: hsl(202 100% 71%); -} - -tspan.pc-opcode { - } \ No newline at end of file diff --git a/src/components/render/index.vue b/src/components/render/index.vue index fea2f18..1f58066 100644 --- a/src/components/render/index.vue +++ b/src/components/render/index.vue @@ -1,10 +1,8 @@ @@ -23,10 +21,8 @@ export default { // TimeScale }, setup() { - const cursorX = ref(0); return { - cursorX, globalLookup } } @@ -43,8 +39,108 @@ export default { transition: .3s ease-out; } -.render-canvas { - +.vcd-container { + --right-panel-width: 0px; + width: calc(100% - var(--right-panel-width)); + transition: width .3s ease-out; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.vcd-vline { + position: absolute; +} + +.vcd-view { + position: absolute; + top: 24px; + bottom: 24px; +} + +.vcd-values { + position: absolute; + top: 24px; + bottom: 24px; +} + +.wd-waveql { + position: absolute; + top: 24px; + bottom: 24px; + width: 100%; + transition: width .3s ease-out; +} + +.vcd-cursor { + position: absolute; + pointer-events: none; +} + +.vcd-values text { + font-size: 14px; + text-anchor: middle; + fill: #fff; +} + + +line.wd-cursor-line { + stroke-dasharray: 12 4; + stroke: var(--main-color); + stroke-width: 1px; +} + +line.wd-grid-time { + stroke: #333; + stroke-width: 1px; +} + +line.gap { + stroke: #fff; + stroke-dasharray: 4 3; +} + +text.wd-grid-time { + text-anchor: middle; + fill: var(--sidebar-item-text); +} + + +text.wd-cursor-time { + font-size: 20px; + fill: var(--sidebar); + text-anchor: middle; + z-index: 55; +} + +rect.wd-cursor-time { + fill: var(--main-color); +} + + +.wd-progress { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +text.xred { + fill: hsl(0, 100%, 50%); +} + +text.zxviolet { + fill: hsl(287, 100%, 67%); +} + +text.pc { + text-anchor: start; +} + +tspan.pc-addr { + fill: hsl(202 100% 71%); } \ No newline at end of file diff --git a/src/hook/global.js b/src/hook/global.js index 5819d13..e983e39 100644 --- a/src/hook/global.js +++ b/src/hook/global.js @@ -33,12 +33,6 @@ const globalLookup = reactive({ // 初始化时会被定义 render: () => {}, - hasHistory: false, - isRO: false, - - // 当前展示的波形 - view: [], - xScale: 1, // // 当前视图的左上角的坐标 diff --git a/src/hook/render.js b/src/hook/render.js index f88bf14..65f3d98 100644 --- a/src/hook/render.js +++ b/src/hook/render.js @@ -274,8 +274,6 @@ function makeWaveView(parentElement) { parentElement.appendChild(container.pstate.container); container.start(globalLookup); - globalLookup.hasHistory = true; - globalLookup.isRO = true; globalLookup.updater = () => { console.log('updater'); }; @@ -311,14 +309,9 @@ function makeWaveView(parentElement) { function toggleRender(signal) { if (globalLookup.currentWires.has(signal)) { globalLookup.currentWires.delete(signal); - // removeWaveCanvas(signal); globalLookup.render(); } else { - // makeWaveSvg(signal); - const lane = { ref: signal.link }; - globalLookup.currentWires.add(signal); - globalLookup.view.push(lane); globalLookup.render(); } } diff --git a/src/hook/wave-view/dom-container.js b/src/hook/wave-view/dom-container.js index a29836e..68ce663 100644 --- a/src/hook/wave-view/dom-container.js +++ b/src/hook/wave-view/dom-container.js @@ -1,6 +1,4 @@ -'use strict'; - -const genRenderWavesGL = require('./gen-render-waves-gl.js'); +const WebGL2WaveRender = require('./gen-render-waves-gl.js'); const renderCursor = require('./render-cursor.js'); const genResizeHandler = require('./gen-resize-handler.js'); const mTree = require('./mount-tree.js'); @@ -50,19 +48,6 @@ const getFullView = desc => { } console.error(ero); throw new Error(); - // Object.keys(obj).map(name => { - // const ref = obj[name]; - // if (typeof ref === 'object') { - // arr.push(name); - // rec(ref); - // arr.push('..'); - // return; - // } - // if (typeof ref !== 'string') { - // throw new Error(); - // } - // arr.push(name); - // }); }; rec(desc.wires); @@ -111,12 +96,12 @@ class DomContainer { const domContainer = (obj) => { - const sidebarWidth = 256; - const fontHeight = 16; + const sidebarWidth = 280; + const fontHeight = 20; const elo = mTree.createElemento(obj.elemento); const container = mTree.createContainer(elo, obj.layers); - elo.container.tabIndex = '0'; + // elo.container.tabIndex = '0'; const pstate = { fontHeight, @@ -127,9 +112,9 @@ const domContainer = (obj) => { topBarHeight: fontHeight * 1.5, // [px] botBarHeight: fontHeight * 1.5, // [px] xOffset: sidebarWidth, - yOffset: 0, // [px] - yStep: fontHeight * 1.5, // = 24 // [px] wave lane height - yDuty: 0.7, + yOffset: -40, // [px] + yStep: 54, // = 24 // [px] wave lane height + yDuty: 0.6, sidebarWidth, container }; @@ -150,7 +135,7 @@ const domContainer = (obj) => { tgcd: deso.tgcd, timescale: deso.timescale, xScale: deso.xScale || 8, - numLanes: deso.view.length, + numLanes: deso.currentWires.size, t0: deso.t0, time: deso.time }); @@ -169,15 +154,12 @@ const domContainer = (obj) => { setTime(pstate, deso.timeOpt.value); } - let render2 = genRenderWavesGL(elo); - let render1 = render2(deso); - let render = render1(pstate, obj.renderPlugins); - deso.render = render; + let waveRender = new WebGL2WaveRender(elo, deso, pstate, obj.renderPlugins); + deso.render = waveRender.render.bind(waveRender); const resizeHandler = genResizeHandler(pstate); const resizeObserver = new ResizeObserver(entries => { - for (let entry of entries) { // TODO : 使用更新的属性替换 contentRect // 未来版本 contentRect 可能会被丢弃 diff --git a/src/hook/wave-view/gen-render-waves-gl.js b/src/hook/wave-view/gen-render-waves-gl.js index 701ef98..d47b4e0 100644 --- a/src/hook/wave-view/gen-render-waves-gl.js +++ b/src/hook/wave-view/gen-render-waves-gl.js @@ -4,8 +4,8 @@ const cColors = new Float32Array([ 0, 0, 0, 0, // 0: 0, 0, 1, 1, // 1: (Z) high impedance - 0, 1, 0, 1, // 2: strong 0 - 0, 1, 1, 1, // 3: strong 1 + 0.2, 0.847, 0.1, 1, // 2: strong 0 + 0.2, 0.847, 0.1, 1, // 3: strong 1 1, 0, 0, 1, // 4: (x X) strong unknown .5, 1, 1, 1, // 5: vec @@ -69,39 +69,6 @@ void main() { `); -/** - * - * @param {WebGL2RenderingContext} webgl2 - * @returns {{ - * colors: WebGLUniformLocation, - * tilts: WebGLUniformLocation, - * scale: WebGLUniformLocation, - * offset: WebGLUniformLocation, - * tilt: WebGLUniformLocation, - * pos: number, - * webgl2: WebGL2RenderingContext - * }} - */ -function initProgram(webgl2) { - const program = webgl2.createProgram(); - webgl2.attachShader(program, vertexShaderScalar(webgl2)); - webgl2.attachShader(program, fragmentShader(webgl2)); - webgl2.linkProgram(program); - webgl2.useProgram(program); - - const webglLocation = { - colors: webgl2.getUniformLocation(program, 'colors'), - tilts: webgl2.getUniformLocation(program, 'tilts'), - scale: webgl2.getUniformLocation(program, 'scale'), - offset: webgl2.getUniformLocation(program, 'offset'), - tilt: webgl2.getUniformLocation(program, 'tilt'), - pos: webgl2.getAttribLocation(program, 'pos'), - webgl2 - }; - - return webglLocation; -} - const bar = [ (f, t, a, b, c0, c1) => [].concat( // 0 (f === 1) ? [a, 2, c1] : [], @@ -153,206 +120,6 @@ const brick = [ ) ]; -const wave2vertex = globalLookup => { - Object.keys(globalLookup.chango).map(ref => { - - const chang = globalLookup.chango[ref]; - const { kind, wave } = chang; - - // globalLookup.view.map(lane => { - // if (!lane || lane.ref === undefined) { return; } - // const chang = globalLookup.chango[lane.ref]; - // if (chang === undefined) { return; } - // const {kind, wave} = chang; - // lane.kind = kind; - // lane.wave = wave; - - if (kind === 'bit') { - const vertices = []; - const ilen = wave.length; - for (let i = 0; i < ilen; i++) { - const f = wave[(i === 0) ? 0 : (i - 1)]; - const [tim, val] = wave[i]; - const t = wave[(i === (ilen - 1)) ? i : (i + 1)]; - const tt = (i === (ilen - 1)) ? globalLookup.time : wave[i + 1][0]; - - switch (val) { - case 0: case 1: // 0 1 - vertices.push(...bar[val](f[1], t[1], tim, tt, 2, 3)); - break; - case 2: case 3: // x X - vertices.push(...bar[2](f[1], t[1], tim, tt, 4, 4)); - break; - case 4: case 5: // z Z - vertices.push(...bar[2](f[1], t[1], tim, tt, 1, 1)); - break; - case 6: case 7: // u U uninitialized - vertices.push(...bar[2](f[1], t[1], tim, tt, 6, 6)); - break; - case 8: case 9: // w W weak unknown - vertices.push(...bar[2](f[1], t[1], tim, tt, 10, 10)); - break; - case 10: case 11: // l L - vertices.push(...bar[0](f[1], t[1], tim, tt, 8, 9)); - break; - case 12: case 13: // h H - vertices.push(...bar[1](f[1], t[1], tim, tt, 8, 9)); - break; - default: - vertices.push(...bar[2](f[1], t[1], tim, tt, 7, 7)); - // throw new Error('val is: ' + val); - } - } - - chang.vertices = new Uint32Array(vertices); // Uint16Array // 16bit - - // lane.vertices = new Uint16Array(vertices); - - } - if (kind === 'vec') { - const vertices = []; - const ilen = wave.length; - for (let i = 0; i < ilen; i++) { - // const f = wave[(i === 0) ? 0 : (i - 1)]; - const [tim, val, msk] = wave[i]; - // const t = wave[(i === (ilen - 1)) ? i : (i + 1)]; - const tt = (i === (ilen - 1)) ? globalLookup.time : wave[i + 1][0]; - - if (val) { - if (msk) { - vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x,z? - } else { - // vertices.push(...brick[2](2, 2, tim, tt, 5, 5)); // 2 - vertices.push( - tim, 0, 0, - tt, 0, 0, tt, 0, 5, tt, 4, 5, - tim, 6, 5, tim, 0, 5, tim, 3, 5, - tt, 1, 5, tt, 0, 5 - ); - } - } else { - if (msk) { - vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x - } else { - // vertices.push(...brick[0](2, 2, tim, tt, 2, 3)); // 0 - vertices.push(tim, 6, 2, tt, 4, 2); - } - } - } - - chang.vertices = new Uint32Array(vertices); // Uint16Array // 16bit - - // lane.vertices = new Uint16Array(vertices); - - } - }); -}; - -/** - * - * @param {{ - * colors: WebGLUniformLocation, - * tilts: WebGLUniformLocation, - * scale: WebGLUniformLocation, - * offset: WebGLUniformLocation, - * tilt: WebGLUniformLocation, - * pos: number, - * webgl2: WebGL2RenderingContext - * }} webglLocation - * @param {{ - * chango: Record, - * vao: WebGLVertexArrayObject - * }> - * }} globalLookup - */ -function initData(webglLocation, globalLookup) { - for (const id of Reflect.ownKeys(globalLookup.chango)) { - const signalItem = globalLookup.chango[id]; - const vertices = signalItem.vertices; - - const webgl2 = webglLocation.webgl2; - const vertexBuffer = webgl2.createBuffer(); - webgl2.bindBuffer(webgl2.ARRAY_BUFFER, vertexBuffer); - // 将初始化的顶点数据复制到 buffer 区域 - webgl2.bufferData(webgl2.ARRAY_BUFFER, vertices, webgl2.STATIC_DRAW); - - signalItem.vao = webgl2.createVertexArray(); - webgl2.bindVertexArray(signalItem.vao); - webgl2.vertexAttribIPointer(webglLocation.pos, 3, webgl2.UNSIGNED_INT, 0, 0); - webgl2.enableVertexAttribArray(webglLocation.pos); - webgl2.uniform4fv(webglLocation.colors, cColors); - webgl2.uniform2fv(webglLocation.tilts, cTilts); - } -} - -const genRenderWavesGL = (els) => { - const canvas = document.createElement('canvas'); - els.view.replaceChildren(canvas); - - const webgl2 = canvas.getContext('webgl2', { - premultipliedAlpha: false, - alpha: true, - antialias: false, - depth: false - }); - const webglLocation = initProgram(webgl2); - - return globalLookup => { - wave2vertex(globalLookup); - initData(webglLocation, globalLookup); - return (pstate, plugins) => { - let aReq; - return () => { - if (aReq !== undefined) { - cancelAnimationFrame(aReq); - } - aReq = window.requestAnimationFrame(() => { - const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = pstate; - const cHeight = height - 40; // FIXME 40 - // console.log(pstate); - canvas.width = width; - canvas.height = cHeight; - // const xs = pstate.scale; - // const xo = -1; - webgl2.uniform1f(webglLocation.tilt, 3 / width); - webgl2.uniform2f(webglLocation.scale, 2 * xScale / width, yStep * yDuty / cHeight); // FIXME 40 - webgl2.viewport(0, 0, width, cHeight); - webgl2.clear(webgl2.COLOR_BUFFER_BIT); - globalLookup.view.map((lane, idx) => { - // console.log(lane, idx); - if (!lane) { // || lane.vertices === undefined) { - return; - } - const ref = lane.ref; - if (ref === undefined) { - return; - } - const chang = globalLookup.chango[ref]; - if (chang === undefined) { - return; - } - // console.log(chang); - webgl2.bindVertexArray(chang.vao); - webgl2.uniform2f(webglLocation.offset, - (2 * xOffset / width) - 1, - (2 * yOffset - 2 * yStep * (idx + .7)) / cHeight + 1 - ); - webgl2.drawArrays( - webgl2.LINE_STRIP, // mode - 0, // first - chang.vertices.length / 3 // count - ); - }); - plugins.map(fn => fn(globalLookup, pstate, els)); - aReq = undefined; - }); - }; - }; - }; -}; class WebGL2WaveRender { /** @@ -361,15 +128,268 @@ class WebGL2WaveRender { * grid: HTMLDivElement, * view: HTMLDivElement, * values: HTMLDivElement - * }}} elements + * }} elements + * @param {{ + * chango: Record, + * vao: WebGLVertexArrayObject + * }> + * view: Array<{ ref: string }>, + * currentWires: Set<{ + * kind: string, + * link: string, + * name: string, + * size: number, + * parent: object, + * type: string + * }>, + * time: number + * }} globalLookup + * @param {{ + * width: number, + * height: number, + * xScale: number, + * xOffset: number, + * yOffset: number, + * yStep: number, + * yDuty: number + * }} pstate + * @param { Array } plugins */ - constructor(elements) { + constructor(elements, globalLookup, pstate, plugins) { const canvas = document.createElement('canvas'); + elements.view.replaceChildren(canvas); + + this.elements = elements; + this.globalLookup = globalLookup; + this.canvas = canvas; + this.pstate = pstate; + this.plugins = plugins; + + const webgl2 = canvas.getContext('webgl2', { + premultipliedAlpha: false, + alpha: true, + antialias: false, + depth: false + }); + this.webglLocation = this.initProgram(webgl2); + this.verticesMap = this.makeVertex(); + this.initData(); + + this.animationHandler = undefined; + } + + /** + * + * @param {WebGL2RenderingContext} webgl2 + * @returns {{ + * colors: WebGLUniformLocation, + * tilts: WebGLUniformLocation, + * scale: WebGLUniformLocation, + * offset: WebGLUniformLocation, + * tilt: WebGLUniformLocation, + * pos: number, + * webgl2: WebGL2RenderingContext + * }} + */ + initProgram(webgl2) { + const program = webgl2.createProgram(); + webgl2.attachShader(program, vertexShaderScalar(webgl2)); + webgl2.attachShader(program, fragmentShader(webgl2)); + webgl2.linkProgram(program); + webgl2.useProgram(program); + + const webglLocation = { + colors: webgl2.getUniformLocation(program, 'colors'), + tilts: webgl2.getUniformLocation(program, 'tilts'), + scale: webgl2.getUniformLocation(program, 'scale'), + offset: webgl2.getUniformLocation(program, 'offset'), + tilt: webgl2.getUniformLocation(program, 'tilt'), + pos: webgl2.getAttribLocation(program, 'pos'), + webgl2 + }; + + return webglLocation; + } + + /** + * + * @returns {Map} + */ + makeVertex() { + const globalLookup = this.globalLookup; + const time = globalLookup.time; + const verticesMap = new Map(); + for (const id of Reflect.ownKeys(globalLookup.chango)) { + const signalItem = globalLookup.chango[id]; + const { kind, wave } = signalItem; + if (kind === 'bit') { + const vertices = this.makeBitVertex(wave, time); + verticesMap.set(id, vertices); + } else if (kind === 'vec') { + const vertices = this.makeVecVertex(wave, time); + verticesMap.set(id, vertices); + } + } + return verticesMap; + } + + /** + * + * @param {Array} wave + * @param { number } time + * @returns {Uint32Array} + */ + makeBitVertex(wave, time) { + const vertices = []; + const ilen = wave.length; + for (let i = 0; i < ilen; i++) { + const f = wave[(i === 0) ? 0 : (i - 1)]; + const [tim, val] = wave[i]; + const t = wave[(i === (ilen - 1)) ? i : (i + 1)]; + const tt = (i === (ilen - 1)) ? time : wave[i + 1][0]; + switch (val) { + case 0: case 1: // 0 1 + vertices.push(...bar[val](f[1], t[1], tim, tt, 2, 3)); + break; + case 2: case 3: // x X + vertices.push(...bar[2](f[1], t[1], tim, tt, 4, 4)); + break; + case 4: case 5: // z Z + vertices.push(...bar[2](f[1], t[1], tim, tt, 1, 1)); + break; + case 6: case 7: // u U uninitialized + vertices.push(...bar[2](f[1], t[1], tim, tt, 6, 6)); + break; + case 8: case 9: // w W weak unknown + vertices.push(...bar[2](f[1], t[1], tim, tt, 10, 10)); + break; + case 10: case 11: // l L + vertices.push(...bar[0](f[1], t[1], tim, tt, 8, 9)); + break; + case 12: case 13: // h H + vertices.push(...bar[1](f[1], t[1], tim, tt, 8, 9)); + break; + default: + vertices.push(...bar[2](f[1], t[1], tim, tt, 7, 7)); + } + } + + return new Uint32Array(vertices); + } + + /** + * + * @param {Array} wave + * @param { number } time + * @returns {Uint32Array} + */ + makeVecVertex(wave, time) { + const vertices = []; + const ilen = wave.length; + for (let i = 0; i < ilen; i++) { + const [tim, val, msk] = wave[i]; + const tt = (i === (ilen - 1)) ? time : wave[i + 1][0]; + + if (val) { + if (msk) { + vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x,z? + } else { + vertices.push( + tim, 0, 0, + tt, 0, 0, tt, 0, 5, tt, 4, 5, + tim, 6, 5, tim, 0, 5, tim, 3, 5, + tt, 1, 5, tt, 0, 5 + ); + } + } else { + if (msk) { + vertices.push(...brick[2](2, 2, tim, tt, 4, 4)); // x + } else { + vertices.push(tim, 6, 2, tt, 4, 2); + } + } + } + + return new Uint32Array(vertices); + } + + initData() { + const webglLocation = this.webglLocation; + const webgl2 = webglLocation.webgl2; + const globalLookup = this.globalLookup; + const verticesMap = this.verticesMap; + for (const id of Reflect.ownKeys(globalLookup.chango)) { + const signalItem = globalLookup.chango[id]; + const vertices = verticesMap.get(id); + + const vertexBuffer = webgl2.createBuffer(); + webgl2.bindBuffer(webgl2.ARRAY_BUFFER, vertexBuffer); + // 将初始化的顶点数据复制到 buffer 区域 + webgl2.bufferData(webgl2.ARRAY_BUFFER, vertices, webgl2.STATIC_DRAW); + + signalItem.vao = webgl2.createVertexArray(); + webgl2.bindVertexArray(signalItem.vao); + webgl2.vertexAttribIPointer(webglLocation.pos, 3, webgl2.UNSIGNED_INT, 0, 0); + webgl2.enableVertexAttribArray(webglLocation.pos); + webgl2.uniform4fv(webglLocation.colors, cColors); + webgl2.uniform2fv(webglLocation.tilts, cTilts); + } + } + + render() { + if (this.animationHandler !== undefined) { + cancelAnimationFrame(this.animationHandler); + } + + const canvas = this.canvas; + const webglLocation = this.webglLocation; + const webgl2 = webglLocation.webgl2; + const globalLookup = this.globalLookup; + const verticesMap = this.verticesMap; + const elements = this.elements; + + this.animationHandler = window.requestAnimationFrame(() => { + const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = this.pstate; + const canvasHeight = height - 40; + canvas.width = width; + canvas.height = canvasHeight; + + // 设置 glsl 变量 + webgl2.uniform1f(webglLocation.tilt, 3 / width); + webgl2.uniform2f(webglLocation.scale, 2 * xScale / width, yStep * yDuty / canvasHeight); + // 设置 webgl 和 canvas 大小位置一致 + webgl2.viewport(0, 0, width, canvasHeight); + // 清楚颜色缓冲区,也就是删除上一次的渲染结果 + webgl2.clear(webgl2.COLOR_BUFFER_BIT); + + // 根据 globalLookup 当前激活的需要渲染的信号进行渲染 + let index = 0; + for (const signal of globalLookup.currentWires) { + const signalItem = globalLookup.chango[signal.link]; + if (!signalItem) { + return; + } + + webgl2.bindVertexArray(signalItem.vao); + webgl2.uniform2f(webglLocation.offset, + (2 * xOffset / width) - 1, + (2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1 + ); + // 根据 vao 进行绘制 + const vertices = verticesMap.get(signal.link); + // console.log(vertices); + webgl2.drawArrays(webgl2.LINE_STRIP, 0, vertices.length / 3); + + index ++; + } + + this.plugins.map(fn => fn(globalLookup, this.pstate, elements)); + this.animationHandler = undefined; + }); } } -module.exports = genRenderWavesGL; - -/* eslint-env browser */ -/* eslint complexity: [1, 30] */ +module.exports = WebGL2WaveRender; \ No newline at end of file diff --git a/src/hook/wave-view/plugin-render-values.js b/src/hook/wave-view/plugin-render-values.js index 2e2aa2d..4effb05 100644 --- a/src/hook/wave-view/plugin-render-values.js +++ b/src/hook/wave-view/plugin-render-values.js @@ -2,15 +2,15 @@ const renderValues = require('./render-values.js'); -const pluginRenderValues = (desc, pstate, els) => { - const gen = renderValues(desc, pstate); - for (let i = 0; i < 1e6; i++) { - const iter = gen.next(); - if (iter.done) { - els.values.innerHTML = iter.value; - break; +function pluginRenderValues(desc, pstate, els) { + const gen = renderValues(desc, pstate); + for (let i = 0; i < 1e6; i++) { + const iter = gen.next(); + if (iter.done) { + els.values.innerHTML = iter.value; + break; + } } - } -}; +} module.exports = pluginRenderValues; diff --git a/src/hook/wave-view/render-cursor.js b/src/hook/wave-view/render-cursor.js index c9204d2..2c131c5 100644 --- a/src/hook/wave-view/render-cursor.js +++ b/src/hook/wave-view/render-cursor.js @@ -41,6 +41,8 @@ const renderCursor = (cfg, pstate) => { class: 'wd-cursor-time', x: xmargin - lWidth / 2, y: height - fontHeight * 1.25, + rx: 9, + ry: 9, width: lWidth, height: fontHeight * 1.25 }], diff --git a/src/hook/wave-view/render-values.js b/src/hook/wave-view/render-values.js index 5c4726d..46127bd 100644 --- a/src/hook/wave-view/render-values.js +++ b/src/hook/wave-view/render-values.js @@ -12,116 +12,119 @@ const vlineStylo = require('./vline-stylo.js'); const getLabel = require('./get-label.js'); const defs = ['defs', - ['linearGradient', {id: 'valid'}, - ['stop', {offset: '30%', 'stop-color': 'hsla(100, 100%, 100%, 0)'}], - ['stop', {offset: '90%', 'stop-color': 'hsla(100, 100%, 100%, .3)'}] - ], - ['linearGradient', {id: 'valid&ready'}, - ['stop', {offset: '30%', 'stop-color': 'hsla(100, 100%, 50%, 0)'}], - ['stop', {offset: '90%', 'stop-color': 'hsla(100, 100%, 50%, .5)'}] - ], - ['linearGradient', {id: 'valid&~ready'}, - ['stop', {offset: '30%', 'stop-color': 'hsla(50, 100%, 50%, 0)'}], - ['stop', {offset: '90%', 'stop-color': 'hsla(50, 100%, 50%, .5)'}] - ], - ...Object.keys(vlineStylo).map(key => { - const e = vlineStylo[key]; - return ['filter', {id: 'neonGlow-' + key, width: 7, x: -3}, - ['feGaussianBlur', {stdDeviation: 3, in: 'SourceAlpha', result: 'ablur'}], - ['feFlood', {'flood-color': `hsl(${e.h},100%,${e.l}%)`, result: 'xf'}], - ['feComposite', {in: 'xf', in2: 'ablur', operator: 'in'}] - ]; - }) + ['linearGradient', { id: 'valid' }, + ['stop', { offset: '30%', 'stop-color': 'hsla(100, 100%, 100%, 0)' }], + ['stop', { offset: '90%', 'stop-color': 'hsla(100, 100%, 100%, .3)' }] + ], + ['linearGradient', { id: 'valid&ready' }, + ['stop', { offset: '30%', 'stop-color': 'hsla(100, 100%, 50%, 0)' }], + ['stop', { offset: '90%', 'stop-color': 'hsla(100, 100%, 50%, .5)' }] + ], + ['linearGradient', { id: 'valid&~ready' }, + ['stop', { offset: '30%', 'stop-color': 'hsla(50, 100%, 50%, 0)' }], + ['stop', { offset: '90%', 'stop-color': 'hsla(50, 100%, 50%, .5)' }] + ], + ...Object.keys(vlineStylo).map(key => { + const e = vlineStylo[key]; + return ['filter', { id: 'neonGlow-' + key, width: 7, x: -3 }, + ['feGaussianBlur', { stdDeviation: 3, in: 'SourceAlpha', result: 'ablur' }], + ['feFlood', { 'flood-color': `hsl(${e.h},100%,${e.l}%)`, result: 'xf' }], + ['feComposite', { in: 'xf', in2: 'ablur', operator: 'in' }] + ]; + }) ]; -const renderValues = function* (desc, pstate) { - const { width, height, sidebarWidth, yOffset, yStep, topBarHeight, botBarHeight } = pstate; - const { view } = desc; +function* renderValues(desc, pstate) { + const { width, height, sidebarWidth, yOffset, yStep, topBarHeight, botBarHeight } = pstate; - const ilen = height / yStep; - const iskip = yOffset / yStep; - - // console.log(iskip, ilen, view.length); - - const ml = genSVG(width, height - topBarHeight - botBarHeight); - - let ifirst = 0; - for (let i = 0; i < ilen; i += 1) { - const lane = view[i]; - if (lane && (lane.name || lane.kind)) { - if (i > iskip) { - break; - } - ifirst = i; + const currentWires = desc.currentWires; + const view = []; + for (const signal of currentWires) { + view.push({ + kind: signal.kind, + name: signal.name, + ref: signal.link + }); } - } - ml.push(defs); - yield; - const markers = ['g']; - ml.push(markers); + const ilen = height / yStep; + const iskip = yOffset / yStep; - for (let i = 0; i < (iskip + ilen); i++) { - const lane = view[i + (ifirst |0)]; + const ml = genSVG(width, height - topBarHeight - botBarHeight); - if (lane && lane.kind === 'DIZ') { - markers.push(['g', tt(0, Math.round((i - (iskip - ifirst) + 1.18) * yStep))].concat(water(lane, desc, pstate))); - } else - - if (lane && lane.kind === 'brace') { - markers.push(['g', tt(0, Math.round((i - (iskip - ifirst) + 1.18) * yStep))].concat(bracer(lane, desc, pstate))); - } else - - if (lane && lane.ref) { - const chango = desc.chango[lane.ref]; - if (chango && chango.kind === 'vec') { - const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + .9) * yStep))]; - const { wave } = chango; - const jlen = wave.length; - - perLane: { - let [tPre, vPre, mPre] = wave[0]; - let xPre = getX(pstate, tPre); - const labeler = getLabel(lane); - for (let j = 1; j <= jlen; j++) { - const mark = wave[j]; - const [tCur, vCur, mCur] = (mark || [desc.time, 0, 0]); - const xCur = getX(pstate, tCur); - if (vPre || mPre) { - if (xPre > width && xCur > width) { // both time stamps to the right - break perLane; - } - if (!((xPre < sidebarWidth) && (xCur < sidebarWidth))) { // both time stamps to the left - const xPreNorm = ((xPre > sidebarWidth) ? xPre : sidebarWidth) |0; - const xCurNorm = ((xCur < width) ? xCur : width) |0; - const w = xCurNorm - xPreNorm; - if (w > 8) { - const x = Math.round((xPreNorm + xCurNorm) / 2); - mLane.push(labeler(vPre, mPre, x, w)); - } - } + let ifirst = 0; + for (let i = 0; i < ilen; i += 1) { + const lane = view[i]; + if (lane && (lane.name || lane.kind)) { + if (i > iskip) { + break; } - xPre = xCur; - vPre = vCur; - mPre = mCur; - } + ifirst = i; } - ml.push(mLane); - } - yield; } - } + ml.push(defs); + yield; - // console.log(view); - for (let i = 0; i < view.length; i++) { - const lane = view[i]; - if (lane && lane.vlines) { - markers.push(...vline(lane, pstate, i)); + const markers = ['g']; + ml.push(markers); + + for (let i = 0; i < (iskip + ilen); i++) { + const lane = view[i + (ifirst | 0)]; + + if (lane && lane.kind === 'DIZ') { + markers.push(['g', tt(0, Math.round((i - (iskip - ifirst) + 1.18) * yStep))].concat(water(lane, desc, pstate))); + } else if (lane && lane.kind === 'brace') { + markers.push(['g', tt(0, Math.round((i - (iskip - ifirst) + 1.18) * yStep))].concat(bracer(lane, desc, pstate))); + } else if (lane && lane.ref) { + const chango = desc.chango[lane.ref]; + if (chango && chango.kind === 'vec') { + const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + .8) * yStep))]; + const { wave } = chango; + const jlen = wave.length; + + perLane: { + let [tPre, vPre, mPre] = wave[0]; + let xPre = getX(pstate, tPre); + const labeler = getLabel(lane); + for (let j = 1; j <= jlen; j++) { + const mark = wave[j]; + const [tCur, vCur, mCur] = (mark || [desc.time, 0, 0]); + const xCur = getX(pstate, tCur); + if (vPre || mPre) { + if (xPre > width && xCur > width) { // both time stamps to the right + break perLane; + } + if (!((xPre < sidebarWidth) && (xCur < sidebarWidth))) { // both time stamps to the left + const xPreNorm = ((xPre > sidebarWidth) ? xPre : sidebarWidth) | 0; + const xCurNorm = ((xCur < width) ? xCur : width) | 0; + const w = xCurNorm - xPreNorm; + if (w > 8) { + const x = Math.round((xPreNorm + xCurNorm) / 2); + mLane.push(labeler(vPre, mPre, x, w)); + } + } + } + xPre = xCur; + vPre = vCur; + mPre = mCur; + } + } + ml.push(mLane); + } + yield; + } } - } - yield; - return stringify(ml); -}; + + // console.log(view); + for (let i = 0; i < view.length; i++) { + const lane = view[i]; + if (lane && lane.vlines) { + markers.push(...vline(lane, pstate, i)); + } + } + yield; + return stringify(ml); +} module.exports = renderValues; /* eslint complexity: [1, 55] */