From b60bd29e573224a7155ff970b323c78b6bb4238b Mon Sep 17 00:00:00 2001 From: smeyfroi Date: Fri, 31 Jul 2026 07:57:39 +0100 Subject: [PATCH] fix(tess2): test Apple TARGET_OS_* macros by value, not defined() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TargetConditionals.h defines EVERY TARGET_OS_* macro on EVERY Apple platform, as 1 or 0 — and this very patch adds #include 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: - 064906de ('Tess2 fixes for emscripten', #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. - 9a6d0b83 ('tess2 apple silicon fix arm defines', #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 #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 #558's arm guard intact. --- apothecary/formulas/tess2/tess2.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apothecary/formulas/tess2/tess2.patch b/apothecary/formulas/tess2/tess2.patch index 9a684c839..e095acd8d 100644 --- a/apothecary/formulas/tess2/tess2.patch +++ b/apothecary/formulas/tess2/tess2.patch @@ -18,7 +18,7 @@ index c27541e..eafb0aa 100755 typedef float TESSreal; -typedef int TESSindex; -+#if defined(TARGET_OS_IPHONE) || defined(TARGET_OS_IOS) || defined(ANDROID) || defined(TARGET_ANDROID) || defined(__EMSCRIPTEN__) || defined(TARGET_EMSCRIPTEN) || defined(TARGET_OS_WATCHOS) || defined(TARGET_OS_XROS) || defined(TARGET_OS_VISION) || defined(TARGET_CATOS) || defined(__QNX__) || ((defined(__ARMEL__) || defined(__arm__) || defined(__aarch32__)) && !defined(__APPLE__)) ++#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS) || defined(ANDROID) || defined(TARGET_ANDROID) || defined(__EMSCRIPTEN__) || defined(TARGET_EMSCRIPTEN) || (defined(TARGET_OS_WATCHOS) && TARGET_OS_WATCHOS) || (defined(TARGET_OS_XROS) && TARGET_OS_XROS) || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) || (defined(TARGET_CATOS) && TARGET_CATOS) || defined(__QNX__) || ((defined(__ARMEL__) || defined(__arm__) || defined(__aarch32__)) && !defined(__APPLE__)) + typedef unsigned short TESSindex; +#else + typedef unsigned int TESSindex;