|
| 1 | +# Spout2 (vendored subset) |
| 2 | + |
| 3 | +This directory contains a vendored, minimal subset of [Spout2](https://github.com/leadedge/Spout2) |
| 4 | +— the server-side DirectX 11 sender used by Sonic Pi's *Publish Window via Spout* feature |
| 5 | +on Windows. Counterpart to the macOS `Syphon-Framework/` vendor. |
| 6 | + |
| 7 | +## Upstream |
| 8 | + |
| 9 | +- Repo: <https://github.com/leadedge/Spout2> |
| 10 | +- Version: **2.007.010** |
| 11 | +- Source commit: `62362774c96547d63b502d7efd5cfbf138eb7570` |
| 12 | +- License: BSD-2-Clause (`LICENSE`) |
| 13 | + |
| 14 | +## Subset |
| 15 | + |
| 16 | +Only the SpoutDX (DirectX 11 sender) path is shipped. The OpenGL helpers, GL-based |
| 17 | +Spout/SpoutSender/SpoutReceiver wrappers, demos, examples and the SpoutPanel / |
| 18 | +SpoutSettings tools are deliberately omitted. |
| 19 | + |
| 20 | +``` |
| 21 | +SPOUTSDK/ |
| 22 | +├── SpoutGL/ ← runtime backing (despite the "GL" dir name, |
| 23 | +│ ├── SpoutCommon.h these files are the DX subset's deps) |
| 24 | +│ ├── SpoutCopy.{h,cpp} |
| 25 | +│ ├── SpoutDirectX.{h,cpp} |
| 26 | +│ ├── SpoutFrameCount.{h,cpp} |
| 27 | +│ ├── SpoutSenderNames.{h,cpp} |
| 28 | +│ ├── SpoutSharedMemory.{h,cpp} |
| 29 | +│ └── SpoutUtils.{h,cpp} |
| 30 | +└── SpoutDirectX/SpoutDX/ |
| 31 | + └── SpoutDX.{h,cpp} ← the public facade we consume |
| 32 | +``` |
| 33 | + |
| 34 | +## Local modifications |
| 35 | + |
| 36 | +Three patches applied directly to the source — they do **not** exist as separate |
| 37 | +`.patch` files in this tree because the vendored copy is checked in already-patched. |
| 38 | + |
| 39 | +### 1. fix-include-path |
| 40 | + |
| 41 | +`SpoutDirectX/SpoutDX/SpoutDX.h` uses quote-form includes like |
| 42 | +`#include "SpoutGL\SpoutCommon.h"`. Upstream's CMake builds `SpoutDX` as a |
| 43 | +separate target with its own private include path that lets `..\..\SpoutGL\X.h` |
| 44 | +resolve. In our in-tree build the headers come from this directory's structure |
| 45 | +directly, so the relative paths were normalised to single-segment form. |
| 46 | + |
| 47 | +### 2. fix-dx-keyed |
| 48 | + |
| 49 | +`spoutDX::spoutDX()` ctor: explicitly initialises `m_bKeyed = false` so the |
| 50 | +keyed-mutex code path is deterministic without depending on whatever a default |
| 51 | +caller may have set. |
| 52 | + |
| 53 | +### 3. fix-arm64 (Sonic Pi specific) |
| 54 | + |
| 55 | +Spout's `SpoutCopy.{h,cpp}` uses SSE2/SSSE3 intrinsics (`<emmintrin.h>`, |
| 56 | +`<tmmintrin.h>`, `__m128i`, `_mm_*`) for fast pixel copies, plus 3 `__movsd` |
| 57 | +calls in `SpoutCopy.cpp` and 3 in `SpoutSenderNames.cpp` for the 280-byte |
| 58 | +shared-sender-info struct. None of those compile for MSVC on ARM64. |
| 59 | + |
| 60 | +Modifications: |
| 61 | + |
| 62 | +- SSE includes guarded with `#if defined(_M_IX86) || defined(_M_AMD64)`, |
| 63 | + defining `SPOUT_HAS_SSE` to 1 / 0. |
| 64 | +- `spoutCopy::memcpy_sse2`, `rgba_bgra_sse2`, `rgba_bgra_sse3` and |
| 65 | + `rgb_to_bgrx_sse` function bodies wrapped in `#if SPOUT_HAS_SSE`, with |
| 66 | + scalar `memcpy` (or no-op) fallbacks on ARM64. The call sites are already |
| 67 | + runtime-guarded by `m_bSSE2 / m_bSSSE3` flags which stay `false` on ARM64 |
| 68 | + because `CheckSSE()`'s `__cpuid` calls are also gated out. |
| 69 | +- Six `__movsd(dst, src, n)` calls replaced with `memcpy(dst, src, n*4)`. |
| 70 | + Semantically equivalent. On x64 / x86 modern MSVC `memcpy` is heavily |
| 71 | + optimised (often emits the same `rep movs` instruction internally). |
| 72 | + |
| 73 | +On x86 / x64 the patches are inert — `SPOUT_HAS_SSE` is 1, all SSE bodies |
| 74 | +compile as upstream, runtime SSE-detection works, behaviour is identical. |
| 75 | + |
| 76 | +The `__movsd` -> `memcpy` swap is unconditional but the perf difference is |
| 77 | +sub-microsecond on a 280-byte struct copied once per sender event — not on |
| 78 | +any hot path. |
| 79 | + |
| 80 | +## Updating |
| 81 | + |
| 82 | +To pull a new upstream Spout2 release: |
| 83 | + |
| 84 | +1. Download `https://github.com/leadedge/Spout2/archive/<commit>.tar.gz` |
| 85 | +2. Diff against this tree to see what's drifted in the subset above. |
| 86 | +3. Re-apply the three modifications above (the `fix-arm64` one is the only |
| 87 | + non-trivial diff). |
| 88 | +4. Bump the version + commit references in this README. |
| 89 | + |
| 90 | +Long term: upstreaming the ARM64 changes to `leadedge/Spout2` would eliminate |
| 91 | +the third patch entirely. The mods follow the same `_M_IX86 || _M_AMD64` |
| 92 | +pattern Spout already uses internally in some places, so a PR should be |
| 93 | +mechanical. |
0 commit comments