fix(tess2): test Apple TARGET_OS_* macros by value, not defined() - #561
Open
smeyfroi wants to merge 1 commit into
Open
fix(tess2): test Apple TARGET_OS_* macros by value, not defined()#561smeyfroi wants to merge 1 commit into
smeyfroi wants to merge 1 commit into
Conversation
TargetConditionals.h defines EVERY TARGET_OS_* macro on EVERY Apple platform, as 1 or 0 — and this very patch adds #include <TargetConditionals.h> to the top of tesselator.h, so the macros are always in scope. On macOS, TARGET_OS_IPHONE is defined as 0, which makes defined(TARGET_OS_IPHONE) true and silently narrows tess2's TESSindex — and with it openFrameworks' ofIndexType (ofConstants.h: typedef TESSindex ofIndexType) — to unsigned short on every macOS build. History of the regression: - 064906d ('Tess2 fixes for emscripten', openframeworks#552, 2026-04-24) rewrote the index-width condition from its original value-form #if TARGET_OS_IPHONE || ANDROID || __ARMEL__ || EMSCRIPTEN to a defined()-form. The value-form was correct: undefined identifiers evaluate to 0 in #if, and Apple documents TARGET_OS_* macros as value-tested. The rewrite flipped macOS to 16-bit indices. - 9a6d0b8 ('tess2 apple silicon fix arm defines', openframeworks#558, 2026-06-13) noticed Apple builds landing in the 16-bit branch, but attributed it to the __arm__-family defines and guarded those with !defined(__APPLE__). __arm__ / __aarch32__ are not defined on Apple arm64, so the actual macOS trigger — defined(TARGET_OS_IPHONE) — survived that fix. Downstream effect in openFrameworks: ofGLRenderer and ofGLProgrammableRenderer hardcode GL_UNSIGNED_INT for indexed draws on desktop, so a 16-bit ofIndexType makes every indexed/instanced draw read 2x past the uploaded index buffer — out-of-range vertex fetches that render as garbage triangles or nothing at all, varying with GPU heap layout, i.e. non-deterministic across launches and relinks. Diagnosed on macOS 26 / Apple silicon against of_v20260730 nightlies; of_v20251123 (which predates openframeworks#552's artifacts) is unaffected. A renderer-side fix deriving the GL index type from sizeof(ofIndexType) is proposed separately in openFrameworks; both fixes stand on their own, and this one also restores the full 32-bit vertex range for indexed meshes on macOS. Fix: test the Apple TARGET_OS_* macros by value in the canonical defined(X) && X form (robust under -Wundef), keeping plain defined() for the non-Apple macros and openframeworks#558's arm guard intact.
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.
Problem
Since #552, every macOS build gets 16-bit
TESSindex— and with it a 16-bitofIndexTypein openFrameworks (ofConstants.h: typedef TESSindex ofIndexType). Downstream, the OF renderers hardcodeGL_UNSIGNED_INTfor indexed draws on desktop, so every indexed/instanced draw reads 2× past the uploaded index buffer: out-of-range vertex fetches that render as garbage triangles or nothing at all, varying with GPU heap layout — non-deterministic across launches and relinks. It also caps indexed meshes at 65k vertices on macOS. Diagnosed on macOS 26 / Apple silicon against of_v20260730 nightlies; of_v20251123 (predating #552's artifacts) is unaffected.Cause
TargetConditionals.hdefines everyTARGET_OS_*macro on every Apple platform — as 1 or 0. On macOS,TARGET_OS_IPHONEis defined as 0, sodefined(TARGET_OS_IPHONE)is true. And this very patch adds#include <TargetConditionals.h>to the top oftesselator.h, so the macros are always in scope.History:
064906de, "Tess2 fixes for emscripten") rewrote the index-width condition from its original value-form —#if TARGET_OS_IPHONE || ANDROID || __ARMEL__ || EMSCRIPTEN— to adefined()-form. The value-form was correct: undefined identifiers evaluate to 0 in#if, and Apple documentsTARGET_OS_*macros as value-tested. The rewrite flipped macOS to 16-bit indices.9a6d0b83, "tess2 apple silicon fix arm defines") noticed Apple builds landing in the 16-bit branch, but attributed it to the__arm__-family defines and guarded those with!defined(__APPLE__).__arm__/__aarch32__aren't defined on Apple arm64, so the actual macOS trigger —defined(TARGET_OS_IPHONE)— survived that fix.Fix
Test the Apple
TARGET_OS_*macros by value in the canonicaldefined(X) && Xform (robust under-Wundef), keeping plaindefined()for the non-Apple macros and #558's arm guard intact.A companion openFrameworks PR makes the renderers derive the GL index type from
sizeof(ofIndexType)so they stay correct under either header: openframeworks/openFrameworks#8526. Both fixes stand alone.Verification
Applied both the current and the patched
tess2.patchto a fresh libtess2 v1.0.2 checkout with the formula's own command (patch -p1 -u -N; both apply with zero rejects), then compiled_Static_assert(sizeof(TESSindex) == EXPECT)probes against the resulting headers, all with-Wundef -Werror:sizeof(TESSindex)xcrun --sdk iphoneos, arm64)-Wundef -Werrorstaying silent confirms thedefined(X) && Xidiom is warning-clean on every target.