modern-canvas 0.26.2 → 0.27.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.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 合批 shader 的效果插槽:每个效果是一个独立模块,声明自己的 GLSL 片段与
3
+ * uniform,编译时组装进共享 uber-shader —— 特性代码不再散落在核心模板里,
4
+ * 新增同类效果(虚线 / 渐变描边 / 选中脉冲…)只需注册一个新效果对象。
5
+ *
6
+ * 核心向片段提供的通用通道:
7
+ * - `vec4 color`(可读写,预乘 alpha)
8
+ * - `vec2 vUv`(纯色描边下 u = 路径像素弧长、v = 横向 0..1,见 CanvasContext)
9
+ * - `float vFlags`(aTextureParams.y 字节:bit0 = clipOutsideUv 为核心保留,
10
+ * bit1+ 归效果使用,由 {@link Batchable2D.effectFlags} 写入)
11
+ * - `float vParam`(aTextureParams.w 字节:效果自定义标量,
12
+ * 由 {@link Batchable2D.effectParam} 写入,0 = 关闭)
13
+ * - `float uTime`(秒,核心时钟)+ 效果自声明的 uniform
14
+ * (宿主经 `batch2D.effectUniforms` 覆盖默认值)
15
+ *
16
+ * 运行成本:标志/参数是 per-primitive 常量,warp 内分支不发散,未启用的
17
+ * 元素只付几条标量比较。
18
+ */
19
+ export interface Batch2DEffect {
20
+ /** 唯一名;重复注册按名替换。 */
21
+ name: string;
22
+ /** ES300 片段,注入 main() 内(clip 之后、输出之前)。 */
23
+ fragment?: string;
24
+ /** ES100(WebGL1,无导数函数)降级片段;缺省则该效果在 GL1 下关闭。 */
25
+ fragmentGl1?: string;
26
+ /** 片段所需的 uniform 声明,如 `uniform vec3 uFlowColor;`。 */
27
+ uniformDecls?: string;
28
+ /** uniform 默认值;宿主可经 `batch2D.effectUniforms` 逐帧覆盖。 */
29
+ uniformDefaults?: Record<string, any>;
30
+ }
31
+ /** aTextureParams.y bit0:UV 越界裁剪(核心语义,效果位从 bit1 起)。 */
32
+ export declare const FLAG_CLIP_OUTSIDE_UV = 1;
33
+ /** aTextureParams.y bit1:描边羽化 + hairline(需要横向 v UV)。 */
34
+ export declare const FLAG_STROKE_AA = 2;
35
+ /** 流动速度(周期/秒,符号=方向)→ 参数字节:128=0 速,1 单位=1/32 周期/s,0=关。 */
36
+ export declare function encodeFlowSpeed(speed: number): number;
37
+ /**
38
+ * 描边羽化 + 亚像素 hairline 补偿。1/fwidth(v) 即描边屏幕像素宽度:边缘做
39
+ * ~1px alpha 渐变;宽度不足 1px 时按覆盖率降 alpha(能量守恒),细线不再
40
+ * 碎成点刻。流动描边自带 core AA,编码侧不会同时置此位。
41
+ */
42
+ export declare const strokeFeatherEffect: Batch2DEffect;
43
+ /**
44
+ * 描边流动亮段(vParam = encodeFlowSpeed 编码的速度):u 为路径像素弧长,
45
+ * 亮段间距 uFlowPeriod 路径像素(固定物理长度,长短线亮段一致),每段
46
+ * 前缘快收 + 短拖尾(~22% 周期)。宿主把几何加宽(widthBoost)后,可见
47
+ * 线体只画在中间 50%,外圈是亮段经过时点亮的辉光带——零额外 pass 的 bloom。
48
+ */
49
+ export declare const flowStreakEffect: Batch2DEffect;
@@ -1,4 +1,5 @@
1
- import type { BufferLike, GeometryAttributeLike, TextureLike } from '../shared';
1
+ import type { BufferLikeObject, GeometryAttributeLike, GeometryLikeObject, ShaderLikeObject, TextureLike } from '../shared';
2
+ import type { Batch2DEffect } from './Batch2DEffect';
2
3
  import type { GlDrawOptions } from './geometry';
