Skip to content

Commit 8b6d20c

Browse files
tpmoddingclaude
andcommitted
Fix hyperion-project#1921: replace per-frame SCScreenshotManager with persistent SCStream
Previously capture15() called getShareableContentWithCompletionHandler on every single frame grab (10-60 times/second), causing WindowServer to spike in CPU usage and occasional frame-rate drops on macOS Tahoe. Replace with a persistent SCStream (started once in setDisplayIndex): - getShareableContentWithCompletionHandler is called only once at setup - HyperionStreamOutput (SCStreamOutput delegate) receives frames on a high-priority dispatch queue and stores the latest CVPixelBuffer - grabFrame() reads directly from the CVPixelBuffer — no CIImage/CIContext overhead, no per-frame system enumeration - Stream pixel format kCVPixelFormatType_32BGRA maps directly to BGR32, eliminating an extra copy/conversion step - Falls back to single-shot screenshot if the stream fails to start or no frame has been delivered yet Additional fixes in the same file: - Fix missing braces in setupDisplay() that caused early return even when CGRequestScreenCaptureAccess() succeeded - Fix CGDisplayModeRef leak in capture15() (missing CGDisplayModeRelease) - Fix CGColorSpaceRef leak in capture15() (CGColorSpaceCreateDeviceRGB result was never released) - Reduce queueDepth from 5 to 3 for lower latency Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 71c9d3a commit 8b6d20c

2 files changed

Lines changed: 447 additions & 167 deletions

File tree

include/grabber/osx/OsxFrameGrabber.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class OsxFrameGrabber : public Grabber
1717
/// Construct a OsxFrameGrabber that will capture snapshots with specified dimensions.
1818
///
1919
/// @param[in] display The index of the display to capture
20-
2120
///
2221
OsxFrameGrabber(int display=kCGDirectMainDisplay);
2322
~OsxFrameGrabber() override;
@@ -58,4 +57,19 @@ class OsxFrameGrabber : public Grabber
5857

5958
/// Reference to the captured display
6059
CGDirectDisplayID _display;
60+
61+
#if defined(SDK_15_AVAILABLE)
62+
/// SCStream* stored as opaque pointer to keep ObjC out of this C++ header
63+
void* _stream;
64+
/// HyperionStreamOutput* stored as opaque pointer
65+
void* _streamOutput;
66+
67+
/// Start a persistent SCStream for the given display.
68+
/// Calls getShareableContentWithCompletionHandler only once (at setup).
69+
/// @return true on success
70+
bool startStream(CGDirectDisplayID displayID);
71+
72+
/// Stop and release the active SCStream.
73+
void stopStream();
74+
#endif
6175
};

0 commit comments

Comments
 (0)