perspective-dev/perspective · error

Density

Error message

Density: ${message}

What it means

One-time console warning from the density chart renderer when a requested signed-density mode must be downgraded. Specifically, 'extreme' mode needs WebGL2 features (MAX blend and a second color attachment); on a WebGL1 context the renderer silently falls back to 'mean' and warns once per density cache.

Solutions

  1. Ensure the browser/context provides WebGL2 (update browser or GPU drivers)
  2. Check that the canvas context creation isn't forcing WebGL1 via context attributes
  3. Accept the fallback to mean mode, which renders correctly with reduced fidelity
  4. Request or configure a mode supported by WebGL1 if the target environment cannot provide WebGL2
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at packages/viewer-charts/src/ts/charts/cartesian/glyphs/density.ts:618 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of perspective-dev/perspective@11c8238c0c (2026-09-09). Data as JSON: /api/errors/8e7b9d8c378297ed. Report an issue: GitHub.

Appendix: source

Thrown at packages/viewer-charts/src/ts/charts/cartesian/glyphs/density.ts:618

        if (requested === "extreme" && !glManager.isWebGL2) {
            this.warnDowngradeOnce(
                cache,
                "extreme mode requires WebGL2 (for MAX blend and a second color attachment); falling back to mean.",
            );
            return "mean";
        }

        return requested;
    }

    private warnDowngradeOnce(cache: DensityCache, message: string): void {
        if (cache.signedDowngradeWarned) {
            return;
        }

        cache.signedDowngradeWarned = true;
        console.warn(`Density: ${message}`);
    }

    /**
     * Shared splat → resolve pipeline. `dispatchSplats(cb)` iterates
     * the series ranges the caller wants drawn, invoking
     * `cb(slotOffset, count)` per range — `drawSeries` passes a single
     * range, `draw` iterates every series. Internally branches on the
     * active color mode: density/mean/signed share the single-target
     * heat-only pass, `extreme` runs either an MRT single-pass or two
     * sequential passes depending on extension support.
     */
    private runSplatAndResolve(
        chart: CartesianChart,
        glManager: WebGLContextManager,
        cache: DensityCache,
        projection: Float32Array,
        dispatchSplats: (
            cb: (slotOffset: number, count: number) => void,

View on GitHub (pinned to 11c8238c0c)