From f7115d7515aec3023d610b8121e9da74a965b522 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Sun, 19 Jul 2026 09:20:32 +0000 Subject: [PATCH 10/71] debug(macos): log every renderTile to stderr, enabled in the probe The grid is correct (row 0 dump shows all cells incl. the leading 'c' and the spaces), so the missing 'c'/'a' glyphs are a rendering issue, not engine/parse. Add SoftwareRenderTarget::setDebugTiles() to log each renderTile()'s target position, bitmap/target size, selector and normalized atlas sub-rect, and enable it in the probe (rev 4). This shows exactly what the engine emits vs where it lands, to locate whether tiles are missing, mispositioned, or sampling blank atlas regions. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01AeG2jwYMX5gdvvtUnx3PJa --- src/contour_macos/SoftwareRenderTarget.cpp | 15 +++++++++++++++ src/contour_macos/SoftwareRenderTarget.h | 5 +++++ src/contour_macos/render_probe.cpp | 3 ++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/contour_macos/SoftwareRenderTarget.cpp b/src/contour_macos/SoftwareRenderTarget.cpp index 4fbc94e4..43f3a0cd 100644 --- a/src/contour_macos/SoftwareRenderTarget.cpp +++ b/src/contour_macos/SoftwareRenderTarget.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -170,6 +171,20 @@ void SoftwareRenderTarget::uploadTile(UploadTile tile) void SoftwareRenderTarget::renderTile(RenderTile tile) { + if (_debugTiles) + std::fprintf(stderr, + "renderTile x=%d y=%d bmp=%dx%d target=%dx%d sel=%u norm=[%.3f,%.3f,%.3f,%.3f]\n", + tile.x.value, + tile.y.value, + static_cast(widthOf(tile.bitmapSize)), + static_cast(heightOf(tile.bitmapSize)), + static_cast(widthOf(tile.targetSize)), + static_cast(heightOf(tile.targetSize)), + tile.fragmentShaderSelector, + tile.normalizedLocation.x, + tile.normalizedLocation.y, + tile.normalizedLocation.width, + tile.normalizedLocation.height); _textTiles.push_back(TileCommand { std::move(tile), currentClip() }); } diff --git a/src/contour_macos/SoftwareRenderTarget.h b/src/contour_macos/SoftwareRenderTarget.h index 3e7ba315..2e40e35a 100644 --- a/src/contour_macos/SoftwareRenderTarget.h +++ b/src/contour_macos/SoftwareRenderTarget.h @@ -45,6 +45,9 @@ class SoftwareRenderTarget final: /// The composited frame, RGBA8, top-left origin, tightly packed (width*height*4 bytes). [[nodiscard]] PixelBuffer const& outputBuffer() const noexcept { return _output; } + /// When enabled, logs each renderTile() call (target position/size, selector) to stderr. + void setDebugTiles(bool on) noexcept { _debugTiles = on; } + // --- vtrasterizer::RenderTarget --- void setRenderSize(ImageSize size) override; [[nodiscard]] ImageSize renderSize() const noexcept override { return _renderSize; } @@ -146,6 +149,8 @@ class SoftwareRenderTarget final: // Deferred screenshot request: satisfied at end of the current frame's execute(). std::optional _pendingScreenshot; + + bool _debugTiles = false; }; } // namespace contour_macos diff --git a/src/contour_macos/render_probe.cpp b/src/contour_macos/render_probe.cpp index 42598f82..a7a1db07 100644 --- a/src/contour_macos/render_probe.cpp +++ b/src/contour_macos/render_probe.cpp @@ -59,7 +59,7 @@ void writePpm(std::string const& path, contour_macos::PixelBuffer const& buf) // produced it. __DATE__/__TIME__ update whenever THIS translation unit is recompiled, so the // printed line is a reliable "is the running binary built from the current source?" signal // without needing a full rebuild. -#define RENDER_PROBE_REVISION 3 +#define RENDER_PROBE_REVISION 4 int main(int argc, char** argv) { @@ -141,6 +141,7 @@ int main(int argc, char** argv) auto const surfaceSize = ImageSize { pixelWidth, pixelHeight }; auto target = contour_macos::SoftwareRenderTarget { surfaceSize }; + target.setDebugTiles(true); renderer.setRenderTarget(target); (void) renderer.applyStagedReconfigDuringSetup();