Page MenuHomeFreeBSD

www/linux-brave: DRM out of the box, GPU auto-detection
Needs ReviewPublic

Authored by dteske on Tue, Aug 11, 8:20 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Aug 16, 8:34 PM
Unknown Object (File)
Sun, Aug 16, 8:33 PM
Unknown Object (File)
Sat, Aug 15, 11:48 PM
Unknown Object (File)
Sat, Aug 15, 9:43 PM
Unknown Object (File)
Sat, Aug 15, 7:03 PM
Unknown Object (File)
Sat, Aug 15, 6:58 PM
Unknown Object (File)
Sat, Aug 15, 6:57 PM
Unknown Object (File)
Sat, Aug 15, 6:33 PM
Subscribers

Details

Summary

Add a WIDEVINE option (default on) so DRM playback works with no
browser-side setup once the CDM is present. The option links
${PREFIX}/lib/WidevineCdm into the Brave install directory, where the
component updater discovers it as a preinstalled component, and runs a
pre-launch seed script that sets brave.widevine_opted_in and maintains
the Widevine component hint file: Chromium registers the CDM at
startup from the hint and never repairs it itself, so the script
plants the hint before the first launch and repoints it when its
target no longer holds a CDM (e.g. after the CDM port is reinstalled),
while leaving intact hints -- including one naming a newer
component-updated CDM -- alone.

The option adds no dependency: Google's license permits fetching the
CDM but not redistributing it (www/linux-widevine-cdm is
no-pkg-mirror), so a RUN_DEPENDS would keep linux-brave itself off the
package mirrors. Everything the option installs is inert until the
user builds www/linux-widevine-cdm from ports -- the symlink dangles
and the seed script only acts when the CDM is present -- and DRM
starts working on the next launch after the CDM appears. Verified
against Netflix, Disney+, Hulu, Amazon Prime Video, discovery+, Dish
Anywhere, and Pandora, including recovery across a CDM
remove/reinstall cycle.

Wrapper improvements:

  • Re-exec under dbus-run-session when no session bus is present (new RUN_DEPENDS on devel/dbus).
  • Use hardware GL when a writable DRM render node and the Linux Mesa DRI drivers (graphics/linux-rl9-dri) are present, software rendering otherwise; BRAVE_GPU=1/0 forces.
  • With hardware GL, prefer ANGLE-on-Vulkan when the Linux Vulkan loader (x11-toolkits/linux-rl9-vulkan) and a hardware driver ICD are present: GL command streams from the Linux Mesa drivers have proven prone to GPU hangs on some kernel driver pairings, while the Vulkan path drives the same hardware reliably; BRAVE_VULKAN=1/0 forces.
  • Never inherit a FreeBSD-side LD_PRELOAD; drop --test-type (ImmediateCrash under the Linuxulator); fix PULSE_COOKIE (literal ~ never expanded inside quotes).
  • Fix pre-existing pulseaudio socket detection: pass -uw to sockstat (without -w long local addresses truncate, clipping the native socket path so the match never fired and PULSE_SERVER was never exported); quote $(whoami) against usernames bearing whitespace (pw(8) rejects them, vipw(8) does not).

Suppress the unsupported-flag warning banner via the supported
CommandLineFlagSecurityWarningsEnabled policy: the wrapper must pass
--no-sandbox because the Linuxulator lacks user namespaces.

Rewrite pkg-message to the essentials (Linuxulator setup, CDM install
step, Widevine and GPU behavior). Drop shared-mime-info dependency:
the package installs nothing under share/mime.

Diff Detail

Repository
R11 FreeBSD ports repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 75543
Build 72426: arc lint + arc unit

Event Timeline

dteske created this revision.
www/linux-brave/Makefile
43

This will prevent Brave from being packaged, because we don't package linux-widevine-cdm due to licensing restrictions.

Remove runtime dependency on liux-widevine-cdm

Keep the option, keep it on-by-default, but make it so the CDM
can be uninstalled/reinstalled at-will. Uninstall, Netflix stops,
reinstall, relaunch browser, Netflix works again.

dteske marked an inline comment as done.
dteske added inline comments.
www/linux-brave/Makefile
43

Thanks Gleb — point well taken. Worth spelling out for anyone following along: this port ships no Widevine bits itself (just a symlink and a JSON hint file), but you're right that a default-on RUN_DEPENDS on a no-pkg-mirror port would drag linux-brave off the official mirrors with it, and that defeats the purpose of a browser package.

Fixed in the next diff by dropping the RUN_DEPENDS entirely rather than defaulting the option off: everything the WIDEVINE option installs is inert without the CDM — the seed script only acts when ${PREFIX}/lib/WidevineCdm/manifest.json exists, the symlink dangles harmlessly, and Brave simply runs without DRM. pkg-message now points users at building www/linux-widevine-cdm from ports, and DRM starts working on the next launch after your port is installed — verified here through a full remove/reinstall cycle, including automatic repair of a hint file left stale by the removal. Does that shape work for you as linux-widevine-cdm's maintainer?

www/linux-brave/Makefile
31

Aren't these default values? We can probably drop these two knobs.

43

Yes, that's very similar to what www/chromium does.

dteske marked an inline comment as done.

Remove default-value variables for brevity (arrowd)

Other than that, LGTM.

www/linux-brave/files/brave-browser.in
57

Is this var really needed? dbus-launch exports DBUS_SESSION_BUS_ADDRESS so that consecutive calls to dbus-launch would be no-op.

www/linux-brave/files/brave-widevine-seed.in
44

This should be %%LOCALBASE%%. Actually, you can obtain this value from sysctl user.localbase.

This revision is now accepted and ready to land.Tue, Aug 11, 7:09 PM

I'd say the necessity of the "procfs guard" (is that LLM terminology?) is dubious at best (same issue as in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=297426) and I don't quite get the point of the GPU stuff. Also export LIBGL_DRI3_DISABLE=1 workaround was obsoleted by https://github.com/freebsd/drm-kmod/pull/35 and it easily could interfer with the GPU acceleration.

Prefer %%LOCALBASE%% over %%PREFIX%% and rely solely on Dbus relaunch sentinel

This revision now requires review to proceed.Tue, Aug 11, 8:34 PM

@arrowd thank you, if all looks good, I'll commit it with your re-approval

dteske removed a subscriber: iwtcex_gmail.com.

What's this about?

www/linux-brave/Makefile
56

How is this substitution used?

www/linux-brave/files/brave-browser.in
93

I don't get this part, why is it needed?

dteske removed a subscriber: iwtcex_gmail.com.

What's this about?

Procfs objection: unsupported and contradicted by controlled reproduction
GPU objection: no technical claim
DRI3 observation: concerns unchanged pre-existing code, so it is out of scope

Alex S. comment is largely provocation and drive-by objection, no concrete
evidence, further ... references the below:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=297426#c7

Where Alex’s opening (comment 3):

“are you just trying to waste everyone’s time?”

was plainly inappropriate.

I don't exactly enjoy my time trying to understand LLM dumps on the bug tracker. That itself is pretty rude.

www/linux-brave/Makefile
56

See %%BRAVE_WIDEVINE%% in the generated brave-browser wrapper; it records the build option and controls whether the wrapper invokes brave-widevine-seed.

Looking again, the adjacent executable check is sufficient because the helper is generated and installed only when WIDEVINE is enabled, while the package metadata already records the option.

Good catch. I’ll remove the BRAVE_WIDEVINE substitutions and use the helper's presence as the runtime condition.

I don't exactly enjoy my time trying to understand LLM dumps on the bug tracker. That itself is pretty rude.

Not LLM. Have you ever met Bruce Evans? He and I have a lot in common. May he RIP.

www/linux-brave/files/brave-browser.in
93

linux-rl9-fontconfig installs /compat/linux/etc/fonts as an absolute symlink to /usr/local/etc/fonts. From a Linux process, the default /etc/fonts/fonts.conf lookup currently fails through that symlink:

$ env -u FONTCONFIG_FILE -u FONTCONFIG_PATH \
    /compat/linux/usr/bin/fc-match sans
Fontconfig error: Cannot load default config file: No such file: (null)

Setting FONTCONFIG_PATH=/usr/local/etc/fonts makes the Linuxulator’s ENOENT fallback reach the host ports fontconfig tree; fc-match then loads fonts.conf and conf.d without error. That gives Brave the host ports fonts rather than fontconfig’s in-memory fallback. Testing also shows that FONTCONFIG_FILE is redundant once FONTCONFIG_PATH is set, so I can reduce this block to:

export FONTCONFIG_PATH="${FONTCONFIG_PATH:-/usr/local/etc/fonts}"

In addition to the two cleanup tasks for later today (eliminating FONTCONFIG_FILE and setting only FONTCONFIG_PATH plus eliminating BRAVE_WIDEVINE substitution), I propose we move from GL rendering to vulkan when the wrapper detects it as viable (passing --use-angle=vulkan).

