GeezerVison is showing github.com — feat: Linux support by triniwiz · Pull Request #189 · NativeScript/canvas
Conversation
triniwiz
commented
Nov 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Adds NativeScript Linux (GTK 4) support to canvas and its plugins, through the Node-API modules the Windows port uses.
Packages
- canvas
- A GTK 4 widget drives the
canvasnative.node Node-API module.
- 2D, WebGL and WebGL2 run on EGL using GDK's display. Offscreen surfaces use pbuffers, and transferred
OffscreenCanvas is supported.
- WebGPU runs on Vulkan. Its frames are shared with GL through exported memory.
- canvas-svg: a GTK 4 view.
- canvas-media: video and audio play through GStreamer.
- audio-context: works through its Node-API module.
- canvas-gamepad:
- Reads evdev devices through gilrs, which uses SDL's mapping database. Hot-plug is watched through udev.
- Reports the standard 17-button / 4-axis layout.
- Reading
/dev/input/event* requires read access. Desktop sessions normally grant it to gamepads.
- canvas-polyfill:
fetch works for local files.
- Blob-URL Workers work on Node-API hosts.
- The window size is taken from the app window.
- canvas-chartjs: Linux V8 ships without ICU data, so the Intl polyfills are forced on there.
- The x64 and arm64
.node modules are committed under each package's platforms/linux/lib/<arch>. They're built by tools/scripts/build-linux.sh, which needs libudev-dev on the build machine. The arm64 ones were built on Ubuntu 22.04 arm64 (glibc 2.35, GTK 4.6, clang 18) and load in Node 22 on arm64, but haven't been run in a GTK app on arm64 hardware yet.
Cross-platform fixes found along the way
- WebGL:
clearBuffer* now takes the buffer enum.
bindTransformFeedback now binds the transform feedback.
bindVertexArrayOES(null) now unbinds.
- WebGPU: subgroups are no longer advertised, because naga can't enable them yet. WGSL compile errors are now logged.
- 2D:
- Non-finite values for
lineDashOffset, globalAlpha, miterLimit and lineWidth are now ignored.
createImageBitmap accepts Blob-like sources.
- Images: an image that fails to decode now fires
error.
- Node-API: Windows-only methods are now in their own impl blocks, so the module builds on other hosts.
GPU video frames
- Display: canvas-media decodes into GL textures (
glupload ! glcolorconvert) in a GStreamer GL context that shares GDK's, and GTK shows them as GdkGLTextures. If the GL path isn't available it falls back to CPU memory; NS_CANVAS_MEDIA_CPU=1 forces the fallback.
- WebGL:
texImage2D / texImage3D with a video does a GPU blit through an EGLImage, guarded by an EGL fence.
- WebGPU:
importExternalTexture and copyExternalImageToTexture(video) read Vulkan images that GL imports and fills on the GPU, synchronised by exported semaphores, as on Windows.
- wgpu's Vulkan backend has no external textures, so
texture_external is emulated by binding the frame as a texture_2d<f32>.
- Software decode: mapped frames go to WebGL / WebGPU natively and are uploaded once.
- VA-API:
disable-vpp on vaapidecodebin fixes H.264 producing no frames on the Intel iHD driver.
1080p, process CPU:
| Scenario |
GL path |
CPU path |
| H.264 playback |
~11–16% |
~28–35% |
| VP9 playback, VA-API decode |
~11% |
~44% |
WebGL texImage2D(video): 0.19 ms per call, down from ~3.9 ms.
Not done: displaying DMABuf frames with GdkDmabufTexture (needs GTK 4.14+) and importing them straight into Vulkan. Both are TODOs.
Tests: media.video 9/9 on both paths, webgpu 19/19, webgl 83/83.
Depends on
Known gaps
- Draco decoding in a Worker (three)
webgpu_backdrop renders black
- an error in the
webgpu_cube sample
- gamepad tested only with no controller attached
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
…binds the transform feedback, bindVertexArrayOES(null) unbinds
…; log WGSL compile errors
…t and lineWidth; createImageBitmap takes Blob-like sources
…ob URL Workers on Node-API hosts
…le builds on other hosts
…cles skip the DOM-only inspector, phaser-ce's accelerometer is Android/Apple only
…rfaces and present hooks
…et driven by the Node-API module
…dow size from the app window
…ia, canvas-gamepad and audio-context
coderabbitai
Bot
commented
Nov 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Important
Review skipped
Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.
Run configuration
-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
b9fbcc04-d80e-4704-a1ac-70e7d619f416
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Share
-
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
…nvas
GStreamer's GL context shares GDK's on its EGL display: glupload ! glcolorconvert
makes RGBA textures, shown as GdkGLTextures and handed to canvas as
NSCVideoFrame descriptors (an EGLImage for WebGL, a blit into WebGPU's
exportable Vulkan image synchronized with its semaphores). videoconvert to
memory stays the fallback (NS_CANVAS_MEDIA_CPU=1, no GDK EGL, GL errors).
vaapidecodebin runs without vaapipostproc, whose NV12 buffers fail to map on
iHD (H.264 showed no frames), and the preroll frame is delivered.
__texImageVideoFrame copies a GL frame through its EGLImage into the bound
texture (texImage2D/3D, sub-images, flipY) or uploads a memory frame once.
WebGPU imports frames into an exportable Vulkan image per video, waiting on
the producer's semaphore and signalling release (devices enable
VK_KHR_external_semaphore_fd); __getAdapterLuid gives the device UUID key.
Vulkan lacks EXTERNAL_TEXTURE: external textures bind their plane as a
texture_2d<f32> that shader modules use in place of texture_external.
getCurrentFrame and the texImage3D hooks go through __texImageVideoFrame;
supportsGPUFrames/getGPUFrameTexture return NSCVideoFrame descriptors (GPU on
the same device, else memory). importExternalTexture closes frames the import
copies (Linux, Windows) instead of holding them until collected.
canvas, canvas-svg, canvas-media, canvas-gamepad and audio-context, built with tools/scripts/build-linux.sh on Ubuntu 22.04 arm64 (glibc 2.35, GTK 4.6, clang 18).
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|