Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5b5ec15ead | |||
| c9ff144492 | |||
| 7930d2f0f4 |
@@ -30,15 +30,17 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
// --- EGL_EXT_image_dma_buf_import(+_modifiers) constants (khronos-egl exposes none) ------
|
||||
const EGL_LINUX_DMA_BUF_EXT: egl::Enum = 0x3270;
|
||||
const EGL_LINUX_DRM_FOURCC_EXT: usize = 0x3271;
|
||||
const EGL_DMA_BUF_PLANE0_FD_EXT: usize = 0x3272;
|
||||
const EGL_DMA_BUF_PLANE0_OFFSET_EXT: usize = 0x3273;
|
||||
const EGL_DMA_BUF_PLANE0_PITCH_EXT: usize = 0x3274;
|
||||
const EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT: usize = 0x3443;
|
||||
const EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT: usize = 0x3444;
|
||||
const EGL_WIDTH: usize = 0x3057;
|
||||
const EGL_HEIGHT: usize = 0x3056;
|
||||
const EGL_NONE: usize = 0x3038;
|
||||
// eglCreateImageKHR takes 32-bit EGLint attribs (the core-1.5 eglCreateImage variant is the
|
||||
// one with pointer-sized EGLAttrib) — using the wrong width feeds the driver garbage pairs.
|
||||
const EGL_LINUX_DRM_FOURCC_EXT: i32 = 0x3271;
|
||||
const EGL_DMA_BUF_PLANE0_FD_EXT: i32 = 0x3272;
|
||||
const EGL_DMA_BUF_PLANE0_OFFSET_EXT: i32 = 0x3273;
|
||||
const EGL_DMA_BUF_PLANE0_PITCH_EXT: i32 = 0x3274;
|
||||
const EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT: i32 = 0x3443;
|
||||
const EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT: i32 = 0x3444;
|
||||
const EGL_WIDTH: i32 = 0x3057;
|
||||
const EGL_HEIGHT: i32 = 0x3056;
|
||||
const EGL_NONE: i32 = 0x3038;
|
||||
const DRM_FORMAT_MOD_INVALID: u64 = 0x00ff_ffff_ffff_ffff;
|
||||
|
||||
/// `fourcc('N','V','1','2')` — the only decoder output today (8-bit 4:2:0). P010 joins when
|
||||
@@ -140,7 +142,7 @@ type EglCreateImageKhr = unsafe extern "C" fn(
|
||||
*mut c_void, // EGLContext (EGL_NO_CONTEXT for dmabuf)
|
||||
egl::Enum,
|
||||
*mut c_void, // EGLClientBuffer (null for dmabuf)
|
||||
*const usize,
|
||||
*const i32, // EGLint attrib list (KHR variant — NOT pointer-sized EGLAttrib)
|
||||
) -> *const c_void;
|
||||
type EglDestroyImageKhr = unsafe extern "C" fn(*mut c_void, *const c_void) -> egl::Boolean;
|
||||
|
||||
@@ -464,24 +466,24 @@ impl GlConverter {
|
||||
) -> Result<*const c_void> {
|
||||
let mut attribs = vec![
|
||||
EGL_WIDTH,
|
||||
width as usize,
|
||||
width as i32,
|
||||
EGL_HEIGHT,
|
||||
height as usize,
|
||||
height as i32,
|
||||
EGL_LINUX_DRM_FOURCC_EXT,
|
||||
fourcc as usize,
|
||||
fourcc as i32,
|
||||
EGL_DMA_BUF_PLANE0_FD_EXT,
|
||||
plane.fd as usize,
|
||||
plane.fd,
|
||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT,
|
||||
plane.offset as usize,
|
||||
plane.offset as i32,
|
||||
EGL_DMA_BUF_PLANE0_PITCH_EXT,
|
||||
plane.stride as usize,
|
||||
plane.stride as i32,
|
||||
];
|
||||
if modifier != DRM_FORMAT_MOD_INVALID && modifier != 0 {
|
||||
attribs.extend_from_slice(&[
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
|
||||
(modifier & 0xffff_ffff) as usize,
|
||||
(modifier & 0xffff_ffff) as u32 as i32,
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
|
||||
(modifier >> 32) as usize,
|
||||
(modifier >> 32) as u32 as i32,
|
||||
]);
|
||||
}
|
||||
attribs.push(EGL_NONE);
|
||||
@@ -497,12 +499,12 @@ impl GlConverter {
|
||||
};
|
||||
if img.is_null() {
|
||||
bail!(
|
||||
"eglCreateImageKHR rejected plane ({}x{} {:#x} mod {:#018x}): {:#x}",
|
||||
"eglCreateImageKHR rejected plane ({}x{} {:#x} mod {:#018x}): {:?}",
|
||||
width,
|
||||
height,
|
||||
fourcc,
|
||||
modifier,
|
||||
self.egl.get_error().map(|e| e as u32).unwrap_or(0)
|
||||
self.egl.get_error()
|
||||
);
|
||||
}
|
||||
Ok(img)
|
||||
|
||||
@@ -412,7 +412,7 @@ async fn session(args: Args) -> Result<()> {
|
||||
io::write_msg(
|
||||
&mut send,
|
||||
&Hello {
|
||||
abi_version: punktfunk_core::ABI_VERSION,
|
||||
abi_version: punktfunk_core::WIRE_VERSION,
|
||||
mode: args.mode,
|
||||
compositor: args.compositor,
|
||||
gamepad: args.gamepad,
|
||||
|
||||
@@ -876,7 +876,7 @@ async fn worker_main(args: WorkerArgs) {
|
||||
io::write_msg(
|
||||
&mut send,
|
||||
&Hello {
|
||||
abi_version: crate::ABI_VERSION,
|
||||
abi_version: crate::WIRE_VERSION,
|
||||
mode,
|
||||
compositor,
|
||||
gamepad,
|
||||
|
||||
@@ -54,3 +54,11 @@ pub use stats::Stats;
|
||||
/// v3: added `punktfunk_wake_on_lan` (Wake-on-LAN magic packet; the host's wake MAC(s) reach
|
||||
/// clients out-of-band via the mDNS `mac` TXT record, so no connection is required to wake).
|
||||
pub const ABI_VERSION: u32 = 3;
|
||||
|
||||
/// The punktfunk/1 **wire** version — what `Hello`/`Welcome` carry and hosts equality-check.
|
||||
/// Deliberately its own constant: [`ABI_VERSION`] tracks the embeddable **C surface**
|
||||
/// (functions a client links), which can grow without changing a single wire byte — v3's
|
||||
/// `punktfunk_wake_on_lan` is client-local, and riding the C-ABI bump onto the wire locked
|
||||
/// every new client out of every deployed host ("ABI mismatch: client 3 host 2", observed
|
||||
/// live). Bump this ONLY when the handshake/planes actually change incompatibly.
|
||||
pub const WIRE_VERSION: u32 = 2;
|
||||
|
||||
@@ -585,10 +585,10 @@ async fn serve_session(
|
||||
// the `handshake` future re-decodes for the real session — a few dozen bytes, negligible.
|
||||
let gate_hello = Hello::decode(&first).map_err(|e| anyhow!("Hello decode: {e:?}"))?;
|
||||
anyhow::ensure!(
|
||||
gate_hello.abi_version == punktfunk_core::ABI_VERSION,
|
||||
"ABI mismatch: client {} host {}",
|
||||
gate_hello.abi_version == punktfunk_core::WIRE_VERSION,
|
||||
"wire version mismatch: client {} host {}",
|
||||
gate_hello.abi_version,
|
||||
punktfunk_core::ABI_VERSION
|
||||
punktfunk_core::WIRE_VERSION
|
||||
);
|
||||
let fp = endpoint::peer_fingerprint(&conn);
|
||||
let known = fp
|
||||
@@ -654,10 +654,10 @@ async fn serve_session(
|
||||
let handshake = async {
|
||||
let hello = Hello::decode(&first).map_err(|e| anyhow!("Hello decode: {e:?}"))?;
|
||||
anyhow::ensure!(
|
||||
hello.abi_version == punktfunk_core::ABI_VERSION,
|
||||
"ABI mismatch: client {} host {}",
|
||||
hello.abi_version == punktfunk_core::WIRE_VERSION,
|
||||
"wire version mismatch: client {} host {}",
|
||||
hello.abi_version,
|
||||
punktfunk_core::ABI_VERSION
|
||||
punktfunk_core::WIRE_VERSION
|
||||
);
|
||||
// The pairing gate (require_pairing → paired? else park for delegated approval) ran above,
|
||||
// before this future, so a client reaching here is paired (or the host is `--open`).
|
||||
@@ -805,7 +805,7 @@ async fn serve_session(
|
||||
let mut key = [0u8; 16];
|
||||
rand::thread_rng().fill_bytes(&mut key);
|
||||
let welcome = Welcome {
|
||||
abi_version: punktfunk_core::ABI_VERSION,
|
||||
abi_version: punktfunk_core::WIRE_VERSION,
|
||||
udp_port,
|
||||
mode: hello.mode,
|
||||
// The post-GameStream point of punktfunk/1: Leopard GF(2¹⁶) FEC + real encryption.
|
||||
|
||||
@@ -21,6 +21,14 @@
|
||||
// clients out-of-band via the mDNS `mac` TXT record, so no connection is required to wake).
|
||||
#define ABI_VERSION 3
|
||||
|
||||
// The punktfunk/1 **wire** version — what `Hello`/`Welcome` carry and hosts equality-check.
|
||||
// Deliberately its own constant: [`ABI_VERSION`] tracks the embeddable **C surface**
|
||||
// (functions a client links), which can grow without changing a single wire byte — v3's
|
||||
// `punktfunk_wake_on_lan` is client-local, and riding the C-ABI bump onto the wire locked
|
||||
// every new client out of every deployed host ("ABI mismatch: client 3 host 2", observed
|
||||
// live). Bump this ONLY when the handshake/planes actually change incompatibly.
|
||||
#define WIRE_VERSION 2
|
||||
|
||||
// `PunktfunkHidOutput::kind` — lightbar RGB (`r`/`g`/`b` valid).
|
||||
#define PUNKTFUNK_HIDOUT_LED 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user