phpolygon/php-vio

PHP extension for GPU rendering (OpenGL, Vulkan, Metal), audio, video recording, streaming, and input

Maintainers

Package info

github.com/phpolygon/php-vio

Language:C

Type:php-ext

Ext name:ext-vio

pkg:composer/phpolygon/php-vio

Statistics

Installs: 25

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 1

1.10.0 2026-04-28 13:55 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:

  1. Copy php_vio.dll into your PHP ext\ directory
  2. Add extension=vio to your php.ini
  3. 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.

License

MIT