Repository navigation
Conversation
Member
|
Oh, the shape draw call count, yes, this issue was something we'd have to get into. From a first glance, the change looks okay to me. If draw order, blending and texturing are properly honoured, it shouldn't result in any visual differences. There is an issue with the code though: It uses C++17 features ( |
kblaschke
requested changes
Oct 15, 2026
kblaschke
left a comment
Member
There was a problem hiding this comment.
Code must compile with C++14, but uses C++17 features.
Author
|
Thanks for taking a look, I'll push an update targeting C++14 when I get some time (probably over the weekend) :) |
CustomShape::Draw drew every instance with its own shader/uniform setup, buffer upload and glDrawElements. A shape can have up to 1024 instances, and drivers with a high per-draw cost (macOS's OpenGL-over-Metal layer, which starts a new render pass per draw) spend most of the frame on it: a preset with 1300 instances ran at 15 fps on an M-series Mac. Collect the fills of consecutive instances that share a blend mode and texturing into one indexed triangle list and draw them together. Borders are still drawn per instance, after flushing the batch, so the draw order (and the output) is unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A border forced a flush of the fill batch, then one draw per outline pass (four with thickOutline), each with its own buffer upload, so a 1024-instance shape with borders still made ~5000 draw calls per frame. Additive blending is order-independent, so borders of additive instances are now collected as a line list and drawn right after their fills. Non-additive borders keep the exact per-instance order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fa7ad
force-pushed
the
batch-custom-shape-instances
branch
from
October 16, 2026 10:57
194cf2b to
869913d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi, a heads-up before anything else: these changes were written by Claude (LLM/AI), not by me, and I don't know the projectM codebase at all. I've tested them visually and checked the frame rate, but I can't vouch for them beyond that. If you don't take AI-generated contributions, or would rather not review code from someone who can't fully explain it, please feel free to close this outright. No hard feelings.
Background
I'm building a small native macOS frontend for libprojectM 4.x for personal use and experimentation here. These patches came out of chasing slow presets there.
Problem
CustomShape::Draw() makes at least one draw call per instance, and shapes can have up to 1024 instances. On macOS, where OpenGL runs on top of Metal and each draw call is expensive, that cost dominates:
Changes
Results (Apple Silicon, macOS):
Things I'm unsure about
Thanks for projectM!