Fix browser source tearing with hardware acceleration #531
Labels
No labels
area/accessibility
area/dependency
Confirmed
Crash Report
Delayed
Design Issue
Duplicate
Feedback required
Good first issue
kind/bug
kind/cleanup
kind/enhancement
platform/linux
platform/macos
platform/windows
priority/high
Question
Request for Comments
Seeking Other Contributors
Seeking Testers
Won't Fix / By Design
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-obsproject/obs-browser!531
Loading…
Reference in a new issue
No description provided.
Delete branch "blastorg/fix/source_tearing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
Since the CEF M124 OSR rework,
OnAcceleratedPainthands out a texture from a small internal pool, with no keyed mutex. The handle "cannot be cached and cannot be accessed outside of this callback" and the contents "should be copied to a texture owned by the client application". "Resources will be released to the underlying pool for reuse when the callback returns" and that the texture "is instantiated without a keyed mutex".The current implementation does the opposite: open the handle, keep the resource as
bs->texture, and let the render thread sample it during composition at some later point. When the compositor falls behind under CPU load, CEF is already writing a later frame into that same pooled texture while we sample it, which shows up as the one-frame swaps and tears from the issue.Fix
CopyAcceleratedTexture()now copies the frame into a texture we own, inside the callback, while the handle is guaranteed valid. The copy target is reused across frames and only reallocated when the size or format changes.gs_flush()submits the copy before the callback returns, since the pooled texture can be reused after that. The render thread then samples our private, stable copy.The
gs_texture_acquire_sync(shared, 1, 50)is a no-op right now but it cooperates, with a bounded wait, if a future producer exposes a keyed mutex.One note: the flush submits the copy but cannot fence it, because CEF exposes no fence through this API. This is as close to the documented contract as a consumer can get. The exposure window shrinks from a full compositor frame of sampling to command submission granularity, and the pool depth gives the copy several frame intervals of slack in practice.
Motivation and Context
Recurrence of #488
How Has This Been Tested?
Retested multiple times against example from #488, and with python script to detect tear artifacts.
Types of changes
Checklist:
I have independently tested the patch and this solves our issue!
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.