Skip to content

Introduce an Abstract Render Pipeline to support WebGL-Accelerated Rendering for high-density & collaborative environments #1427

@realone09

Description

@realone09

What problem does this feature solve?

currently, canvas-editor relies entirely on a CPU-bound HTML5 Canvas 2D context (canvas2d). While this engine provides incredible precision for standard pages, performance bottlenecks emerge when handling:

High-density documents: Documents exceeding 50+ pages with heavy layouts (tables, complex text styling).

Real-time collaboration: Frequently executing command.executeSetValue() or updating multiple remote selections/cursors concurrently forces sequential, main-thread-blocking canvas repaints.

Fluid Viewport Mutations: Smooth mobile touch-scrolling, pinch-to-zoom scaling, and rapid page-turning.

Under heavy text mutations or state modifications, the sequential use of ctx.fillText(), ctx.fillRect(), and context state switches inside src/editor/core/draw/particle/ can lead to main-thread processing delays and dropped frames.

Off-screen Texture Atlas: Unique characters and font styles are rasterized once to a hidden canvas, generating a glyph lookup texture.

Unified Vertex Buffer: Instead of hundreds of isolated ctx.fillText calls per page, the canvas paths and text tokens are converted to flat vertex geometry matrices [X, Y, Width, Height] and UV texture coordinates.

GPU Acceleration: The graphics card processes and composites the entire view frame in a single unified draw call, resulting in locked 60 FPS scrolling and instantaneous zooming/pans.

What does the proposed API look like?

1.Introduce an abstract class or interface (IRenderer) that outlines core draw hooks:
interface IRenderer {
clear(): void;
drawText(char: string, x: number, y: number, style: IElementStyle): void;
drawRect(x: number, y: number, w: number, h: number, style: IRectStyle): void;
drawImage(image: HTMLImageElement, x: number, y: number, w: number, h: number): void;
flush(): void; // Trigger draw batching
}

  1. Modernize the Leaf Nodes:
    Refactor modules like TextParticle.ts and TableParticle.ts to consume the injected renderer pipeline rather than directly mutating this.ctx:

// Inside TextParticle.ts
// Old: this.ctx.fillText(char, x, y);
this.renderer.drawText(char, x, y, style);

  1. Provide Opt-In WebGL Initialization:
    Introduce a configuration flag (renderMode: 'canvas2d' | 'webgl') within the initialization parameters. Selecting webgl spins up a dedicated vertex/fragment shader pipeline and initializes the font texture atlas manager.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions