diff --git a/tests/gal-regression/README.md b/tests/gal-regression/README.md index e92c9ae..d0c44b1 100644 --- a/tests/gal-regression/README.md +++ b/tests/gal-regression/README.md @@ -1,13 +1,51 @@ -# GAL Regression Test Harness +# GAL Regression Test Suite -Native test harness for KiCad's OPENGL_GAL (Graphics Abstraction Layer) to enable visual regression testing of the WebGL port. +Visual regression testing for KiCad's Graphics Abstraction Layer (GAL), covering both native OpenGL and WebGL implementations. -## Purpose +## Overview -This test suite exercises KiCad's actual OPENGL_GAL implementation to: -- Generate baseline screenshots for visual regression testing -- Verify GAL API coverage (70/70 methods tested) -- Provide reference implementations for the WebGL port +This test suite validates KiCad's GAL rendering by: +- Running 28 test scenarios that exercise all 70 GAL API methods +- Comparing native OpenGL output against committed baselines +- Comparing WebGL WASM output against native (for parity verification) +- Detecting rendering regressions during development + +## WebGL GAL Integration + +The WebGL GAL implementation lives in **`kicad/common/gal/webgl/`** (~27,800 lines) and is a full port of KiCad's OPENGL_GAL to WebGL 2.0 / OpenGL ES 3.0. + +Key changes from native OpenGL: +- GLSL ES 3.0 shaders (`attribute`→`in`, `varying`→`out`, `texture2D()`→`texture()`) +- VAOs required (WebGL 2.0 requirement) +- No legacy GL (`glBegin/glEnd` replaced with VBOs) +- GLU tesselator replaced with earcut.hpp + +The WASM test harness in `wasm/` links against KiCad's WebGL GAL to verify the implementation matches native rendering. + +## Test Scripts + +| Script | Purpose | +|--------|---------| +| `scripts/build-gal-native-test.sh` | Build native OpenGL test harness (macOS) | +| `scripts/build-gal-webgl-test.sh` | Build WebGL WASM test harness | +| `scripts/test-gal-regression.sh` | **Master script**: builds both, runs tests, compares native vs baseline AND webgl vs native | +| `scripts/test-gal-webgl.sh` | WebGL regression monitor: compares webgl vs baseline-webgl | + +### Quick Start + +```bash +# Run full regression suite (recommended) +./scripts/test-gal-regression.sh + +# Run WebGL-only tests (faster, for WebGL development) +./scripts/test-gal-webgl.sh + +# Build native test only +./scripts/build-gal-native-test.sh + +# Build WebGL test only +./scripts/build-gal-webgl-test.sh +``` ## Test Scenarios @@ -44,66 +82,112 @@ This test suite exercises KiCad's actual OPENGL_GAL implementation to: | 26 | bitmap | DrawBitmap (see limitation below) | | 27 | transform-api | Transform() API documentation | -## Building +## Building & Running + +### Native Test Harness ```bash +# Build ./scripts/build-gal-native-test.sh -``` -## Running - -```bash -# Run all scenarios and save to baseline folder +# Run all scenarios ./tests/gal-regression/native/build/gal_native_test \ - --output ./tests/gal-regression/baseline + --output ./tests/gal-regression/output/native # Run specific scenario (by number) ./tests/gal-regression/native/build/gal_native_test \ - --output ./tests/gal-regression/baseline 5 + --output ./tests/gal-regression/output/native 5 # Show window (non-headless) ./tests/gal-regression/native/build/gal_native_test --show ``` +### WebGL Test Harness + +```bash +# Build +./scripts/build-gal-webgl-test.sh + +# Run via Playwright (headless) +cd tests && npx playwright test gal-webgl.spec.ts +``` + +## Baselines + +Two sets of baseline screenshots: + +| Folder | Purpose | +|--------|---------| +| `baseline/` | Native OpenGL reference (28 PNGs) | +| `baseline-webgl/` | WebGL reference (29 PNGs) | + +### Updating Baselines + +```bash +# Update native baseline (after verifying output looks correct) +cp tests/gal-regression/output/native/*.png tests/gal-regression/baseline/ + +# Update WebGL baseline +cp tests/gal-regression/output/webgl/*.png tests/gal-regression/baseline-webgl/ +``` + ## Known Limitations ### DrawBitmap (Scenario 26) The DrawBitmap test shows empty panels because OPENGL_GAL::DrawBitmap uses legacy OpenGL immediate mode (`glBegin`/`glVertex3f`/`glEnd`) which is incompatible with the shader-based rendering pipeline used by the test harness. -In KiCad's production code, DrawBitmap works because: -1. The VIEW rendering system orchestrates buffer flushes between render targets -2. GPU_MANAGER::DrawAll() deactivates the shader after flushing vertices -3. The fixed-function pipeline can then render the textured quad - -In our isolated test harness, the shader remains active throughout rendering, causing the legacy GL calls to fail silently. +In KiCad's production code, DrawBitmap works because the VIEW rendering system orchestrates buffer flushes between render targets. This is acceptable because: - DrawBitmap is primarily used for reference images in schematics -- The WebGL port will need its own bitmap rendering implementation anyway +- The WebGL port has its own bitmap rendering implementation - All other 69 GAL methods are fully tested ### Transform() API (Scenario 27) - EXCLUDED FROM COMPARISON -The Transform() method is **dead code in KiCad** - never called anywhere in the codebase. KiCad uses Rotate(), Translate(), Scale() instead. - -In native OPENGL_GAL, Transform() calls `glMultMatrixd()` which modifies GL_MODELVIEW, but VERTEX_MANAGER uses its own independent `m_transform` - so glMultMatrixd has no visible effect on rendered output. The scenario is kept for documentation but excluded from WebGL vs Native comparisons since both implementations are effectively broken (by design). +The Transform() method is **dead code in KiCad** - never called anywhere in the codebase. KiCad uses Rotate(), Translate(), Scale() instead. The scenario is kept for documentation but excluded from comparisons. ## Directory Structure ``` tests/gal-regression/ -├── README.md # This file -├── baseline/ # Reference PNG screenshots +├── README.md # This file +├── baseline/ # Native OpenGL reference (28 PNGs) +├── baseline-webgl/ # WebGL reference (29 PNGs) +├── output/ +│ ├── native/ # Fresh native test output +│ └── webgl/ # Fresh WebGL test output ├── native/ │ ├── CMakeLists.txt -│ ├── gal_native_test.cpp # Main test driver -│ ├── gal_test_accessor.cpp # Private member accessors -│ ├── kicad_stubs.cpp # KiCad symbol stubs -│ ├── bitmap_base_stub.h # Bitmap test patterns -│ ├── kifont_stub.h # Glyph factory helpers -│ └── generated/ # Shader source files +│ ├── gal_native_test.cpp # Main test driver +│ ├── gal_test_accessor.cpp # Private member accessors +│ ├── kicad_stubs.cpp # KiCad symbol stubs +│ ├── bitmap_base_stub.h # Bitmap test patterns +│ ├── kifont_stub.h # Glyph factory helpers +│ └── generated/ # Shader source files +├── wasm/ +│ ├── Makefile # WebGL WASM build +│ ├── gal_webgl_test.cpp # WASM entry point +│ ├── gal_webgl_test.html # Test page with canvas +│ ├── wasm_stubs.cpp # WASM-specific stubs +│ └── generated/ # ES 3.0 shader sources └── scenarios/ - ├── gal_test_scenarios.cpp # Scenario registry - └── scenario_*.cpp # Individual test scenarios + ├── gal_test_scenarios.cpp # Scenario registry + └── scenario_*.cpp # Individual test scenarios (shared by native & wasm) + +kicad/common/gal/webgl/ # WebGL GAL implementation (in KiCad repo) +├── webgl_gal.cpp # Main implementation +├── webgl_gal.h # Class declaration +├── gpu_manager.cpp # VBO/VAO management +├── vertex_manager.cpp # Vertex accumulation +├── shader.cpp # GLSL ES 3.0 compilation +├── glu_tess_impl.cpp # GLU tesselator (earcut.hpp) +└── ... # ~20 files total ``` + +## Comparison Thresholds + +- **Native vs Baseline**: 0% difference (exact match expected) +- **WebGL vs Native**: ~7/28 exact matches typical (minor anti-aliasing differences acceptable) +- **WebGL vs Baseline-WebGL**: 1% threshold (catches actual regressions) diff --git a/tests/gal-regression/baseline-webgl/gal-alpha-blending.png b/tests/gal-regression/baseline-webgl/gal-alpha-blending.png index ff3ab02..86c7c6c 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-alpha-blending.png and b/tests/gal-regression/baseline-webgl/gal-alpha-blending.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-arc-segments.png b/tests/gal-regression/baseline-webgl/gal-arc-segments.png index ce84e18..28c5523 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-arc-segments.png and b/tests/gal-regression/baseline-webgl/gal-arc-segments.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-bezier-curves.png b/tests/gal-regression/baseline-webgl/gal-bezier-curves.png index 8770e5a..e8f288e 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-bezier-curves.png and b/tests/gal-regression/baseline-webgl/gal-bezier-curves.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-bitmap.png b/tests/gal-regression/baseline-webgl/gal-bitmap.png index 96c770f..70233d2 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-bitmap.png and b/tests/gal-regression/baseline-webgl/gal-bitmap.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-circles.png b/tests/gal-regression/baseline-webgl/gal-circles.png index aacea32..3ceefac 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-circles.png and b/tests/gal-regression/baseline-webgl/gal-circles.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-clear-colors.png b/tests/gal-regression/baseline-webgl/gal-clear-colors.png index e20c8bc..9efc966 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-clear-colors.png and b/tests/gal-regression/baseline-webgl/gal-clear-colors.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-cursor-native.png b/tests/gal-regression/baseline-webgl/gal-cursor-native.png index 7bd25a6..d0a489f 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-cursor-native.png and b/tests/gal-regression/baseline-webgl/gal-cursor-native.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-depth-testing.png b/tests/gal-regression/baseline-webgl/gal-depth-testing.png index bc70f26..08302a6 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-depth-testing.png and b/tests/gal-regression/baseline-webgl/gal-depth-testing.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-glyphs.png b/tests/gal-regression/baseline-webgl/gal-glyphs.png index cf831fa..05c4173 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-glyphs.png and b/tests/gal-regression/baseline-webgl/gal-glyphs.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-grid-cursor.png b/tests/gal-regression/baseline-webgl/gal-grid-cursor.png index aefe1cb..edf2f3d 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-grid-cursor.png and b/tests/gal-regression/baseline-webgl/gal-grid-cursor.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-grid-native.png b/tests/gal-regression/baseline-webgl/gal-grid-native.png index 86a57c4..2353a75 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-grid-native.png and b/tests/gal-regression/baseline-webgl/gal-grid-native.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-group-caching.png b/tests/gal-regression/baseline-webgl/gal-group-caching.png index 6607ed5..12c06c8 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-group-caching.png and b/tests/gal-regression/baseline-webgl/gal-group-caching.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-hole-walls.png b/tests/gal-regression/baseline-webgl/gal-hole-walls.png index 51459b4..c7d0454 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-hole-walls.png and b/tests/gal-regression/baseline-webgl/gal-hole-walls.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-negative-mode.png b/tests/gal-regression/baseline-webgl/gal-negative-mode.png index d1f6385..c0fc330 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-negative-mode.png and b/tests/gal-regression/baseline-webgl/gal-negative-mode.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-polygons.png b/tests/gal-regression/baseline-webgl/gal-polygons.png index 806ee7d..6ecc7d6 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-polygons.png and b/tests/gal-regression/baseline-webgl/gal-polygons.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-rectangles.png b/tests/gal-regression/baseline-webgl/gal-rectangles.png index 30a5f8c..78322a6 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-rectangles.png and b/tests/gal-regression/baseline-webgl/gal-rectangles.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-render-targets.png b/tests/gal-regression/baseline-webgl/gal-render-targets.png index d2d548f..7e4947d 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-render-targets.png and b/tests/gal-regression/baseline-webgl/gal-render-targets.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-screen-transform.png b/tests/gal-regression/baseline-webgl/gal-screen-transform.png index 28064f4..aa95e87 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-screen-transform.png and b/tests/gal-regression/baseline-webgl/gal-screen-transform.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-text-attrs.png b/tests/gal-regression/baseline-webgl/gal-text-attrs.png index 083cd0a..983a36b 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-text-attrs.png and b/tests/gal-regression/baseline-webgl/gal-text-attrs.png differ diff --git a/tests/gal-regression/baseline-webgl/gal-transform-api.png b/tests/gal-regression/baseline-webgl/gal-transform-api.png index 1ae853e..83787de 100644 Binary files a/tests/gal-regression/baseline-webgl/gal-transform-api.png and b/tests/gal-regression/baseline-webgl/gal-transform-api.png differ