@empty-sekai/sekai-custom-profile-sdk 0.3.0
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/LICENSE +235 -0
- package/LICENSE-EXCEPTION +32 -0
- package/NOTICE +11 -0
- package/README.en.md +456 -0
- package/README.md +458 -0
- package/dist/allium_renderer_wasm.js +14 -0
- package/dist/allium_renderer_wasm.wasm +0 -0
- package/dist/authoring.d.ts +14 -0
- package/dist/authoring.js +34 -0
- package/dist/cache/glyphPersistentCache.d.ts +145 -0
- package/dist/cache/glyphPersistentCache.js +346 -0
- package/dist/cache/indexedDbGlyphRecordStore.d.ts +26 -0
- package/dist/cache/indexedDbGlyphRecordStore.js +214 -0
- package/dist/cache/sessionImageResourceCache.d.ts +39 -0
- package/dist/cache/sessionImageResourceCache.js +156 -0
- package/dist/emscripten.d.ts +11 -0
- package/dist/emscripten.js +1 -0
- package/dist/fontProvider.d.ts +36 -0
- package/dist/fontProvider.js +84 -0
- package/dist/fontSdfAtlas.d.ts +92 -0
- package/dist/fontSdfAtlas.js +296 -0
- package/dist/gpu/browserSemanticResources.d.ts +64 -0
- package/dist/gpu/browserSemanticResources.js +232 -0
- package/dist/gpu/generalTextRenderPlacement.d.ts +8 -0
- package/dist/gpu/generalTextRenderPlacement.js +131 -0
- package/dist/gpu/previewTransformTextureLayout.d.ts +1 -0
- package/dist/gpu/previewTransformTextureLayout.js +12 -0
- package/dist/gpu/semanticCommandGeometry.d.ts +21 -0
- package/dist/gpu/semanticCommandGeometry.js +226 -0
- package/dist/gpu/semanticCommandPlanner.d.ts +131 -0
- package/dist/gpu/semanticCommandPlanner.js +203 -0
- package/dist/gpu/semanticTextGlyphBridge.d.ts +3 -0
- package/dist/gpu/semanticTextGlyphBridge.js +22 -0
- package/dist/gpu/semanticWebglSceneRenderer.d.ts +70 -0
- package/dist/gpu/semanticWebglSceneRenderer.js +211 -0
- package/dist/gpu/slotRanges.d.ts +5 -0
- package/dist/gpu/slotRanges.js +14 -0
- package/dist/gpu/webglSdfAtlasTexture.d.ts +17 -0
- package/dist/gpu/webglSdfAtlasTexture.js +72 -0
- package/dist/gpu/webglSdfGlyphPipeline.d.ts +26 -0
- package/dist/gpu/webglSdfGlyphPipeline.js +267 -0
- package/dist/gpu/webglSemanticCommandExecutor.d.ts +79 -0
- package/dist/gpu/webglSemanticCommandExecutor.js +686 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +8 -0
- package/dist/interaction/numericTextRegions.d.ts +46 -0
- package/dist/interaction/numericTextRegions.js +44 -0
- package/dist/localizationProvider.d.ts +33 -0
- package/dist/localizationProvider.js +74 -0
- package/dist/originPrebuiltSdfAtlasPackage.d.ts +39 -0
- package/dist/originPrebuiltSdfAtlasPackage.js +316 -0
- package/dist/prebuiltSdfAtlas.d.ts +36 -0
- package/dist/prebuiltSdfAtlas.js +261 -0
- package/dist/protocol.d.ts +456 -0
- package/dist/protocol.js +1 -0
- package/dist/renderer.d.ts +218 -0
- package/dist/renderer.js +641 -0
- package/dist/resourceProvider.d.ts +24 -0
- package/dist/resourceProvider.js +41 -0
- package/dist/telemetry/rendererTelemetry.d.ts +158 -0
- package/dist/telemetry/rendererTelemetry.js +232 -0
- package/dist/third-party/freetype/FTL.txt +169 -0
- package/dist/types/atlas.d.ts +90 -0
- package/dist/types/atlas.js +1 -0
- package/dist/types/authoring.d.ts +81 -0
- package/dist/types/authoring.js +1 -0
- package/dist/types/core.d.ts +128 -0
- package/dist/types/core.js +1 -0
- package/dist/types/freeType.d.ts +54 -0
- package/dist/types/freeType.js +13 -0
- package/dist/types/glyph.d.ts +33 -0
- package/dist/types/glyph.js +1 -0
- package/dist/types/layout.d.ts +25 -0
- package/dist/types/layout.js +1 -0
- package/dist/types/text.d.ts +28 -0
- package/dist/types/text.js +1 -0
- package/dist/worker/glyphWorkScheduler.d.ts +29 -0
- package/dist/worker/glyphWorkScheduler.js +107 -0
- package/dist/worker-client.d.ts +114 -0
- package/dist/worker-client.js +413 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +708 -0
- package/package.json +46 -0
- package/src/atlas.rs +652 -0
- package/src/authoring.ts +42 -0
- package/src/authoring_runtime.rs +303 -0
- package/src/cache/glyphPersistentCache.ts +463 -0
- package/src/cache/indexedDbGlyphRecordStore.ts +238 -0
- package/src/cache/sessionImageResourceCache.ts +186 -0
- package/src/edt.rs +97 -0
- package/src/emscripten.ts +17 -0
- package/src/fontProvider.ts +127 -0
- package/src/fontSdfAtlas.ts +431 -0
- package/src/geometry.rs +149 -0
- package/src/glyph_plan.rs +226 -0
- package/src/gpu/browserSemanticResources.ts +294 -0
- package/src/gpu/generalTextRenderPlacement.ts +175 -0
- package/src/gpu/previewTransformTextureLayout.ts +12 -0
- package/src/gpu/semanticCommandGeometry.ts +260 -0
- package/src/gpu/semanticCommandPlanner.ts +280 -0
- package/src/gpu/semanticTextGlyphBridge.ts +35 -0
- package/src/gpu/semanticWebglSceneRenderer.ts +261 -0
- package/src/gpu/slotRanges.ts +15 -0
- package/src/gpu/webglSdfAtlasTexture.ts +69 -0
- package/src/gpu/webglSdfGlyphPipeline.ts +299 -0
- package/src/gpu/webglSemanticCommandExecutor.ts +739 -0
- package/src/index.ts +84 -0
- package/src/interaction/numericTextRegions.ts +80 -0
- package/src/layout.rs +1882 -0
- package/src/lib.rs +1443 -0
- package/src/localizationProvider.ts +113 -0
- package/src/main.rs +55 -0
- package/src/masterdata_runtime.rs +496 -0
- package/src/originPrebuiltSdfAtlasPackage.ts +403 -0
- package/src/prebuiltSdfAtlas.ts +306 -0
- package/src/protocol.ts +150 -0
- package/src/renderer.ts +792 -0
- package/src/resourceProvider.ts +69 -0
- package/src/scene.rs +665 -0
- package/src/telemetry/rendererTelemetry.ts +358 -0
- package/src/types/atlas.ts +80 -0
- package/src/types/authoring.ts +85 -0
- package/src/types/core.ts +110 -0
- package/src/types/freeType.ts +63 -0
- package/src/types/glyph.ts +33 -0
- package/src/types/layout.ts +28 -0
- package/src/types/text.ts +28 -0
- package/src/worker/glyphWorkScheduler.ts +130 -0
- package/src/worker-client.ts +484 -0
- package/src/worker.ts +895 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
const CARD_W = 1830;
|
|
2
|
+
const CARD_H = 812;
|
|
3
|
+
const FLOATS_PER_INSTANCE = 36;
|
|
4
|
+
export class WebglSdfGlyphPipeline {
|
|
5
|
+
gl;
|
|
6
|
+
program;
|
|
7
|
+
batches = new Map();
|
|
8
|
+
atlasTexture;
|
|
9
|
+
ownsAtlas = true;
|
|
10
|
+
geometryBuilds = 0;
|
|
11
|
+
constructor(gl) {
|
|
12
|
+
this.gl = gl;
|
|
13
|
+
this.program = createProgram(gl, VERTEX_SHADER, FRAGMENT_SHADER);
|
|
14
|
+
const atlas = gl.createTexture();
|
|
15
|
+
if (!atlas)
|
|
16
|
+
throw new Error("glyph pipeline atlas allocation failed");
|
|
17
|
+
this.atlasTexture = atlas;
|
|
18
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, atlas);
|
|
19
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
20
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
21
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
22
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
23
|
+
gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.R8, 1, 1, 1, 0, gl.RED, gl.UNSIGNED_BYTE, new Uint8Array([255]));
|
|
24
|
+
}
|
|
25
|
+
setAtlas(texture) {
|
|
26
|
+
if (this.ownsAtlas)
|
|
27
|
+
this.gl.deleteTexture(this.atlasTexture);
|
|
28
|
+
this.atlasTexture = texture;
|
|
29
|
+
this.ownsAtlas = false;
|
|
30
|
+
}
|
|
31
|
+
upload(key, vertices) {
|
|
32
|
+
this.deleteBatch(key);
|
|
33
|
+
if (vertices.length % FLOATS_PER_INSTANCE !== 0)
|
|
34
|
+
throw new Error(`invalid glyph instance buffer ${key}`);
|
|
35
|
+
const gl = this.gl;
|
|
36
|
+
const vao = gl.createVertexArray();
|
|
37
|
+
const buffer = gl.createBuffer();
|
|
38
|
+
if (!vao || !buffer)
|
|
39
|
+
throw new Error("glyph pipeline batch allocation failed");
|
|
40
|
+
gl.bindVertexArray(vao);
|
|
41
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
42
|
+
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
|
43
|
+
const stride = FLOATS_PER_INSTANCE * 4;
|
|
44
|
+
instanceAttribute(gl, 0, 4, stride, 0);
|
|
45
|
+
instanceAttribute(gl, 1, 4, stride, 4 * 4);
|
|
46
|
+
instanceAttribute(gl, 2, 4, stride, 8 * 4);
|
|
47
|
+
instanceAttribute(gl, 3, 4, stride, 12 * 4);
|
|
48
|
+
instanceAttribute(gl, 4, 4, stride, 16 * 4);
|
|
49
|
+
instanceAttribute(gl, 5, 4, stride, 20 * 4);
|
|
50
|
+
instanceAttribute(gl, 6, 4, stride, 24 * 4);
|
|
51
|
+
instanceAttribute(gl, 7, 4, stride, 28 * 4);
|
|
52
|
+
instanceAttribute(gl, 8, 4, stride, 32 * 4);
|
|
53
|
+
gl.bindVertexArray(null);
|
|
54
|
+
this.batches.set(key, { vao, buffer, instances: vertices.length / FLOATS_PER_INSTANCE, bytes: vertices.byteLength });
|
|
55
|
+
this.geometryBuilds += 1;
|
|
56
|
+
}
|
|
57
|
+
draw(key, stateTexture, maskTexture, stateWidth, commandMaskTexture = maskTexture, commandStateTexture = stateTexture, commandWidth = stateWidth, previewTransformTexture = stateTexture) {
|
|
58
|
+
const batch = this.batches.get(key);
|
|
59
|
+
if (!batch || batch.instances === 0)
|
|
60
|
+
return { drawCalls: 0, instances: 0, bytes: batch?.bytes ?? 0 };
|
|
61
|
+
const gl = this.gl;
|
|
62
|
+
gl.useProgram(this.program);
|
|
63
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
64
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.atlasTexture);
|
|
65
|
+
gl.uniform1i(gl.getUniformLocation(this.program, "u_atlas"), 0);
|
|
66
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
67
|
+
gl.bindTexture(gl.TEXTURE_2D, stateTexture);
|
|
68
|
+
gl.uniform1i(gl.getUniformLocation(this.program, "u_layerState"), 1);
|
|
69
|
+
gl.uniform1f(gl.getUniformLocation(this.program, "u_layerStateWidth"), stateWidth);
|
|
70
|
+
gl.activeTexture(gl.TEXTURE2);
|
|
71
|
+
gl.bindTexture(gl.TEXTURE_2D, maskTexture);
|
|
72
|
+
gl.uniform1i(gl.getUniformLocation(this.program, "u_renderMask"), 2);
|
|
73
|
+
gl.activeTexture(gl.TEXTURE3);
|
|
74
|
+
gl.bindTexture(gl.TEXTURE_2D, commandMaskTexture);
|
|
75
|
+
gl.uniform1i(gl.getUniformLocation(this.program, "u_commandMask"), 3);
|
|
76
|
+
gl.activeTexture(gl.TEXTURE4);
|
|
77
|
+
gl.bindTexture(gl.TEXTURE_2D, commandStateTexture);
|
|
78
|
+
gl.uniform1i(gl.getUniformLocation(this.program, "u_commandState"), 4);
|
|
79
|
+
gl.uniform1f(gl.getUniformLocation(this.program, "u_commandWidth"), commandWidth);
|
|
80
|
+
gl.activeTexture(gl.TEXTURE5);
|
|
81
|
+
gl.bindTexture(gl.TEXTURE_2D, previewTransformTexture);
|
|
82
|
+
gl.uniform1i(gl.getUniformLocation(this.program, "u_previewTransform"), 5);
|
|
83
|
+
gl.bindVertexArray(batch.vao);
|
|
84
|
+
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, batch.instances);
|
|
85
|
+
gl.bindVertexArray(null);
|
|
86
|
+
return { drawCalls: 1, instances: batch.instances, bytes: batch.bytes };
|
|
87
|
+
}
|
|
88
|
+
stats() {
|
|
89
|
+
return {
|
|
90
|
+
geometryBuilds: this.geometryBuilds,
|
|
91
|
+
batches: this.batches.size,
|
|
92
|
+
bytes: [...this.batches.values()].reduce((sum, batch) => sum + batch.bytes, 0),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
clearBatches() {
|
|
96
|
+
for (const key of [...this.batches.keys()])
|
|
97
|
+
this.deleteBatch(key);
|
|
98
|
+
}
|
|
99
|
+
destroy() {
|
|
100
|
+
this.clearBatches();
|
|
101
|
+
if (this.ownsAtlas)
|
|
102
|
+
this.gl.deleteTexture(this.atlasTexture);
|
|
103
|
+
this.gl.deleteProgram(this.program);
|
|
104
|
+
}
|
|
105
|
+
deleteBatch(key) {
|
|
106
|
+
const batch = this.batches.get(key);
|
|
107
|
+
if (!batch)
|
|
108
|
+
return;
|
|
109
|
+
this.gl.deleteBuffer(batch.buffer);
|
|
110
|
+
this.gl.deleteVertexArray(batch.vao);
|
|
111
|
+
this.batches.delete(key);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function buildSdfGlyphInstanceVertices(instances, layerSlots, clips = new Map(), commandSlots = layerSlots) {
|
|
115
|
+
const rows = [];
|
|
116
|
+
for (const instance of instances) {
|
|
117
|
+
if (!instance.drawable || instance.quad.length < 4)
|
|
118
|
+
continue;
|
|
119
|
+
const [tl, tr, br, bl] = instance.quad;
|
|
120
|
+
const position = ([x, y]) => [(x / CARD_W) * 2 - 1, 1 - (y / CARD_H) * 2];
|
|
121
|
+
const clip = clips.get(instance.layerId) ?? [[-1e9, -1e9], [1e9, -1e9], [1e9, 1e9], [-1e9, 1e9]];
|
|
122
|
+
rows.push(...position(tl), ...position(tr), ...position(br), ...position(bl), tl[2], tl[3], br[2], br[3], ...instance.fill, ...instance.outline, instance.shaderFaceScale, instance.shaderFaceBias, instance.shaderUnderlayScale, instance.shaderUnderlayBias, instance.shaderVertexAlpha, layerSlots.get(instance.layerId) ?? 0, instance.atlasPage ?? 0, commandSlots.get(instance.layerId) ?? 0, ...position(clip[0]), ...position(clip[1]), ...position(clip[2]), ...position(clip[3]));
|
|
123
|
+
}
|
|
124
|
+
return new Float32Array(rows);
|
|
125
|
+
}
|
|
126
|
+
function instanceAttribute(gl, index, size, stride, offset) {
|
|
127
|
+
gl.enableVertexAttribArray(index);
|
|
128
|
+
gl.vertexAttribPointer(index, size, gl.FLOAT, false, stride, offset);
|
|
129
|
+
gl.vertexAttribDivisor(index, 1);
|
|
130
|
+
}
|
|
131
|
+
function createProgram(gl, vertexSource, fragmentSource) {
|
|
132
|
+
const compile = (type, source) => {
|
|
133
|
+
const shader = gl.createShader(type);
|
|
134
|
+
if (!shader)
|
|
135
|
+
throw new Error("glyph shader allocation failed");
|
|
136
|
+
gl.shaderSource(shader, source);
|
|
137
|
+
gl.compileShader(shader);
|
|
138
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
|
|
139
|
+
throw new Error(gl.getShaderInfoLog(shader) ?? "glyph shader compile failed");
|
|
140
|
+
return shader;
|
|
141
|
+
};
|
|
142
|
+
const vertex = compile(gl.VERTEX_SHADER, vertexSource);
|
|
143
|
+
const fragment = compile(gl.FRAGMENT_SHADER, fragmentSource);
|
|
144
|
+
const program = gl.createProgram();
|
|
145
|
+
if (!program)
|
|
146
|
+
throw new Error("glyph program allocation failed");
|
|
147
|
+
gl.attachShader(program, vertex);
|
|
148
|
+
gl.attachShader(program, fragment);
|
|
149
|
+
gl.linkProgram(program);
|
|
150
|
+
gl.deleteShader(vertex);
|
|
151
|
+
gl.deleteShader(fragment);
|
|
152
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
|
|
153
|
+
throw new Error(gl.getProgramInfoLog(program) ?? "glyph program link failed");
|
|
154
|
+
return program;
|
|
155
|
+
}
|
|
156
|
+
const VERTEX_SHADER = `#version 300 es
|
|
157
|
+
precision highp float;
|
|
158
|
+
layout(location=0) in vec4 a_pos01;
|
|
159
|
+
layout(location=1) in vec4 a_pos23;
|
|
160
|
+
layout(location=2) in vec4 a_uvRect;
|
|
161
|
+
layout(location=3) in vec4 a_color;
|
|
162
|
+
layout(location=4) in vec4 a_outline;
|
|
163
|
+
layout(location=5) in vec4 a_sdfParams;
|
|
164
|
+
layout(location=6) in vec4 a_instanceMeta;
|
|
165
|
+
layout(location=7) in vec4 a_clip01;
|
|
166
|
+
layout(location=8) in vec4 a_clip23;
|
|
167
|
+
uniform sampler2D u_layerState;
|
|
168
|
+
uniform highp usampler2D u_renderMask;
|
|
169
|
+
uniform float u_layerStateWidth;
|
|
170
|
+
uniform highp usampler2D u_commandMask;
|
|
171
|
+
uniform sampler2D u_commandState;
|
|
172
|
+
uniform float u_commandWidth;
|
|
173
|
+
uniform sampler2D u_previewTransform;
|
|
174
|
+
out vec2 v_uv;
|
|
175
|
+
out vec4 v_color;
|
|
176
|
+
out vec4 v_outline;
|
|
177
|
+
out float v_faceScale;
|
|
178
|
+
out float v_faceBias;
|
|
179
|
+
out float v_underlayScale;
|
|
180
|
+
out float v_underlayBias;
|
|
181
|
+
out float v_vertexAlpha;
|
|
182
|
+
flat out float v_atlasPage;
|
|
183
|
+
out vec2 v_point;
|
|
184
|
+
out vec4 v_clip01;
|
|
185
|
+
out vec4 v_clip23;
|
|
186
|
+
const int CORNER_IDS[6] = int[6](0, 1, 3, 3, 1, 2);
|
|
187
|
+
void main() {
|
|
188
|
+
vec2 positions[4] = vec2[4](a_pos01.xy, a_pos01.zw, a_pos23.xy, a_pos23.zw);
|
|
189
|
+
vec2 uvs[4] = vec2[4](a_uvRect.xy, vec2(a_uvRect.z, a_uvRect.y), a_uvRect.zw, vec2(a_uvRect.x, a_uvRect.w));
|
|
190
|
+
int corner = CORNER_IDS[gl_VertexID];
|
|
191
|
+
float layerSlot = a_instanceMeta.y;
|
|
192
|
+
float stateU = (layerSlot + 0.5) / max(u_layerStateWidth, 1.0);
|
|
193
|
+
vec2 state = texture(u_layerState, vec2(stateU, 0.5)).rg;
|
|
194
|
+
uint mask = texelFetch(u_renderMask, ivec2(int(layerSlot), 0), 0).r;
|
|
195
|
+
uint commandMask = texelFetch(u_commandMask, ivec2(int(a_instanceMeta.w), 0), 0).r;
|
|
196
|
+
vec2 commandState = texelFetch(u_commandState, ivec2(int(a_instanceMeta.w), 0), 0).rg;
|
|
197
|
+
vec2 totalState = state + commandState;
|
|
198
|
+
vec4 preview0 = texelFetch(u_previewTransform, ivec2(int(layerSlot), 0), 0);
|
|
199
|
+
vec4 preview1 = texelFetch(u_previewTransform, ivec2(int(layerSlot), 1), 0);
|
|
200
|
+
vec2 pixelPosition = vec2(
|
|
201
|
+
(positions[corner].x + 1.0) * ${CARD_W / 2}.0,
|
|
202
|
+
(1.0 - positions[corner].y) * ${CARD_H / 2}.0
|
|
203
|
+
) + totalState;
|
|
204
|
+
vec2 previewedPosition = vec2(
|
|
205
|
+
dot(preview0.xy, pixelPosition) + preview0.z,
|
|
206
|
+
dot(preview1.xy, pixelPosition) + preview1.z
|
|
207
|
+
);
|
|
208
|
+
vec2 position = vec2(
|
|
209
|
+
previewedPosition.x * ${2 / CARD_W} - 1.0,
|
|
210
|
+
1.0 - previewedPosition.y * ${2 / CARD_H}
|
|
211
|
+
);
|
|
212
|
+
vec2 clipPoints[4] = vec2[4](a_clip01.xy, a_clip01.zw, a_clip23.xy, a_clip23.zw);
|
|
213
|
+
for (int index = 0; index < 4; index += 1) {
|
|
214
|
+
vec2 clipPixel = vec2((clipPoints[index].x + 1.0) * ${CARD_W / 2}.0, (1.0 - clipPoints[index].y) * ${CARD_H / 2}.0) + state;
|
|
215
|
+
vec2 transformed = vec2(dot(preview0.xy, clipPixel) + preview0.z, dot(preview1.xy, clipPixel) + preview1.z);
|
|
216
|
+
clipPoints[index] = vec2(transformed.x * ${2 / CARD_W} - 1.0, 1.0 - transformed.y * ${2 / CARD_H});
|
|
217
|
+
}
|
|
218
|
+
if (mask == 0u || commandMask == 0u) position = vec2(2.0);
|
|
219
|
+
gl_Position = vec4(position, 0.0, 1.0);
|
|
220
|
+
v_uv = uvs[corner];
|
|
221
|
+
v_color = a_color;
|
|
222
|
+
v_outline = a_outline;
|
|
223
|
+
v_faceScale = max(a_sdfParams.x, 0.0001);
|
|
224
|
+
v_faceBias = a_sdfParams.y;
|
|
225
|
+
v_underlayScale = max(a_sdfParams.z, 0.0001);
|
|
226
|
+
v_underlayBias = a_sdfParams.w;
|
|
227
|
+
v_vertexAlpha = clamp(a_instanceMeta.x, 0.0, 1.0);
|
|
228
|
+
v_atlasPage = a_instanceMeta.z;
|
|
229
|
+
v_point = position;
|
|
230
|
+
v_clip01 = vec4(clipPoints[0], clipPoints[1]);
|
|
231
|
+
v_clip23 = vec4(clipPoints[2], clipPoints[3]);
|
|
232
|
+
}`;
|
|
233
|
+
const FRAGMENT_SHADER = `#version 300 es
|
|
234
|
+
precision highp float;
|
|
235
|
+
uniform highp sampler2DArray u_atlas;
|
|
236
|
+
in vec2 v_uv;
|
|
237
|
+
in vec4 v_color;
|
|
238
|
+
in vec4 v_outline;
|
|
239
|
+
in float v_faceScale;
|
|
240
|
+
in float v_faceBias;
|
|
241
|
+
in float v_underlayScale;
|
|
242
|
+
in float v_underlayBias;
|
|
243
|
+
in float v_vertexAlpha;
|
|
244
|
+
flat in float v_atlasPage;
|
|
245
|
+
in vec2 v_point;
|
|
246
|
+
in vec4 v_clip01;
|
|
247
|
+
in vec4 v_clip23;
|
|
248
|
+
out vec4 outColor;
|
|
249
|
+
float cross2(vec2 a, vec2 b) { return a.x * b.y - a.y * b.x; }
|
|
250
|
+
bool insideClip() {
|
|
251
|
+
vec2 p[4] = vec2[4](v_clip01.xy, v_clip01.zw, v_clip23.xy, v_clip23.zw);
|
|
252
|
+
float c0 = cross2(p[1] - p[0], v_point - p[0]);
|
|
253
|
+
float c1 = cross2(p[2] - p[1], v_point - p[1]);
|
|
254
|
+
float c2 = cross2(p[3] - p[2], v_point - p[2]);
|
|
255
|
+
float c3 = cross2(p[0] - p[3], v_point - p[3]);
|
|
256
|
+
return (c0 >= 0.0 && c1 >= 0.0 && c2 >= 0.0 && c3 >= 0.0) || (c0 <= 0.0 && c1 <= 0.0 && c2 <= 0.0 && c3 <= 0.0);
|
|
257
|
+
}
|
|
258
|
+
void main() {
|
|
259
|
+
if (!insideClip()) discard;
|
|
260
|
+
float sdf = texture(u_atlas, vec3(v_uv, v_atlasPage)).r;
|
|
261
|
+
float faceT = clamp(sdf * v_faceScale - v_faceBias, 0.0, 1.0);
|
|
262
|
+
float underlayT = clamp(sdf * v_underlayScale - v_underlayBias, 0.0, 1.0) * clamp(sdf * 12.5, 0.0, 1.0);
|
|
263
|
+
vec4 face = vec4(v_color.rgb * v_color.a, v_color.a);
|
|
264
|
+
vec4 outline = vec4(v_outline.rgb * v_outline.a, v_outline.a);
|
|
265
|
+
float oneMinusFace = 1.0 - face.a * faceT;
|
|
266
|
+
outColor = (face * faceT + outline * underlayT * oneMinusFace) * v_vertexAlpha;
|
|
267
|
+
}`;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type SemanticDrawBatch } from "./semanticCommandGeometry.js";
|
|
2
|
+
import type { SemanticCommandPlan, SemanticCommandStatePatch, SemanticLayerPatch } from "./semanticCommandPlanner.js";
|
|
3
|
+
import type { SdfAtlas } from "../fontSdfAtlas.js";
|
|
4
|
+
import type { BrowserImageSource } from "./browserSemanticResources.js";
|
|
5
|
+
export type SemanticGpuMetrics = {
|
|
6
|
+
drawCalls: number;
|
|
7
|
+
geometryBuilds: number;
|
|
8
|
+
vertexBytes: number;
|
|
9
|
+
textureUploads: number;
|
|
10
|
+
textureBytes: number;
|
|
11
|
+
stateUploadBytes: number;
|
|
12
|
+
maskUploadBytes: number;
|
|
13
|
+
glyphGeometryBuilds: number;
|
|
14
|
+
isolationBegins: number;
|
|
15
|
+
isolationComposites: number;
|
|
16
|
+
isolationTargetAllocations: number;
|
|
17
|
+
isolationTextureBytes: number;
|
|
18
|
+
};
|
|
19
|
+
export declare class WebglSemanticCommandExecutor {
|
|
20
|
+
private readonly gl;
|
|
21
|
+
private readonly canvasWidth;
|
|
22
|
+
private readonly canvasHeight;
|
|
23
|
+
private shapeProgram;
|
|
24
|
+
private textureProgram;
|
|
25
|
+
private compositeProgram;
|
|
26
|
+
private compositeVao;
|
|
27
|
+
private stateTexture;
|
|
28
|
+
private maskTexture;
|
|
29
|
+
private commandMaskTexture;
|
|
30
|
+
private commandStateTexture;
|
|
31
|
+
private previewTransformTexture;
|
|
32
|
+
private batches;
|
|
33
|
+
private textures;
|
|
34
|
+
private state;
|
|
35
|
+
private mask;
|
|
36
|
+
private stateWidth;
|
|
37
|
+
private commandMask;
|
|
38
|
+
private commandState;
|
|
39
|
+
private previewTransforms;
|
|
40
|
+
private commandWidth;
|
|
41
|
+
private plan;
|
|
42
|
+
private layerSlotById;
|
|
43
|
+
private readonly glyphPipeline;
|
|
44
|
+
private sdfAtlasTexture;
|
|
45
|
+
private geometryBuilds;
|
|
46
|
+
private textureUploads;
|
|
47
|
+
private textureBytes;
|
|
48
|
+
private readonly isolationTargets;
|
|
49
|
+
private isolationTargetAllocations;
|
|
50
|
+
constructor(gl: WebGL2RenderingContext, canvasWidth?: number, canvasHeight?: number);
|
|
51
|
+
setTextGlyphBatch(commandId: string, vertices: Float32Array): void;
|
|
52
|
+
setSdfAtlas(atlas: SdfAtlas): Promise<{
|
|
53
|
+
bytes: number;
|
|
54
|
+
rects: number;
|
|
55
|
+
}>;
|
|
56
|
+
setScene(plan: SemanticCommandPlan, batches: SemanticDrawBatch[], resources: Map<string, BrowserImageSource>): void;
|
|
57
|
+
applyCommandPatches(patches: SemanticCommandStatePatch[]): {
|
|
58
|
+
commandMaskUploadBytes: number;
|
|
59
|
+
commandStateUploadBytes: number;
|
|
60
|
+
};
|
|
61
|
+
applyLayerPatches(patches: SemanticLayerPatch[]): {
|
|
62
|
+
stateUploadBytes: number;
|
|
63
|
+
maskUploadBytes: number;
|
|
64
|
+
};
|
|
65
|
+
setLayerPreviewTransform(layerId: string, matrix: [number, number, number, number, number, number] | null): {
|
|
66
|
+
previewUploadBytes: number;
|
|
67
|
+
};
|
|
68
|
+
draw(): SemanticGpuMetrics;
|
|
69
|
+
destroy(): void;
|
|
70
|
+
private bindCommon;
|
|
71
|
+
private setBlendMode;
|
|
72
|
+
private isolationTarget;
|
|
73
|
+
private drawIsolationTexture;
|
|
74
|
+
private uploadFullState;
|
|
75
|
+
private uploadBatch;
|
|
76
|
+
private ensureTexture;
|
|
77
|
+
private deleteBatches;
|
|
78
|
+
}
|
|
79
|
+
export declare function resourceIdentity(namespace: string, key: string): string;
|