From 370ee949d99897bbd79d35c4237828a3c655062a Mon Sep 17 00:00:00 2001 From: fkwp Date: Thu, 8 Oct 2026 09:06:53 +0200 Subject: [PATCH] Offer background effects on any platform whose browser can run them - The desktop rule from #4059 goes: now that the menu says where effects run slowly, using them there is the user's choice. A phone on the fast route held 99% of its frame rate and was refused; a desktop on the slow one held 73% and was allowed. - Asks @livekit/track-processors directly; the wrapper module goes. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/components/CallFooterViewModel.test.ts | 6 ++--- src/components/CallFooterViewModel.tsx | 8 +++--- src/livekit/BackgroundEffectsContext.test.ts | 6 ++--- src/livekit/BackgroundEffectsContext.tsx | 2 +- src/livekit/backgroundProcessing.ts | 27 -------------------- 5 files changed, 11 insertions(+), 38 deletions(-) delete mode 100644 src/livekit/backgroundProcessing.ts diff --git a/src/components/CallFooterViewModel.test.ts b/src/components/CallFooterViewModel.test.ts index 6c2075a7c..e7d7ddd85 100644 --- a/src/components/CallFooterViewModel.test.ts +++ b/src/components/CallFooterViewModel.test.ts @@ -254,12 +254,12 @@ describe("createCallFooterViewModel", () => { ); } - it("offers nothing on a phone, where the pipeline would refuse them", () => { + it("offers them on a phone whose browser can run them", () => { sdkSupportMock.mockReturnValue(true); - expect(lobbyOn("ios").selectBackgroundEffect$.value).toBeUndefined(); + expect(lobbyOn("ios").selectBackgroundEffect$.value).toBeDefined(); }); - it("offers them where the pipeline will honour them", () => { + it("offers them on a desktop whose browser can run them", () => { sdkSupportMock.mockReturnValue(true); expect(lobbyOn("desktop").selectBackgroundEffect$.value).toBeDefined(); }); diff --git a/src/components/CallFooterViewModel.tsx b/src/components/CallFooterViewModel.tsx index cc879e7d2..372e2cb98 100644 --- a/src/components/CallFooterViewModel.tsx +++ b/src/components/CallFooterViewModel.tsx @@ -13,11 +13,11 @@ import { switchMap, } from "rxjs"; import { supportsAudioOutputSelection } from "livekit-client"; - import { supportsBackgroundProcessors, - usesFallbackProcessing, -} from "../livekit/backgroundProcessing"; + supportsModernBackgroundProcessors, +} from "@livekit/track-processors"; + import { parseEffect, serializeEffect, @@ -112,7 +112,7 @@ function buildDeviceBehaviors( ); const supported = supportsBackgroundProcessors(); - const slow = usesFallbackProcessing(); + const slow = !supportsModernBackgroundProcessors(); const offered$ = disableSwitcher$.pipe( map((switcherDisabled) => !switcherDisabled && supported), ); diff --git a/src/livekit/BackgroundEffectsContext.test.ts b/src/livekit/BackgroundEffectsContext.test.ts index 0e3317b95..5bc76fec2 100644 --- a/src/livekit/BackgroundEffectsContext.test.ts +++ b/src/livekit/BackgroundEffectsContext.test.ts @@ -195,14 +195,14 @@ describe("BackgroundEffectsProvider", () => { expect(track.stopProcessor).not.toHaveBeenCalled(); }); - it("does not run on a phone, even where its browser could", async () => { + it("runs on a phone whose browser can run it", async () => { platformMock.platform = "ios"; const track = cameraTrack(); render(surfaces(track)); await blur(true); - expect(latest().supported).toBe(false); - expect(track.setProcessor).not.toHaveBeenCalled(); + expect(latest().supported).toBe(true); + expect(track.setProcessor).toHaveBeenCalledWith(latest().processor); }); it("preview and call share one pipeline", async () => { diff --git a/src/livekit/BackgroundEffectsContext.tsx b/src/livekit/BackgroundEffectsContext.tsx index 0c0332ef7..2fca5239c 100644 --- a/src/livekit/BackgroundEffectsContext.tsx +++ b/src/livekit/BackgroundEffectsContext.tsx @@ -9,6 +9,7 @@ Please see LICENSE in the repository root for full details. import { type ProcessorWrapper, type BackgroundOptions, + supportsBackgroundProcessors, } from "@livekit/track-processors"; import { createContext, @@ -25,7 +26,6 @@ import { combineLatest } from "rxjs"; import { backgroundEffect as backgroundEffectSetting } from "../settings/settings"; import { BackgroundEffectTransformer } from "./BackgroundEffectTransformer"; import { OneStepPipeline } from "./OneStepPipeline"; -import { supportsBackgroundProcessors } from "./backgroundProcessing"; import { type Behavior } from "../state/Behavior"; import { ObservableScope } from "../state/ObservableScope"; import { diff --git a/src/livekit/backgroundProcessing.ts b/src/livekit/backgroundProcessing.ts deleted file mode 100644 index 4463be3af..000000000 --- a/src/livekit/backgroundProcessing.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2026 Element Creations Ltd. - -SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -Please see LICENSE in the repository root for full details. -*/ - -import { - supportsBackgroundProcessors as supportsBackgroundProcessorsLivekitSdk, - supportsModernBackgroundProcessors, -} from "@livekit/track-processors"; - -import { platform } from "../Platform"; - -/** One answer for the controls and the pipeline, so neither offers what the other refuses. */ -export function supportsBackgroundProcessors(): boolean { - return supportsBackgroundProcessorsLivekitSdk() && platform === "desktop"; -} - -/** - * Whether effects, where they run at all, draw every frame through a canvas: - * the slower route, which costs frame rate and stalls the page while the - * first one is built. - */ -export function usesFallbackProcessing(): boolean { - return !supportsModernBackgroundProcessors(); -}