From 4e779ac4f5d179e412ce20b6b8d8fe50fcdc3343 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/tracks/BackgroundEffectsContext.test.ts | 6 ++--- src/tracks/BackgroundEffectsContext.tsx | 6 +++-- src/tracks/backgroundProcessing.ts | 27 --------------------- 5 files changed, 14 insertions(+), 39 deletions(-) delete mode 100644 src/tracks/backgroundProcessing.ts diff --git a/src/components/CallFooterViewModel.test.ts b/src/components/CallFooterViewModel.test.ts index 52004185e..e061f4ef2 100644 --- a/src/components/CallFooterViewModel.test.ts +++ b/src/components/CallFooterViewModel.test.ts @@ -250,12 +250,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 183ebff8d..e9a262335 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 "../tracks/backgroundProcessing"; + supportsModernBackgroundProcessors, +} from "@livekit/track-processors"; + import { parseEffect, serializeEffect, @@ -113,7 +113,7 @@ function buildDeviceBehaviors( ); const supported = supportsBackgroundProcessors(); - const slow = usesFallbackProcessing(); + const slow = !supportsModernBackgroundProcessors(); const offered$ = disableSwitcher$.pipe( map((switcherDisabled) => !switcherDisabled && supported), ); diff --git a/src/tracks/BackgroundEffectsContext.test.ts b/src/tracks/BackgroundEffectsContext.test.ts index acb7a9e47..71d9d7152 100644 --- a/src/tracks/BackgroundEffectsContext.test.ts +++ b/src/tracks/BackgroundEffectsContext.test.ts @@ -93,13 +93,13 @@ describe("BackgroundEffectsProvider", () => { expect(latest().processor).toBeDefined(); }); - 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"; render(surface()); await blur(true); - expect(latest().supported).toBe(false); - expect(latest().processor).toBeUndefined(); + expect(latest().supported).toBe(true); + expect(latest().processor).toBeDefined(); }); it("switches to an effect chosen while the camera is off", async () => { diff --git a/src/tracks/BackgroundEffectsContext.tsx b/src/tracks/BackgroundEffectsContext.tsx index 78f47db3f..d582bc0b3 100644 --- a/src/tracks/BackgroundEffectsContext.tsx +++ b/src/tracks/BackgroundEffectsContext.tsx @@ -5,12 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { BackgroundProcessorWrapper } from "@livekit/track-processors"; +import { + BackgroundProcessorWrapper, + supportsBackgroundProcessors, +} from "@livekit/track-processors"; import { createContext, type FC, type JSX, use } from "react"; import { backgroundEffect as backgroundEffectSetting } from "../settings/settings"; import { BackgroundEffectTransformer } from "./BackgroundEffectTransformer"; -import { supportsBackgroundProcessors } from "./backgroundProcessing"; import { type Behavior } from "../state/Behavior"; import { type ObservableScope } from "../state/ObservableScope"; import { diff --git a/src/tracks/backgroundProcessing.ts b/src/tracks/backgroundProcessing.ts deleted file mode 100644 index 4463be3af..000000000 --- a/src/tracks/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(); -}