phpolygon / php-vio
PHP extension for GPU rendering (OpenGL, Vulkan, Metal), audio, video recording, streaming, and input
Package info
Language:C
Type:php-ext
Ext name:ext-vio
pkg:composer/phpolygon/php-vio
Requires
- php: >=8.4
This package is auto-updated.
Last update: 2026-04-28 13:57:04 UTC
README
A PHP extension that brings GPU rendering, audio, video recording, streaming, and input handling to PHP. Foundation layer for the PHPolygon game engine.
Features
- Multi-Backend GPU Rendering — OpenGL 4.1, Vulkan (MoltenVK), Metal
- 2D Batch Renderer — Rects, circles, lines, sprites, text (z-sorted, up to 4096 items)
- 3D Pipeline — Meshes, shaders, pipelines, textures, uniform/storage buffers
- Shader Toolchain — GLSL to SPIR-V compilation, reflection, cross-compilation
- Audio — Playback via miniaudio (MP3, WAV, FLAC)
- Video Recording — H.264 encoding via FFmpeg (with VideoToolbox HW acceleration)
- Network Streaming — RTMP and SRT via FFmpeg
- Input — Keyboard, mouse, and gamepad support via GLFW
- Headless Mode — Offscreen rendering for tests and visual regression testing
- Plugin System — Extensible output/input/filter plugins
- Cross-Platform — macOS, Linux, Windows
Requirements
- PHP >= 8.4
All native libraries are optional — the extension compiles and runs without them, features are simply unavailable at runtime:
| Library | Feature | Build Flag |
|---|---|---|
| GLFW 3.4 | Windowing, input, gamepad | --with-glfw |
| glslang | GLSL to SPIR-V compilation | --with-glslang |
| SPIRV-Cross | Shader reflection & transpilation | --with-spirv-cross |
| Vulkan SDK | Vulkan backend | --with-vulkan |
| FFmpeg | Video recording & streaming | --with-ffmpeg |
| Metal (macOS framework) | Metal backend | --with-metal |
Installation
Via PIE (PHP Installer for Extensions)
pie install phpolygon/php-vio
Pre-built Binaries
Download platform-specific binaries from the Releases page. Available for:
- Linux x86_64 / ARM64
- macOS x86_64 (Intel) / ARM64 (Apple Silicon)
- Windows x64
From Source (macOS)
brew install glfw glslang spirv-cross ffmpeg
phpize
./configure --enable-vio --with-glfw --with-glslang --with-spirv-cross \
--with-vulkan --with-ffmpeg --with-metal
make -j$(sysctl -n hw.ncpu)
sudo make install
From Source (Linux)
# Ubuntu/Debian sudo apt install php-dev libglfw3-dev glslang-dev libvulkan-dev \ libavcodec-dev libavformat-dev libavutil-dev libswscale-dev \ spirv-cross libspirv-cross-c-shared-dev phpize ./configure --enable-vio --with-glfw --with-glslang --with-spirv-cross \ --with-vulkan --with-ffmpeg make -j$(nproc) sudo make install
Windows
On Windows, no build toolchain is needed — PHP extensions are distributed as pre-compiled DLLs. Download the matching DLL from the Releases page (match your PHP version and thread-safety mode), then:
- Copy
php_vio.dllinto your PHPext\directory - Add
extension=vioto yourphp.ini - Restart PHP / your web server
All backends use conditional compilation (#ifdef HAVE_*), so builds without certain dependencies compile fine — those features are simply unavailable at runtime.
Quick Start
<?php // Create a window with OpenGL backend $ctx = vio_create("opengl", [ "width" => 800, "height" => 600, "title" => "Hello VIO", ]); while (!vio_should_close($ctx)) { vio_begin($ctx); vio_clear($ctx, 0.1, 0.1, 0.1); // 2D drawing vio_rect($ctx, 50, 50, 200, 100, ["color" => 0xFF0000FF]); vio_circle($ctx, 400, 300, 60, ["color" => 0x00FF00FF]); vio_draw_2d($ctx); vio_end($ctx); vio_poll_events($ctx); } vio_close($ctx); vio_destroy($ctx);
API Overview
71 functions across these categories:
| Category | Functions |
|---|---|
| Context | vio_create, vio_begin, vio_end, vio_clear, vio_close, vio_destroy |
| Input | vio_key_pressed, vio_mouse_position, vio_mouse_button, vio_on_key |
| 2D | vio_rect, vio_circle, vio_line, vio_sprite, vio_text, vio_draw_2d |
| 3D | vio_mesh, vio_shader, vio_pipeline, vio_bind_pipeline, vio_draw |
| Textures | vio_texture, vio_bind_texture, vio_texture_load_async |
| Buffers | vio_uniform_buffer, vio_update_buffer |
| Audio | vio_audio_load, vio_audio_play, vio_audio_pause, vio_audio_stop |
| Recording | vio_recorder, vio_recorder_capture, vio_recorder_stop |
| Streaming | vio_stream, vio_stream_push, vio_stream_stop |
| Headless | vio_read_pixels, vio_save_screenshot, vio_compare_images |
| Shaders | vio_shader_reflect, shader compilation via glslang |
| Plugins | vio_plugins, vio_plugin_info |
Full API documentation: see vio.stub.php
Backends
| Backend | Status | Platforms |
|---|---|---|
| OpenGL 4.1 | Stable | macOS, Linux, Windows |
| Metal | Stable | macOS only |
| Vulkan | Experimental | macOS (MoltenVK), Linux, Windows |
| Null | Stable | All (for unit testing) |
Backend auto-selection: Metal (macOS) > Vulkan (Linux/Windows) > OpenGL > Null
Performance: Metal vs OpenGL
Benchmarked on Apple M2 Pro (macOS 26.4, 1280x720, VSync off). Measures draw + flush time only (excludes present/VSync wait).
| Scenario | Metal (median) | OpenGL (median) | Delta |
|---|---|---|---|
| 500 rects | 192 us | 179 us | +7% |
| 200 rects + 200 rounded rects + 50 text | 323 us | 313 us | +3% |
| 1000 rects + 100 text | 301 us | 374 us | -20% |
Tail latency (frame time consistency):
| Percentile | Metal | OpenGL |
|---|---|---|
| p95 | 306-601 us | 437-754 us |
| p99 | 375-674 us | 907-953 us |
Metal is slightly slower on simple scenes due to command encoding overhead, but 20% faster on heavy scenes (1000+ draw calls with text). More importantly, Metal delivers 30-40% better tail latency — fewer frame time spikes and more consistent rendering.
Testing
NO_INTERACTION=1 TEST_PHP_EXECUTABLE=$(which php) \ php run-tests.php -d extension=$PWD/modules/vio.so tests/
38 tests included, covering headless rendering, 2D/3D pipelines, shaders, audio, input, and visual regression testing.