Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ target_include_directories(driver_babble SYSTEM PRIVATE
target_include_directories(driver_babble PRIVATE ${BABBLE_GENERATED_DIR}) # This directory has babble_version.h.
add_dependencies(driver_babble babble_version)
target_compile_options(driver_babble PRIVATE -Wall -Wextra)
target_link_options(driver_babble PRIVATE -Wl,--no-undefined -static-libstdc++ -static-libgcc)
target_link_options(driver_babble PRIVATE -Wl,--no-undefined -static-libstdc++ -static-libgcc
$<$<CONFIG:Release>:-Wl,--strip-all>)
target_link_libraries(driver_babble PRIVATE dl pthread)
set_target_properties(driver_babble PROPERTIES PREFIX "")

Expand All @@ -28,7 +29,8 @@ add_executable(babble_setup src/babble_setup.cpp)
target_include_directories(babble_setup SYSTEM PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/nlohmann_json/single_include)
target_compile_options(babble_setup PRIVATE -Wall -Wextra)
target_link_options(babble_setup PRIVATE -static-libstdc++ -static-libgcc)
target_link_options(babble_setup PRIVATE -static-libstdc++ -static-libgcc
$<$<CONFIG:Release>:-Wl,--strip-all>)
set_target_properties(babble_setup PROPERTIES OUTPUT_NAME babble-setup)

# Put all the parts of the SteamVR driver folder in build/babble.
Expand Down
1 change: 1 addition & 0 deletions runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ target_link_libraries(babble_runtime PRIVATE babble_core)
set_target_properties(babble_runtime PROPERTIES OUTPUT_NAME babble-runtime
BUILD_RPATH "${THIRD_PARTY}/openvr/lib/linuxarm64" INSTALL_RPATH "$ORIGIN")
target_link_options(babble_runtime PRIVATE "-Wl,-rpath,$ORIGIN"
$<$<CONFIG:Release>:-Wl,--strip-all>
-rdynamic) # This option puts function names in crash backtraces.
if(NOT BABBLE_ASAN)
# Link libstdc++ statically because the binary must not use the libstdc++ of the OS.
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/model/babble_eye.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ bool BabbleEye::run_model(const float *x, float *y) {
half_out_.resize(os.elements());
out = half_out_.data();
}
std::vector<TensorView> iv{{const_cast<void *>(in), &is}};
std::vector<TensorView> ov{{out, &os}};
TensorView iv[] = {{const_cast<void *>(in), &is}};
TensorView ov[] = {{out, &os}};
if (!model_->run(iv, ov))
return false;
if (os.dtype == DType::F16)
Expand Down
10 changes: 6 additions & 4 deletions runtime/src/model/babble_mono_face.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ bool BabbleMonoFace::init() {
for (size_t i = 0; i < face::kShapes.size(); i++)
ids_[i] = deps_.state.add_signal(face::kShapes[i]);

tmp_a_.resize(kMaxSide * kMaxSide);
tmp_b_.resize(kMaxSide * kMaxSide);
small_.resize(kSize * kSize);
input_.resize(kSize * kSize);
out_.resize(face::kShapes.size());
Expand All @@ -96,6 +94,10 @@ void BabbleMonoFace::prepare(const Frame &f, float *input) {
const uint32_t w = std::min<uint32_t>(cur.width, kMaxSide), h = std::min<uint32_t>(cur.height, kMaxSide);
cur.width = w;
cur.height = h;
if ((gain_ != 1.0f || flip_h_ || flip_v_ || quarter_turns_) && tmp_a_.size() < size_t(w) * h) {
tmp_a_.resize(size_t(w) * h);
tmp_b_.resize(size_t(w) * h);
}

if (gain_ != 1.0f) { // The gain saturates and rounds as the OpenCV convertTo does.
for (uint32_t y = 0; y < h; y++)
Expand Down Expand Up @@ -160,8 +162,8 @@ void BabbleMonoFace::process(const StereoFrame &sf) {
half_out_.resize(os.elements());
out = half_out_.data();
}
std::vector<TensorView> iv{{in, &is}};
std::vector<TensorView> ov{{out, &os}};
TensorView iv[] = {{in, &is}};
TensorView ov[] = {{out, &os}};
if (!runner_->run(iv, ov))
return;
if (os.dtype == DType::F16)
Expand Down
15 changes: 7 additions & 8 deletions runtime/src/model/fusionnet_mouth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ bool FusionNetMouth::init() {
tmp_a_.resize(400 * 400);
tmp_b_.resize(400 * 400);
small_.resize(kSize * kSize);
eq_.resize(kSize * kSize);
in0_.resize(kSize * kSize);
in1_.resize(kSize * kSize);
probe_left_ = probe_total_ = cfg_.value("probe_orientation", 0);
Expand Down Expand Up @@ -123,9 +122,9 @@ void FusionNetMouth::prepare(const StereoFrame &sf, float *view0, float *view1)
img::resize_area(cur, small);
else
img::resize_linear(cur, small);
img::equalize_hist(small, {eq_.data(), kSize, kSize, kSize});
for (size_t i = 0; i < eq_.size(); i++)
outs[v][i] = float(eq_[i]) / 255.0f;
img::equalize_hist(small, small);
for (size_t i = 0; i < small_.size(); i++)
outs[v][i] = float(small_[i]) / 255.0f;
}
}

Expand All @@ -140,9 +139,9 @@ void FusionNetMouth::probe(const StereoFrame &sf) {
const int saved_turns = quarter_turns_;
auto ri = runner_->inputs();
auto ro = runner_->outputs();
std::vector<TensorView> iv{{in0_.data(), &ri[0]}, {in1_.data(), &ri[1]}};
TensorView iv[] = {{in0_.data(), &ri[0]}, {in1_.data(), &ri[1]}};
std::array<float, mouth::kNumChannels> out{};
std::vector<TensorView> ov{{out.data(), &ro[0]}};
TensorView ov[] = {{out.data(), &ro[0]}};
for (int c = 0; c < 8; c++) {
swap_ = c >= 4;
quarter_turns_ = c % 4;
Expand Down Expand Up @@ -183,8 +182,8 @@ void FusionNetMouth::process(const StereoFrame &sf) {

auto ri = runner_->inputs();
auto ro = runner_->outputs();
std::vector<TensorView> iv{{in0_.data(), &ri[0]}, {in1_.data(), &ri[1]}};
std::vector<TensorView> ov{{out_.data(), &ro[0]}};
TensorView iv[] = {{in0_.data(), &ri[0]}, {in1_.data(), &ri[1]}};
TensorView ov[] = {{out_.data(), &ro[0]}};
if (!runner_->run(iv, ov))
return;
uint64_t t2 = mono_ns();
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/model/fusionnet_mouth.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class FusionNetMouth : public PipelineBase {
std::unique_ptr<mouth::Post> post_;
std::array<SignalId, mouth::kNumShapes> ids_{};

std::vector<uint8_t> tmp_a_, tmp_b_, small_, eq_;
std::vector<uint8_t> tmp_a_, tmp_b_, small_;
std::vector<float> in0_, in1_;
std::array<float, mouth::kNumChannels> out_{};
std::atomic<bool> reset_pending_{false};
Expand Down
12 changes: 8 additions & 4 deletions runtime/src/model/image_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,15 @@ void resize_area(View src, Mut dst) {

std::vector<float> buf(dw), sum(dw, 0.f);
int prev_dy = ytab.empty() ? 0 : ytab[0].di;
int prev_sy = -1;
for (const AreaTab &yt : ytab) {
const uint8_t *S = src.data + size_t(yt.si) * src.stride;
std::fill(buf.begin(), buf.end(), 0.f);
for (const AreaTab &xt : xtab)
buf[xt.di] += float(S[xt.si]) * xt.alpha;
if (yt.si != prev_sy) {
const uint8_t *S = src.data + size_t(yt.si) * src.stride;
std::fill(buf.begin(), buf.end(), 0.f);
for (const AreaTab &xt : xtab)
buf[xt.di] += float(S[xt.si]) * xt.alpha;
prev_sy = yt.si;
}
if (yt.di != prev_dy) {
uint8_t *D = dst.data + size_t(prev_dy) * dst.stride;
for (int x = 0; x < dw; x++) {
Expand Down
6 changes: 4 additions & 2 deletions runtime/src/sink/link_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,8 @@ void LinkSink::choose(uint64_t now) {

void LinkSink::run() {
const uint64_t scan_ns = 5'000'000'000;
std::vector<pollfd> fds;
std::vector<Path *> owners;
while (!stop_) {
uint64_t now = mono_ns();
if (now >= next_scan_ns_) {
Expand All @@ -628,8 +630,8 @@ void LinkSink::run() {
ping(now);
choose(now);

std::vector<pollfd> fds;
std::vector<Path *> owners;
fds.clear();
owners.clear();
if (listen_sock_ >= 0) {
fds.push_back({listen_sock_, POLLIN, 0});
owners.push_back(nullptr);
Expand Down
9 changes: 5 additions & 4 deletions runtime/src/sink/osc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ size_t encode_float(std::string_view address, float value, uint8_t *out, size_t
const size_t total = addr_len + 4 + 4;
if (total > cap)
return 0;
memset(out, 0, total);
memcpy(out, address.data(), address.size());
memcpy(out + addr_len, ",f", 2);
memset(out + address.size(), 0, addr_len - address.size());
memcpy(out + addr_len, ",f\0", 4);
uint32_t bits;
memcpy(&bits, &value, 4);
bits = __builtin_bswap32(bits);
Expand All @@ -42,13 +42,14 @@ size_t encode_blob(std::string_view address, const uint8_t *data, size_t size, u
const size_t total = addr_len + 4 + 4 + data_len;
if (total > cap || size > 0x7fffffff)
return 0;
memset(out, 0, total);
memcpy(out, address.data(), address.size());
memcpy(out + addr_len, ",b", 2);
memset(out + address.size(), 0, addr_len - address.size());
memcpy(out + addr_len, ",b\0", 4);
const uint32_t n = __builtin_bswap32(uint32_t(size));
memcpy(out + addr_len + 4, &n, 4);
if (size)
memcpy(out + addr_len + 8, data, size);
memset(out + addr_len + 8 + size, 0, data_len - size);
return total;
}

Expand Down
3 changes: 2 additions & 1 deletion runtime/src/sink/osc_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ void OscSink::run() {
uint64_t seq = 0, last_batch_ns = 0, generation = 0;
std::vector<uint64_t> last_sent_t; // The t_ns of the last value that the sink sent for each signal.
std::vector<std::string> addresses; // The OSC address for each signal, or "" if the signal is excluded.
ExpressionState::Snapshot snap;

while (!stop_) {
if (test_pattern_) {
Expand All @@ -183,7 +184,7 @@ void OscSink::run() {
generation = g;
}

auto snap = state_.snapshot();
state_.snapshot(snap);
if (addresses.size() != snap.names.size()) {
// Make the address table again if the number of signals changes.
addresses.clear();
Expand Down
8 changes: 5 additions & 3 deletions runtime/src/sink/vrc_native_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,9 @@ std::optional<std::string> VrcNativeSink::live_pc() {
std::ifstream in(log_path_, std::ios::binary);
std::stringstream text;
text << in.rdbuf();
log_pc_ = vrc_native::streaming_pc(text.str());
log_pid_ = vrc_native::session_pid(text.str());
const std::string contents = text.str();
log_pc_ = vrc_native::streaming_pc(contents);
log_pid_ = vrc_native::session_pid(contents);
}
// The session is live if its vrlink process still runs.
if (!log_pc_ || !log_pid_)
Expand Down Expand Up @@ -384,6 +385,7 @@ void VrcNativeSink::run() {
uint64_t seq = 0, last_send_ns = 0;
std::vector<vrc_native::Target> targets;
std::vector<std::optional<float>> values;
ExpressionState::Snapshot snap;

while (!stop_) {
seq = state_.wait_update(seq, std::chrono::milliseconds(200));
Expand All @@ -396,7 +398,7 @@ void VrcNativeSink::run() {
continue;
last_send_ns = now;

const auto snap = state_.snapshot();
state_.snapshot(snap);
if (targets.size() != snap.names.size()) {
targets.clear();
for (const auto &nm : snap.names)
Expand Down
10 changes: 9 additions & 1 deletion runtime/src/state/expression_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,16 @@ std::string ExpressionState::name(SignalId id) const {
}

ExpressionState::Snapshot ExpressionState::snapshot() const {
Snapshot out;
snapshot(out);
return out;
}

void ExpressionState::snapshot(Snapshot &out) const {
std::lock_guard<std::mutex> lock(mutex_);
return {seq_, names_, signals_};
out.seq = seq_;
out.names = names_;
out.signals = signals_;
}

uint64_t ExpressionState::wait_update(uint64_t after_seq, std::chrono::nanoseconds timeout) const {
Expand Down
1 change: 1 addition & 0 deletions runtime/src/state/expression_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ExpressionState {

void update(std::span<const std::pair<SignalId, Signal>> values);
Snapshot snapshot() const;
void snapshot(Snapshot &out) const;
// Writes the current value for ids[i] to out[i] and returns the sequence number of the values.
uint64_t read(std::span<const SignalId> ids, Signal *out) const;
size_t count() const; // The number of registered signals, with ids from 0 to count-1.
Expand Down
13 changes: 10 additions & 3 deletions runtime/src/ui/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,19 @@ void Canvas::line(float x0, float y0, float x1, float y1, float width, Color c)
void Canvas::image(const Image &img, int x, int y, float radius) {
const Rect r{float(x), float(y), float(img.width), float(img.height)};
const float rad = std::min({radius, r.w / 2, r.h / 2});
for (int iy = 0; iy < img.height; iy++)
for (int ix = 0; ix < img.width; ix++) {
const int x0 = int(std::clamp<int64_t>(-int64_t(x), 0, img.width));
const int x1 = int(std::clamp<int64_t>(int64_t(w_) - x, 0, img.width));
const int y0 = int(std::clamp<int64_t>(-int64_t(y), 0, img.height));
const int y1 = int(std::clamp<int64_t>(int64_t(h_) - y, 0, img.height));
for (int iy = y0; iy < y1; iy++)
for (int ix = x0; ix < x1; ix++) {
const uint8_t *s = &img.rgba[(size_t(iy) * img.width + ix) * 4];
if (!s[3])
continue;
// The coverage is the rounded-corner coverage multiplied by the alpha of the image.
float cov = 1.0f;
if (rad > 0)
if (rad > 0 && (ix + 0.5f < rad || ix + 0.5f > r.w - rad) &&
(iy + 0.5f < rad || iy + 0.5f > r.h - rad))
cov = std::clamp(0.5f - round_box_sdf(x + ix + 0.5f, y + iy + 0.5f, r, rad), 0.f, 1.f);
blend(x + ix, y + iy, Color{s[0], s[1], s[2], s[3]}, cov);
}
Expand Down