3
4
  import type { WebGLRenderer } from './WebGLRenderer';
4
5
  import { GlBlendMode, GlState } from './state';
@@ -16,10 +17,48 @@ export interface Batchable2D {
16
17
  blendMode?: GlBlendMode;
17
18
  roundPixels?: boolean;
18
19
  clipOutsideUv?: boolean;
20
+ /**
21
+ * Effect flag bits (bit 1+ of the aTextureParams.y byte; bit 0 is reserved
22
+ * for clipOutsideUv). Semantics are defined by the registered
23
+ * {@link Batch2DEffect}s — e.g. {@link FLAG_STROKE_AA}. 0/undefined = none.
24
+ */
25
+ effectFlags?: number;
26
+ /**
27
+ * Effect scalar parameter (the spare aTextureParams.w byte, 0-255; 0 = off).
28
+ * Encoding is defined by the effect that consumes it — e.g. the flow streak
29
+ * effect's {@link encodeFlowSpeed}. Costs no extra vertex attribute.
30
+ */
31
+ effectParam?: number;
19
32
  }
20
- interface Shader {
21
- update: (bufferData: BufferLike['data'], indexBufferData: BufferLike['data']) => void;
22
- draw: (options?: GlDrawOptions) => void;
33
+ type DrawCall = Required<GlDrawOptions> & {
34
+ id: number;
35
+ textures: TextureLike[];
36
+ textureLocationMap: Map<TextureLike, number>;
37
+ blendMode: GlBlendMode;
38
+ };
39
+ interface BatchProgram {
40
+ shader: ShaderLikeObject;
41
+ samplers: Int32Array;
42
+ /** merged `uniformDefaults` of the effects compiled into this program */
43
+ uniformDefaults: Record<string, any>;
44
+ }
45
+ /**
46
+ * Per-flush GPU + staging resources, addressed by flush ordinal within a frame.
47
+ * Dedicated (not pooled/shared) so an unchanged flush can skip both the CPU
48
+ * vertex rewrite and the GPU upload and just re-issue its draw calls — the GL
49
+ * buffers still hold exactly this flush's data. `refs` snapshots what the
50
+ * buffer content was built from (see {@link GlBatch2DSystem.flush}).
51
+ */
52
+ interface BatchSlot {
53
+ buffer: BufferLikeObject;
54
+ indexBuffer: BufferLikeObject;
55
+ geometry: GeometryLikeObject;
56
+ attrData?: ArrayBuffer;
57
+ f32?: Float32Array;
58
+ u8?: Uint8Array;
59
+ indexData?: Uint32Array<ArrayBuffer>;
60
+ refs: any[];
61
+ drawCalls: DrawCall[];
23
62
  }
24
63
  export declare class GlBatch2DSystem extends GlSystem {
25
64
  install(renderer: WebGLRenderer): void;
@@ -28,17 +67,38 @@ export declare class GlBatch2DSystem extends GlSystem {
28
67
  protected _batchables: Batchable2D[];
29
68
  protected _vertexCount: number;
30
69
  protected _indexCount: number;
31
- protected _attributeBuffer: ArrayBuffer[];
32
- protected _indexBuffers: Uint32Array<ArrayBuffer>[];
33
- protected _shaders: Map<number, Shader>;
70
+ protected _programs: Map<string, BatchProgram>;
71
+ /**
72
+ * Registered shader effects, composed into the batch program at compile time
73
+ * (see {@link Batch2DEffect}). Re-registering by name replaces and triggers a
74
+ * program rebuild on the next flush.
75
+ */
76
+ protected _effects: Batch2DEffect[];
77
+ protected _effectsRevision: number;
78
+ /**
79
+ * Host-written uniform values for effect snippets (e.g. `uFlowColor`).
80
+ * Merged over each effect's `uniformDefaults` on every draw.
81
+ */
82
+ effectUniforms: Record<string, any>;
83
+ registerEffect(effect: Batch2DEffect): void;
84
+ protected _slots: BatchSlot[];
85
+ protected _slotIndex: number;
86
+ /**
87
+ * Marks the start of a frame: flush ordinals restart so each flush lines up
88
+ * with the slot holding its previous content. Without this call slots keep
89
+ * advancing and simply never reuse (capped at {@link MAX_SLOTS}).
90
+ */
91
+ beginFrame(): void;
34
92
  protected _attributes: Record<string, Partial<GeometryAttributeLike>>;
35
93
  protected _vertexSize: number;
36
- protected _getShader(maxTextureUnits: number): Shader;
37
- protected _createShader(maxTextureUnits: number): Shader;
94
+ protected _getProgram(maxTextureUnits: number): BatchProgram;
95
+ protected _createProgram(maxTextureUnits: number): BatchProgram;
96
+ protected _getSlot(): BatchSlot;
97
+ protected _drawSlot(program: BatchProgram, slot: BatchSlot, options: GlDrawOptions): void;
98
+ protected _issueDrawCalls(program: BatchProgram, slot: BatchSlot): void;
38
99
  render(batchable: Batchable2D): void;
39
100
  flush(): void;
40
- protected _getBufferData(size: number): ArrayBuffer;
41
- protected _getIndexBufferData(size: number): Uint32Array<ArrayBuffer>;
101
+ reset(): void;
42
102
  }
43
103
  export declare function nextPow2(v: number): number;
44
104
  export declare function log2(v: number): number;
@@ -1,3 +1,4 @@
1
+ export * from './Batch2DEffect';
1
2
  export * from './buffer';
2
3
  export * from './GlBatch2DSystem';
3
4
  export * from './GlMaskSystem';
@@ -24,6 +24,8 @@ export declare class GlRenderTargetSystem extends GlSystem {
24
24
  protected _hasMRT: boolean;
25
25
  protected _writeDepthTexture: boolean;
26
26
  projection: Projection2D;
27
+ /** 4x MSAA, clamped to what the device actually supports (some GPUs cap at 2). */
28
+ protected get _sampleCount(): number;
27
29
  protected _updateContext(gl: GlRenderingContext): void;
28
30
  bind(renderTarget: RenderTargetLike | null, frame?: RectangleLike): void;
29
31
  unbind(): void;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Revision of everything a connection's endpoints can be derived from. Bumped when:
3
+ *
4
+ * - any Element2D's world geometry is recomputed (globalTransform / globalAabb / size)
5
+ * - a shape's `connectionPoints` are replaced
6
+ * - a node enters or leaves the tree (changes what an id resolves to)
7
+ *
8
+ * Deliberately global rather than per-element: a connection would otherwise have to
9
+ * read its two targets to notice a change, and reading is exactly what we're avoiding.
10
+ * `route()` runs every frame for every connection (Element2D._process), and in a host
11
+ * that wraps elements in a reactive proxy — mce puts them behind Vue's `reactive()` —
12
+ * even reading a handful of properties per connection per frame adds up, while writing
13
+ * a cache field back triggers the proxy's dependency machinery. One integer compare
14
+ * costs nothing.
15
+ *
16
+ * Being global only ever costs extra work, never correctness: an unrelated element
17
+ * moving makes every connection fall through to comparing its own endpoints, which is
18
+ * still far cheaper than re-resolving them.
19
+ *
20
+ * The camera is a plain Node2D whose transform touches no Element2D aabb, so panning /
21
+ * zooming the viewport does NOT bump this — connections stay fully cached while the
22
+ * user navigates.
23
+ */
24
+ export declare function geometryRevision(): number;
25
+ export declare function bumpGeometryRevision(): void;
@@ -1,4 +1,5 @@
1
1
  export * from './css';
2
2
  export * from './dom';
3
+ export * from './geometryRevision';
3
4
  export * from './id';
4
5
  export * from './utils';