Skip to content
Open
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
2 changes: 2 additions & 0 deletions apps/desktop/src-tauri/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,7 @@
<string>Cap captures your screen as part of recording your Caps</string>
<key>NSCameraUseContinuityCameraDeviceType</key>
<true/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<false/>
Comment on lines +32 to +33
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Indentation inconsistency

The new keys use 4 spaces for indentation while all existing keys in the file use tabs. This mixes whitespace styles within the same XML document.

Suggested change
<key>NSSupportsAutomaticGraphicsSwitching</key>
<false/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<false/>
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src-tauri/Info.plist
Line: 32-33

Comment:
**Indentation inconsistency**

The new keys use 4 spaces for indentation while all existing keys in the file use tabs. This mixes whitespace styles within the same XML document.

```suggestion
	<key>NSSupportsAutomaticGraphicsSwitching</key>
	<false/>
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +32 to +33
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Discrete GPU forced for entire app lifetime, not just recording

Setting NSSupportsAutomaticGraphicsSwitching to false prevents macOS from ever switching to the integrated GPU while Cap is running — including when it's idle in the menu bar between recordings. On Intel dual-GPU MacBooks this continuously activates the discrete GPU, which can noticeably increase power consumption and fan activity even when the app is not encoding. Consider whether this trade-off is intentional; a more targeted approach (e.g. invoking CGLEnable(kCGLCEMPEngine) or the Metal equivalent only during active recording) would avoid the always-on GPU cost.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src-tauri/Info.plist
Line: 32-33

Comment:
**Discrete GPU forced for entire app lifetime, not just recording**

Setting `NSSupportsAutomaticGraphicsSwitching` to `false` prevents macOS from ever switching to the integrated GPU while Cap is running — including when it's idle in the menu bar between recordings. On Intel dual-GPU MacBooks this continuously activates the discrete GPU, which can noticeably increase power consumption and fan activity even when the app is not encoding. Consider whether this trade-off is intentional; a more targeted approach (e.g. invoking `CGLEnable(kCGLCEMPEngine)` or the Metal equivalent only during active recording) would avoid the always-on GPU cost.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that a valid fix??

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, CGLEnable(kCGLCEMPEngine) was a bad suggestion on my part — that enables OpenGL's multi-processor engine, it has nothing to do with GPU selection. I shouldn't have cited it.

The reality is there's no clean programmatic way to switch the discrete GPU on/off only during recording in a Tauri + VideoToolbox app. You could enumerate Metal devices via MTLCopyAllDevices() and explicitly pick a non-low-power device when creating your encoder, but VideoToolbox's VTCompressionSession manages its own GPU selection internally and doesn't expose a direct "use this GPU" override.

The NSSupportsAutomaticGraphicsSwitching = false plist key is the correct and standard approach. The always-on discrete GPU trade-off is real, but worth noting:

  • Only affects Intel dual-GPU MacBooks (2016–2019 era, increasingly rare)
  • On those machines, software-encoding fallback (the problem being fixed) burns more CPU/battery than keeping the discrete GPU active

The PR as-is is the right fix. My concern about "entire app lifetime" was valid to flag but the practical alternative doesn't really exist cleanly — so merging this is fine.

Tip: You can customize Greptile's behavior for this repo with .greptile/rules and .greptile/config.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NSSupportsAutomaticGraphicsSwitching = false changed this and the issue still exist , so how can i fix it ,any idea???

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the plist change didn't help, the issue is likely not GPU switching — it's something in the encoder pipeline itself. Looking at crates/enc-ffmpeg/src/video/h264.rs, I see a concrete problem in the recording path:

For export (is_export = true), you have:

options.set("allow_sw", "0");  // Forces hardware, fails hard if unavailable

For realtime recording, you don't set allow_sw at all — which means VideoToolbox's default (allow_sw = true) silently falls back to software encoding internally without any error. The code thinks it's using h264_videotoolbox (hardware), but VTB is actually encoding in software, causing high CPU.

Fix: Add allow_sw = "0" to the recording path so VTB either uses hardware or fails explicitly (triggering fallback to libx264 with a proper warning log):

// in crates/enc-ffmpeg/src/video/h264.rs, "h264_videotoolbox" match arm
"h264_videotoolbox" => {
    if is_export {
        options.set("realtime", "false");
        options.set("profile", "main");
        options.set("allow_sw", "0");
    } else {
        options.set("realtime", "true");
        options.set("prio_speed", "true");
        options.set("profile", "main");
        options.set("allow_sw", "0");  // add this
    }
}

Also worth checking: The debug logs. When recording starts, look for:

  • "Selected hardware H264 encoder" → good
  • "Using SOFTWARE H264 encoder" → means libx264 was selected instead of VTB
  • "Created SOFTWARE scaler for pixel format conversion (CPU-intensive)" → means the pixel format from screen capture doesn't match what VTB expects, causing a CPU-side format conversion even if the encoder itself is hardware

The software scaler case would cause high CPU regardless of the plist change.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if i give the log can you probe the issue??

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, share the logs and I can dig in. Most useful would be:

  1. Tauri/app logs from when a recording starts — look for lines mentioning h264_videotoolbox, allow_sw, scaler, or encoder
  2. FFmpeg/encoder init output — any codec selection messages
  3. Console.app output filtered to your app process during recording start

The key signals I'm looking for:

  • Which encoder was actually selected (hardware VTB vs libx264)
  • Whether a software scaler is being spun up for pixel format conversion
  • Any VTB error codes (e.g. -12902 = no hardware available, -12908 = format unsupported)

Paste them here and I'll trace the issue.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tell me the steps to genrate the log

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's how to capture the logs:

1. Run the app in dev mode (gets you Rust/FFmpeg logs directly in terminal):

cd apps/desktop
pnpm tauri dev

This streams all println!, log::info!, eprintln! output to the terminal. Start a recording and watch for encoder selection messages.

2. If you need logs from a release build, use Console.app:

  • Open Console.app (Applications → Utilities)
  • In the search bar, type your app name (Cap) and filter by Process
  • Click Start before launching the app
  • Start a recording session
  • Stop and export the log (File → Export)

3. Capture VideoToolbox errors specifically:
In a terminal, run this before starting the app:

log stream --process Cap --level debug 2>&1 | tee cap_recording.log

Then start the app and trigger a recording. Press Ctrl+C when done. The log file will have everything.

4. What to look for and paste here:

  • Lines containing: h264_videotoolbox, allow_sw, scaler, libx264, encoder, VT, pixel format
  • Any lines with error codes like -12902, -12908
  • Anything around the moment recording starts

The pnpm tauri dev route is easiest — just start it, record for 10–15 seconds, stop, and paste the terminal output here.

</dict>
</plist>