Add native self-hosted instance connection to fluxer_desktop
Trimmed monorepo checkout (fluxer_desktop + packages/voice_engine_v2 + tools/ci) with a "Connect to a Different Server" menu item and popout that lets the desktop app switch to any self-hosted Fluxer instance, plus fixes for well-known discovery on single-domain self-hosted deployments and a false-positive ERR_ABORTED on same-origin client redirects during the switch. Defaults to chat.fluxr.chat and uses an isolated userData directory from the official build.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"measured_at": "85e057a273fd",
|
||||
"host": "darwin-arm64-apple-silicon",
|
||||
"regression_budget_percent": 5.0,
|
||||
"criterion_args": {
|
||||
"warm_up_time_sec": 2,
|
||||
"measurement_time_sec": 5
|
||||
},
|
||||
"benches": {
|
||||
"frame_bus::get_sink": {
|
||||
"median_ns": 13.292,
|
||||
"low_ns": 13.189,
|
||||
"high_ns": 13.408,
|
||||
"budget_percent_override": 10.0,
|
||||
"note": "~13ns op; noise floor reasoning."
|
||||
},
|
||||
"frame_bus::get_sink_miss": {
|
||||
"median_ns": 3.9658,
|
||||
"low_ns": 3.9444,
|
||||
"high_ns": 3.9918,
|
||||
"budget_percent_override": 15.0,
|
||||
"note": "~4ns op; below the practical resolution of repeated criterion runs."
|
||||
},
|
||||
"frame_bus::native_handle_enqueue/nv12_320x180": {
|
||||
"median_ns": 1.808,
|
||||
"low_ns": 1.7961,
|
||||
"high_ns": 1.8205,
|
||||
"budget_percent_override": 15.0,
|
||||
"note": "~2ns op; below the practical resolution of repeated criterion runs."
|
||||
},
|
||||
"frame_bus::native_handle_enqueue/nv12_1920x1080": {
|
||||
"median_ns": 1.8086,
|
||||
"low_ns": 1.8008,
|
||||
"high_ns": 1.8171,
|
||||
"budget_percent_override": 15.0,
|
||||
"note": "~2ns op; below the practical resolution of repeated criterion runs."
|
||||
},
|
||||
"frame_bus::native_handle_enqueue/nv12_3840x2160": {
|
||||
"median_ns": 1.8141,
|
||||
"low_ns": 1.7964,
|
||||
"high_ns": 1.8333,
|
||||
"budget_percent_override": 15.0,
|
||||
"note": "~2ns op; below the practical resolution of repeated criterion runs."
|
||||
},
|
||||
"frame_bus::native_handle_enqueue/bgra_320x180": {
|
||||
"median_ns": 1.8261,
|
||||
"low_ns": 1.8172,
|
||||
"high_ns": 1.8361,
|
||||
"budget_percent_override": 15.0,
|
||||
"note": "~2ns op; below the practical resolution of repeated criterion runs."
|
||||
},
|
||||
"frame_bus::native_handle_enqueue/bgra_1920x1080": {
|
||||
"median_ns": 1.7952,
|
||||
"low_ns": 1.7877,
|
||||
"high_ns": 1.8027,
|
||||
"budget_percent_override": 15.0,
|
||||
"note": "~2ns op; below the practical resolution of repeated criterion runs."
|
||||
},
|
||||
"frame_bus::enqueue_discard/nv12_320x180": {
|
||||
"median_ns": 1391.4,
|
||||
"low_ns": 1342.4,
|
||||
"high_ns": 1455.8,
|
||||
"budget_percent_override": 20.0,
|
||||
"note": "Allocator-bound: bench does vec![0; total] per iter. Run-to-run sigma observed ~15%; budget set above that."
|
||||
},
|
||||
"frame_bus::enqueue_discard/nv12_1920x1080": {
|
||||
"median_ns": 29502.0,
|
||||
"low_ns": 28397.0,
|
||||
"high_ns": 30819.0,
|
||||
"budget_percent_override": 20.0,
|
||||
"note": "Allocator-bound; see nv12_320x180 note."
|
||||
},
|
||||
"frame_bus::enqueue_discard/nv12_3840x2160": {
|
||||
"median_ns": 121900.0,
|
||||
"low_ns": 114880.0,
|
||||
"high_ns": 129680.0,
|
||||
"budget_percent_override": 25.0,
|
||||
"note": "Largest 4K allocator-bound bench; widest budget."
|
||||
},
|
||||
"frame_bus::enqueue_discard/bgra_320x180": {
|
||||
"median_ns": 2807.2,
|
||||
"low_ns": 2695.1,
|
||||
"high_ns": 2937.6,
|
||||
"budget_percent_override": 20.0,
|
||||
"note": "Allocator-bound; see nv12_320x180 note."
|
||||
},
|
||||
"frame_bus::enqueue_discard/bgra_1920x1080": {
|
||||
"median_ns": 83692.0,
|
||||
"low_ns": 78328.0,
|
||||
"high_ns": 90200.0,
|
||||
"budget_percent_override": 25.0,
|
||||
"note": "Allocator-bound 1080p BGRA bench; widest budget."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use criterion::{Criterion, Throughput, criterion_group, criterion_main};
|
||||
use fluxer_webrtc_sender::bench_internals::{
|
||||
BlurScratch, MaskRefiner, blur_plane_masked, composite_masked_plane,
|
||||
};
|
||||
use std::hint::black_box;
|
||||
|
||||
const BENCH_WIDTH: usize = 1280;
|
||||
const BENCH_HEIGHT: usize = 720;
|
||||
const BENCH_BLUR_RADIUS_PASS: usize = 6;
|
||||
const BENCH_MASK_FEATHER_PX: usize = 64;
|
||||
|
||||
fn synth_plane(seed: usize) -> Vec<u8> {
|
||||
let mut plane = vec![0u8; BENCH_WIDTH * BENCH_HEIGHT];
|
||||
for (index, value) in plane.iter_mut().enumerate() {
|
||||
*value = ((index * 31 + seed) % 251) as u8;
|
||||
}
|
||||
plane
|
||||
}
|
||||
|
||||
fn synth_person_mask() -> Vec<u8> {
|
||||
let mut mask = vec![0u8; BENCH_WIDTH * BENCH_HEIGHT];
|
||||
let person_edge = BENCH_WIDTH / 2;
|
||||
for row in mask.chunks_exact_mut(BENCH_WIDTH) {
|
||||
for (x, value) in row.iter_mut().enumerate() {
|
||||
*value = if x < person_edge {
|
||||
255
|
||||
} else if x < person_edge + BENCH_MASK_FEATHER_PX {
|
||||
(255 - (x - person_edge) * 255 / BENCH_MASK_FEATHER_PX) as u8
|
||||
} else {
|
||||
0
|
||||
};
|
||||
}
|
||||
}
|
||||
mask
|
||||
}
|
||||
|
||||
fn bench_blur_plane_masked(c: &mut Criterion) {
|
||||
let source = synth_plane(7);
|
||||
let mask = synth_person_mask();
|
||||
let mut plane = source.clone();
|
||||
let mut scratch = BlurScratch::new(BENCH_WIDTH, BENCH_HEIGHT);
|
||||
|
||||
let mut group = c.benchmark_group("camera_background::blur_plane_masked");
|
||||
group.throughput(Throughput::Bytes((BENCH_WIDTH * BENCH_HEIGHT) as u64));
|
||||
group.bench_function("1280x720_radius_pass6", |b| {
|
||||
b.iter(|| {
|
||||
plane.copy_from_slice(&source);
|
||||
blur_plane_masked(
|
||||
black_box(&mut plane),
|
||||
BENCH_WIDTH,
|
||||
BENCH_HEIGHT,
|
||||
black_box(&mask),
|
||||
BENCH_BLUR_RADIUS_PASS,
|
||||
&mut scratch,
|
||||
);
|
||||
black_box(&plane);
|
||||
})
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn bench_mask_refine(c: &mut Criterion) {
|
||||
let luma = synth_plane(13);
|
||||
let raw_mask = synth_person_mask();
|
||||
let mut mask = raw_mask.clone();
|
||||
let mut refiner = MaskRefiner::new(BENCH_WIDTH, BENCH_HEIGHT);
|
||||
|
||||
let mut group = c.benchmark_group("camera_background::mask_refine");
|
||||
group.throughput(Throughput::Bytes((BENCH_WIDTH * BENCH_HEIGHT) as u64));
|
||||
group.bench_function("1280x720_guided_refine", |b| {
|
||||
b.iter(|| {
|
||||
mask.copy_from_slice(&raw_mask);
|
||||
refiner.refine(black_box(&luma), black_box(&mut mask));
|
||||
black_box(&mask);
|
||||
})
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn bench_composite_masked_plane(c: &mut Criterion) {
|
||||
let source = synth_plane(11);
|
||||
let background = synth_plane(151);
|
||||
let mask = synth_person_mask();
|
||||
let mut plane = source.clone();
|
||||
|
||||
let mut group = c.benchmark_group("camera_background::composite_masked_plane");
|
||||
group.throughput(Throughput::Bytes((BENCH_WIDTH * BENCH_HEIGHT) as u64));
|
||||
group.bench_function("1280x720_feathered_mask", |b| {
|
||||
b.iter(|| {
|
||||
plane.copy_from_slice(&source);
|
||||
composite_masked_plane(
|
||||
black_box(&mut plane),
|
||||
black_box(&background),
|
||||
BENCH_WIDTH,
|
||||
BENCH_HEIGHT,
|
||||
&mask,
|
||||
);
|
||||
black_box(&plane);
|
||||
})
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
bench_blur_plane_masked,
|
||||
bench_mask_refine,
|
||||
bench_composite_masked_plane
|
||||
);
|
||||
criterion_main!(benches);
|
||||
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use criterion::{Criterion, Throughput, criterion_group, criterion_main};
|
||||
use fluxer_webrtc_sender::bench_internals::{
|
||||
DEEP_FILTER_FRAME_SAMPLES, DEEP_FILTER_NOISE_REDUCTION_LEVEL_MAX, DeepFilterProcessor,
|
||||
};
|
||||
use std::hint::black_box;
|
||||
|
||||
fn next_noise_sample(seed: &mut u32) -> i16 {
|
||||
*seed = seed.wrapping_mul(1_664_525).wrapping_add(1_013_904_223);
|
||||
((*seed >> 16) as u16 as i16) / 4
|
||||
}
|
||||
|
||||
fn noise_frame(seed: &mut u32) -> Vec<i16> {
|
||||
let mut frame = vec![0i16; DEEP_FILTER_FRAME_SAMPLES];
|
||||
for sample in frame.iter_mut() {
|
||||
*sample = next_noise_sample(seed);
|
||||
}
|
||||
frame
|
||||
}
|
||||
|
||||
fn bench_deep_filter_process_frame(c: &mut Criterion) {
|
||||
let mut processor = DeepFilterProcessor::new(DEEP_FILTER_NOISE_REDUCTION_LEVEL_MAX)
|
||||
.expect("embedded model must initialize");
|
||||
let mut seed = 0x9e37_79b9u32;
|
||||
let mut group = c.benchmark_group("deep_filter");
|
||||
group.throughput(Throughput::Elements(DEEP_FILTER_FRAME_SAMPLES as u64));
|
||||
group.bench_function("process_frame_10ms", |bencher| {
|
||||
bencher.iter_batched(
|
||||
|| noise_frame(&mut seed),
|
||||
|mut frame| {
|
||||
processor
|
||||
.process_frame(black_box(&mut frame))
|
||||
.expect("processing must succeed");
|
||||
frame
|
||||
},
|
||||
criterion::BatchSize::SmallInput,
|
||||
);
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_deep_filter_process_frame);
|
||||
criterion_main!(benches);
|
||||
@@ -0,0 +1,220 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
|
||||
use fluxer_screen_frame_bus::{
|
||||
BgraFrame, EnqueueOutcome, NATIVE_SCREEN_FRAME_SINK_ACCEPTED,
|
||||
NATIVE_SCREEN_FRAME_SINK_HANDLE_MAGIC, NATIVE_SCREEN_FRAME_SINK_HANDLE_VERSION,
|
||||
NativeScreenFrameSinkHandle, Nv12Frame, ScreenFrame, ScreenFrameSink, get_sink, register_sink,
|
||||
unregister_sink,
|
||||
};
|
||||
use std::ffi::c_void;
|
||||
use std::hint::black_box;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
struct DiscardSink(AtomicU64);
|
||||
impl ScreenFrameSink for DiscardSink {
|
||||
fn enqueue(&self, _frame: ScreenFrame) -> EnqueueOutcome {
|
||||
self.0.fetch_add(1, Ordering::Relaxed);
|
||||
EnqueueOutcome::Accepted
|
||||
}
|
||||
}
|
||||
|
||||
struct NativeDiscardSink(AtomicU64);
|
||||
|
||||
unsafe extern "C" fn retain_native_discard_sink(context: *const c_void) {
|
||||
unsafe { Arc::increment_strong_count(context.cast::<NativeDiscardSink>()) };
|
||||
}
|
||||
|
||||
unsafe extern "C" fn release_native_discard_sink(context: *const c_void) {
|
||||
unsafe { drop(Arc::from_raw(context.cast::<NativeDiscardSink>())) };
|
||||
}
|
||||
|
||||
unsafe extern "C" fn enqueue_native_discard_nv12(
|
||||
context: *const c_void,
|
||||
data: *const u8,
|
||||
data_len: usize,
|
||||
_width: u32,
|
||||
_height: u32,
|
||||
_stride_y: u32,
|
||||
_stride_uv: u32,
|
||||
_timestamp_us: i64,
|
||||
) -> u32 {
|
||||
if !context.is_null() && !data.is_null() && data_len > 0 {
|
||||
unsafe {
|
||||
(*context.cast::<NativeDiscardSink>())
|
||||
.0
|
||||
.fetch_add(1, Ordering::Relaxed)
|
||||
};
|
||||
}
|
||||
NATIVE_SCREEN_FRAME_SINK_ACCEPTED
|
||||
}
|
||||
|
||||
unsafe extern "C" fn enqueue_native_discard_bgra(
|
||||
context: *const c_void,
|
||||
data: *const u8,
|
||||
data_len: usize,
|
||||
_width: u32,
|
||||
_height: u32,
|
||||
_stride: u32,
|
||||
_timestamp_us: i64,
|
||||
) -> u32 {
|
||||
if !context.is_null() && !data.is_null() && data_len > 0 {
|
||||
unsafe {
|
||||
(*context.cast::<NativeDiscardSink>())
|
||||
.0
|
||||
.fetch_add(1, Ordering::Relaxed)
|
||||
};
|
||||
}
|
||||
NATIVE_SCREEN_FRAME_SINK_ACCEPTED
|
||||
}
|
||||
|
||||
fn native_discard_handle() -> (
|
||||
Arc<NativeDiscardSink>,
|
||||
fluxer_screen_frame_bus::NativeScreenFrameSinkHandleRef,
|
||||
) {
|
||||
let sink = Arc::new(NativeDiscardSink(AtomicU64::new(0)));
|
||||
let raw_context = Arc::into_raw(sink.clone()).cast::<c_void>();
|
||||
let handle = NativeScreenFrameSinkHandle {
|
||||
magic: NATIVE_SCREEN_FRAME_SINK_HANDLE_MAGIC,
|
||||
version: NATIVE_SCREEN_FRAME_SINK_HANDLE_VERSION,
|
||||
context: raw_context,
|
||||
retain: retain_native_discard_sink,
|
||||
release: release_native_discard_sink,
|
||||
enqueue_nv12: Some(enqueue_native_discard_nv12),
|
||||
enqueue_bgra: Some(enqueue_native_discard_bgra),
|
||||
enqueue_mac_cv_pixel_buffer: None,
|
||||
enqueue_dmabuf: None,
|
||||
enqueue_shared_texture: None,
|
||||
};
|
||||
let retained = unsafe { handle.retain_ref().expect("valid native sink handle") };
|
||||
unsafe { release_native_discard_sink(raw_context) };
|
||||
(sink, retained)
|
||||
}
|
||||
|
||||
fn bench_registry_lookup(c: &mut Criterion) {
|
||||
let id = format!("bench:registry:{}", std::process::id());
|
||||
register_sink(
|
||||
id.clone(),
|
||||
Arc::new(DiscardSink(AtomicU64::new(0))) as Arc<dyn ScreenFrameSink>,
|
||||
);
|
||||
|
||||
c.bench_function("frame_bus::get_sink", |b| {
|
||||
b.iter(|| {
|
||||
let s = get_sink(black_box(id.as_str()));
|
||||
black_box(s);
|
||||
})
|
||||
});
|
||||
|
||||
unregister_sink(&id);
|
||||
}
|
||||
|
||||
fn synth_nv12(width: u32, height: u32) -> ScreenFrame {
|
||||
let total = (width * height) as usize + (width * (height / 2)) as usize;
|
||||
let data = vec![0x80u8; total];
|
||||
ScreenFrame::Nv12(Nv12Frame {
|
||||
data: data.into(),
|
||||
width,
|
||||
height,
|
||||
stride_y: width,
|
||||
stride_uv: width,
|
||||
timestamp_us: 1,
|
||||
})
|
||||
}
|
||||
|
||||
fn synth_bgra(width: u32, height: u32) -> ScreenFrame {
|
||||
let total = (width * height * 4) as usize;
|
||||
let data = vec![0xff; total];
|
||||
ScreenFrame::Bgra(BgraFrame {
|
||||
data,
|
||||
width,
|
||||
height,
|
||||
stride: width * 4,
|
||||
timestamp_us: 1,
|
||||
})
|
||||
}
|
||||
|
||||
fn bench_discard_sink_enqueue(c: &mut Criterion) {
|
||||
let id = format!("bench:discard:{}", std::process::id());
|
||||
let sink = Arc::new(DiscardSink(AtomicU64::new(0)));
|
||||
register_sink(id.clone(), sink.clone() as Arc<dyn ScreenFrameSink>);
|
||||
|
||||
let mut group = c.benchmark_group("frame_bus::enqueue_discard");
|
||||
for (label, w, h) in [
|
||||
("nv12_320x180", 320u32, 180u32),
|
||||
("nv12_1920x1080", 1920, 1080),
|
||||
("nv12_3840x2160", 3840, 2160),
|
||||
("bgra_320x180", 320, 180),
|
||||
("bgra_1920x1080", 1920, 1080),
|
||||
] {
|
||||
let bytes = if label.starts_with("nv12") {
|
||||
((w * h) + (w * (h / 2))) as u64
|
||||
} else {
|
||||
(w * h * 4) as u64
|
||||
};
|
||||
group.throughput(Throughput::Bytes(bytes));
|
||||
group.bench_with_input(BenchmarkId::from_parameter(label), &(), |b, _| {
|
||||
b.iter(|| {
|
||||
let frame = if label.starts_with("nv12") {
|
||||
synth_nv12(w, h)
|
||||
} else {
|
||||
synth_bgra(w, h)
|
||||
};
|
||||
let s = get_sink(id.as_str()).unwrap();
|
||||
let outcome = s.enqueue(black_box(frame));
|
||||
black_box(outcome);
|
||||
})
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
unregister_sink(&id);
|
||||
}
|
||||
|
||||
fn bench_native_handle_enqueue(c: &mut Criterion) {
|
||||
let (_sink, handle) = native_discard_handle();
|
||||
let mut group = c.benchmark_group("frame_bus::native_handle_enqueue");
|
||||
for (label, w, h) in [
|
||||
("nv12_320x180", 320u32, 180u32),
|
||||
("nv12_1920x1080", 1920, 1080),
|
||||
("nv12_3840x2160", 3840, 2160),
|
||||
("bgra_320x180", 320, 180),
|
||||
("bgra_1920x1080", 1920, 1080),
|
||||
] {
|
||||
let bytes = if label.starts_with("nv12") {
|
||||
((w * h) + (w * (h / 2))) as usize
|
||||
} else {
|
||||
(w * h * 4) as usize
|
||||
};
|
||||
let data = vec![0x80u8; bytes];
|
||||
group.throughput(Throughput::Bytes(bytes as u64));
|
||||
group.bench_with_input(BenchmarkId::from_parameter(label), &(), |b, _| {
|
||||
b.iter(|| {
|
||||
let outcome = if label.starts_with("nv12") {
|
||||
handle.enqueue_nv12_copy(black_box(&data), w, h, w, w, 1)
|
||||
} else {
|
||||
handle.enqueue_bgra_copy(black_box(&data), w, h, w * 4, 1)
|
||||
};
|
||||
black_box(outcome);
|
||||
})
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn bench_registry_lookup_miss(c: &mut Criterion) {
|
||||
c.bench_function("frame_bus::get_sink_miss", |b| {
|
||||
b.iter(|| {
|
||||
let s = get_sink(black_box("nonexistent"));
|
||||
black_box(s);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
bench_registry_lookup,
|
||||
bench_registry_lookup_miss,
|
||||
bench_native_handle_enqueue,
|
||||
bench_discard_sink_enqueue
|
||||
);
|
||||
criterion_main!(benches);
|
||||
Reference in New Issue
Block a user