In testing, when I loaded multiple sites using Widevine at the same time, it stressed GL rendering to the point that it was causing video glitches, most notably when opening a new tab (the fancy-pants backgrounds that brave rendered behind the widgets in a new tab were visually corrupted).

This is under i915 and I tried multiple drm-6*-kmods and multiple Mesa kits. Consistently I can get Mesa GL to exhibit render-engine hangs. Albeit brave recovers gracefully but kept falling back to software rendering in the process and that is both annoying and sub-optimal. A snippet of my dmesg during those hangs (wherein after brave has suffered 3 or 4 of these, it goes back to software rendering):

20:09:37 GPU HANG: ecode 12:1:c05fffff, in brave
20:09:38 Resetting rcs0 for CS error
20:09:51 GPU HANG: ecode 12:1:00600000, in brave
20:09:52 Resetting rcs0 for CS error
20:09:56 GPU HANG: ecode 12:1:77dffbfa, in brave
20:09:56 Resetting rcs0 for CS error

That's 3 hangs in 19 seconds under linux-rl9-dri 25.2.7 (achieved by Ctrl+T, Ctrl+W repeatedly)

Mesa 24.2.8 was no help (excluding the possibility of a 25.2-specific regression), seeing 3 hangs in 26 seconds:

20:33:07 GPU HANG: ecode 12:1:00600000, in brave
20:33:08 Resetting rcs0 for CS error
20:33:23 GPU HANG: ecode 12:1:00200000, in brave
20:33:23 Resetting rcs0 for CS error
20:33:32 GPU HANG: ecode 12:1:859ffffb, in brave
20:33:33 Resetting rcs0 for preemption time out

It's not just limited to brave though. Stressing brave with Mesa GL even horked my desktop interface a few times.

ANGLE-on-Vulkan tested very stable on drm-66-kmod. I stressed the bejeezus out of it and it remained connected to /dev/drm/0 (with none of the dmesg resets)

So in the dust-up on the previous nits, I also intend to raise in the wrapper vulkan awareness and pass --use-angle=vulkan when appropriate.

Also, currently battling an issue where dbus-launch sticks around after browser exit (expected but they are stacking instead of re-use). Expect a fix for that to come in the next update too.

www/linux-brave/files/brave-browser.in
93

Hmm, I do get the "Cannot load default config file: No such file: (null)" error message with and without /proc mounted, but at the same time I get a correct font match in both cases.

Also, currently battling an issue where dbus-launch sticks around after browser exit. Expect a fix for that to come in the next update too.

Is it really needed, by the way? Applications should only create buses if they want to have a separate bus for their own needs. Does Brave talk to its children via dbus?

Also, currently battling an issue where dbus-launch sticks around after browser exit. Expect a fix for that to come in the next update too.

Is it really needed, by the way? Applications should only create buses if they want to have a separate bus for their own needs. Does Brave talk to its children via dbus?

The value-add we bring with dbus-launch is inhibition of screensaver invocation when Netflix is playing.

All part of my master plan to replace my Apple TV with a Framework Laptop 12

EDIT:

Running dbus-monitor "interface='org.freedesktop.ScreenSaver'" when Netflix video starts playing, you'll see something like:

method call time=1786568426.421178 sender=:1.50 -> destination=org.freedesktop.ScreenSaver serial=52 path=/org/freedesktop/ScreenSaver; interface=org.freedesktop.ScreenSaver; member=Inhibit
   string "/usr/local/share/brave/brave"
   string "Video Wake Lock"

and when Netflix video stops playing, you'll see something like:

method call time=1786568422.553844 sender=:1.50 -> destination=org.freedesktop.ScreenSaver serial=46 path=/org/freedesktop/ScreenSaver; interface=org.freedesktop.ScreenSaver; member=UnInhibit
   uint32 5

NB: important part is member=UnInhibit

www/linux-brave/files/brave-browser.in
93

Nothing to do with /proc on this one.

The match line is the misleading part. Compare the two runs side by side:

$ export FONTCONFIG_PATH=/usr/local/etc/fonts
$ /compat/linux/usr/bin/fc-match sans
DejaVuSans.ttf: "DejaVu Sans" "Book"

against:

$ export FONTCONFIG_PATH=xxx
$ /compat/linux/usr/bin/fc-match sans
Fontconfig error: Cannot load default config file: No such file: (null)
DejaVuMathTeXGyre.ttf: "DejaVu Math TeX Gyre" "Regular"

