Skip to content

[ui] Graph canvas is black on high-DPI/large displays: EffectComposer MSAA render target exceeds GPU allocation (glRenderbufferStorageMultisample too large) due to uncapped setPixelRatio(dpr) #648

Closed

Description

@AndreLFSMartins

Version

codebase-memory-mcp 0.8.1 (darwin-arm64, ui variant)

Platform

macOS 26.5.1 (Apple M5 Pro), Brave + Chrome. Reproduces on any Chromium browser when the window is large / on a high-DPI display.

What happened

Clicking View Graph shows the Graph tab with the correct sidebar, filters, and node/edge counts (e.g. 2,648 nodes / 5,095 edges), but the 3D canvas is entirely black. No UI error, ErrorBoundary does not trigger. Same black-canvas symptom as the (closed) #453, but a different root cause — see below.

Root cause (confirmed via chrome://gpu log)

The post-processing pipeline (EffectComposer + RenderPass, present in the served bundle) creates a multisampled render target sized to the canvas backing store, which is cssSize × devicePixelRatio. The bundle calls renderer.setPixelRatio(dpr) with the uncapped device DPR. On a large, high-DPI display the multisampled renderbuffer exceeds the GPU's max allocation:

GL_INVALID_OPERATION: glRenderbufferStorageMultisample: Texture total allocation size is too large.
GL_INVALID_FRAMEBUFFER_OPERATION: glClear: Framebuffer is incomplete: Attachment has zero size.
GL_INVALID_FRAMEBUFFER_OPERATION: glDrawElementsInstanced: Framebuffer is incomplete: Attachment has zero size.

Because the MSAA renderbuffer allocation fails, the composer's framebuffer attachment ends up zero-sized, every subsequent glClear/glDrawElementsInstanced/glBlitFramebuffer targets an incomplete framebuffer, and nothing is drawn → black canvas. The MCP server, the data, and plain WebGL2 are all fine (a WebGL1 test page renders a cube normally).

GPU context from the log:

  • GL_RENDERER: ANGLE (Apple, ANGLE Metal Renderer: Apple M5 Pro)
  • Max. MSAA samples: 8
  • Displays: internal 1800x1169 @ scale 2, external 2560x1440 @ scale 2, external 3200x1800 @ scale 2

Reproduction

  1. Index any repo and open the graph UI on a high-DPI display (devicePixelRatio = 2).
  2. Maximize the browser window on a large/high-res monitor.
  3. Click View Graph → black canvas; chrome://gpu Log Messages show glRenderbufferStorageMultisample: Texture total allocation size is too large.
  4. Workaround that confirms the cause: shrink the window (or Cmd - zoom out, or move to a lower-res display) and reload → the graph renders. This proves it is the canvas/render-target size, not Shields/CDN/data.

Suggested fix

Cap the renderer pixel ratio for the WebGL canvas / composer, e.g.:

renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5))

or, more robustly, clamp the composer's render-target dimensions to gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) (and to a sane total-bytes budget), and/or fall back to antialias: false / samples: 0 on the composer when the would-be allocation exceeds the limit. R3F's <Canvas dpr={[1, 1.5]}> is the one-line equivalent.

Bonus: when glRenderbufferStorageMultisample fails, surface it through the ErrorBoundary instead of silently rendering black.

Activity

  1. added
    bugSomething isn't working
    ux/behaviorDisplay bugs, docs, adoption UX
    stability/performanceServer crashes, OOM, hangs, high CPU/memory
    on Jun 29, 2026
  2. DeusData commented on Jun 29, 2026

    @DeusData
    Owner

    Thanks for the strong root-cause report. I’ve triaged this under #396, #390, and #593. The fix should cap pixel ratio / render target size and degrade MSAA on oversized canvases, with a browser regression for high-DPI dimensions.

  3. added
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Jun 30, 2026
  4. winklemad commented on Jul 8, 2026

    @winklemad

    Nice root-cause write-up @AndreLFSMartins. @DeusData — since you triaged this under #396/#390/#593 and outlined the fix (cap pixel ratio / clamp the render target, degrade MSAA on oversized canvases, plus a high-DPI regression), is this open for a community PR or are you handling it as part of that batch? If it's open, I'd cap the renderer's effective pixel ratio (Math.min(window.devicePixelRatio, 1.5) / R3F dpr={[1, 1.5]}), clamp the composer's render target against gl.MAX_RENDERBUFFER_SIZE, fall back to samples: 0 when the allocation would still exceed the limit, and surface the failure through the ErrorBoundary as suggested — plus the high-DPI-dimensions regression you mentioned. Happy to open a PR, just confirm it's mine to take.

  5. added
    awaiting-reporterWaiting on the reporter for info/repro; stale bot will warn then close
    on Jul 8, 2026
  6. github-actions commented on Jul 8, 2026

    @github-actions

    Thanks for the report! To move this forward we need a bit more so we can reproduce it ourselves:

    • the codebase-memory-mcp --version you're on
    • the exact steps or command you ran
    • a public repo (or a small dummy snippet) that shows the problem — please don't paste proprietary code

    Once that's here we'll pick it straight back up. Heads-up: issues left awaiting-reporter are automatically closed after a few weeks of silence, but a comment reopens the door anytime.

  7. DeusData commented on Jul 8, 2026

    @DeusData
    Owner

    v0.9.0 includes graph UI scaled rendering, contrast controls, offline labels, and layout stability fixes. Could you retest the black-canvas case on v0.9.0 and confirm whether it still occurs on your display/browser? Marking awaiting-reporter.

  8. winklemad commented on Jul 8, 2026

    @winklemad

    Retested on v0.9.0 and the black canvas is gone for me — the 3D graph renders correctly maximized full-screen on an Apple-silicon Retina display (macOS 26.2, devicePixelRatio 2, Chromium), with a ~2k-node graph. Looks like the v0.9.0 scaled-rendering work resolved it. I'm not the original reporter, so @AndreLFSMartins may want to confirm on their exact display too, but from my side this is fixed. Thanks for the quick turnaround!

  9. added this to the 0.9.1-rc milestone on Jul 8, 2026
  10. removed
    awaiting-reporterWaiting on the reporter for info/repro; stale bot will warn then close
    on Jul 14, 2026
  11. DeusData commented on Sep 25, 2026

    @DeusData
    Owner

    Thank you, @AndreLFSMartins, for an outstanding root-cause analysis. Your chrome://gpu evidence and the suggested fix were spot on. The canvas pixel ratio is now capped at 1.5, with a regression test (d9d7065, shipped in v0.9.0). @winklemad confirmed that the black canvas is gone on a Retina display, so thank you too! Closing as fixed. If your 3200×1800 display still shows it on v0.11.0, please reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memoryux/behaviorDisplay bugs, docs, adoption UX

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions