docs(gal): Update README and refresh WebGL baselines

README updates:
- Document WebGL GAL integration in kicad/common/gal/webgl/
- Add Test Scripts section with all 4 GAL scripts
- Add WebGL Integration section explaining the architecture
- Update Directory Structure to include wasm/ and baseline-webgl/
- Add Comparison Thresholds section

Baseline updates:
- Refresh 20 WebGL baseline images after KiCad integration
- Minor anti-aliasing differences from previous baselines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Viktor Vaczi 2026-01-12 10:10:26 +01:00
commit c04d5f9845
21 changed files with 119 additions and 35 deletions

View file

@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 KiB

After

Width:  |  Height:  |  Size: 491 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After