When you get the error, you're probably not getting the font you want.

Two different fonts returned when asking for "sans" -- only when you get rid of the error do you get the correct font. DejaVuMathTeXGyre is not what we want for "sans" match.

fc-match prints a font regardless, but when it can't find the config, it prints an arbitrary result. What it returns is based on luck; on my system it returns a math font, on your system it might return a sane choice.

In Brave, it looks like wrong font used for closed captioning when playing Netflix video for example.

Also, currently battling an issue where dbus-launch sticks around after browser exit. Expect a fix for that to come in the next update too.

Is it really needed, by the way? Applications should only create buses if they want to have a separate bus for their own needs. Does Brave talk to its children via dbus?

The value-add we bring with dbus-launch is inhibition of screensaver invocation when Netflix is playing.

All part of my master plan to replace my Apple TV with a Framework Laptop 12

sure but shouldn't your X environment be starting dbus-launch and setting up the XDG stuff for its window manager and child processes to run in?

Also, currently battling an issue where dbus-launch sticks around after browser exit. Expect a fix for that to come in the next update too.

Is it really needed, by the way? Applications should only create buses if they want to have a separate bus for their own needs. Does Brave talk to its children via dbus?

The value-add we bring with dbus-launch is inhibition of screensaver invocation when Netflix is playing.

All part of my master plan to replace my Apple TV with a Framework Laptop 12

sure but shouldn't your X environment be starting dbus-launch and setting up the XDG stuff for its window manager and child processes to run in?

Correct. I run fvwm3 and wasn't starting a session bus at all (xautolock knows nothing of dbus). Fixed: fvwm3 starts one bus, a small ScreenSaver shim on it drives xautolock, Brave inherits. The wrapper still has to handle bus-less setups: without any bus Chromium spams connection retries and site notifications (org.freedesktop.Notifications) never fire. Next diff swaps the fallback from dbus-launch to dbus-run-session, which dies with the browser instead of stacking.

Keeping a bus alive even on bus-less setups isn't just spam control. Brave exports MPRIS over it, which is what my framework-keyboard work rides to wire the play/pause, rewind, and fast-forward keys on the Framework laptops into the browser.

Caught a couple more technical debt issues in the wrapper:

  • the pulseaudio detection at the top fails to pass -uw (instead of args lacking -w -- -u added for good measure) to sockstat which can lead to truncation of long local-address values (e.g., /var/run/xdg/$USER/pulse/native cutting off the word native that the awk searches for)
  • a username with a space in it can break the awk -v me=$(whoami) invocation [*]

This can prevent audio from working in some instances.

  • pw useradd may disallow a space in the username, but vipw does not. A common use-case would be someone setting up a login that uses "first last" nomenclature (perfectly valid; strange, but valid)
  1. Fix dbus integration (dbus-launch -> dbus-run-session)
  2. Remove BRAVE_WIDEVINE from SUB_LIST (arrowd)
  3. Fix pulseaudio detection (pre-existing issue)
  4. Favor angle-on-vulkan over Mesa GL (w/ pkg-message updates)
  5. Remove unnecessary FONTCONFIG_FILE (rely on FONTCONFIG_PATH) (~arrowd)
dteske edited the summary of this revision. (Show Details)

Tested dbus integration with working pause/play, rewind, and fast-forward integration, and screensaver inhibit all working regardless of whether WM is bus-less or not. In a bus-less WM session, it brings its own bus run that tears down on browser exit

The fontconfig setup is really a fix for CURRENT that deals with broken symlink resolution at-present -- that needs to be bisected separately, but until then keeping the setting is harmless and produces the desired results even on CURRENT

Tested dbus integration with working pause/play, rewind, and fast-forward integration, and screensaver inhibit all working regardless of whether WM is bus-less or not. In a bus-less WM session, it brings its own bus run that tears down on browser exit

I wonder if a proper way to handle this is what Obsidian does https://cgit.freebsd.org/ports/tree/textproc/obsidian/files/obsidian.in

Anyways, I think I provided all the useful input I could, but I don't wear the emulation@ hat, so I can't formally approve this.

dteske retitled this revision from www/linux-brave: DRM out of the box, procfs guard, GPU auto-detection to www/linux-brave: DRM out of the box, GPU auto-detection.Sat, Aug 15, 6:29 AM
dteske edited the summary of this revision. (Show Details)
dteske edited the summary of this revision. (Show Details)