Full screen (bypassed) surfaces (e.g. GLMark2Test) are missing frames and appear to freeze or judder with swap interval 0
Bug #1379685 reported by
Daniel van Vugt
This bug affects 1 person
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Mir |
Fix Released
|
Medium
|
Daniel van Vugt | ||
mir (Ubuntu) |
Fix Released
|
Medium
|
Unassigned |
Bug Description
I'm observing missing client frames when swap interval is set to zero.
Test case (1):
https:/
Test case (2):
sudo bin/mir_
Expected: Perfect smoothness
Observed: Constant slight visible judder during all the animations.
Related branches
lp://staging/~vanvugt/mir/unfreeze-1
- PS Jenkins bot (community): Needs Fixing (continuous-integration)
- Alan Griffiths: Approve
- Alexandros Frantzis (community): Approve
-
Diff: 271 lines (+163/-51)2 files modifiedsrc/server/compositor/buffer_queue.cpp (+71/-43)
tests/unit-tests/compositor/test_buffer_queue.cpp (+92/-8)
lp://staging/~vanvugt/mir/unfreeze-2
On hold
for merging
into
lp://staging/mir
- PS Jenkins bot (community): Needs Fixing (continuous-integration)
- Mir development team: Pending requested
-
Diff: 256 lines (+150/-46)3 files modifiedsrc/server/compositor/buffer_queue.cpp (+66/-45)
src/server/compositor/buffer_queue.h (+2/-0)
tests/unit-tests/compositor/test_buffer_queue.cpp (+82/-1)
Changed in mir: | |
assignee: | nobody → Daniel van Vugt (vanvugt) |
Changed in mir: | |
milestone: | 0.9.0 → 0.10.0 |
Changed in mir: | |
assignee: | nobody → Daniel van Vugt (vanvugt) |
Changed in mir: | |
status: | Triaged → In Progress |
description: | updated |
summary: |
- Full screen (bypassed) surfaces are missing frames and appear to freeze - with swap interval 0 + Full screen (bypassed) surfaces (e.g. GLMark2Test) are missing frames + and appear to freeze or judder with swap interval 0 |
Changed in mir: | |
status: | In Progress → Fix Committed |
Changed in mir: | |
status: | Fix Committed → Fix Released |
To post a comment you must log in.
The problem appears to be our new(ish) drop_frame implementation:
void mc::BufferQueue ::drop_ frame(std: :unique_ lock<std: :mutex> lock) to_composite_ queue); current_ compositor_ buffer, buffers_ sent_to_ compositor) )
current_ buffer_ users.clear( );
current_ buffer_ users.push_ back(impossible _user_id) ;
std::swap( buffer_ to_give, current_ compositor_ buffer) ; buffer_ to_client( buffer_ to_give, std::move(lock));
{
auto buffer_to_give = pop(ready_
/* Advance compositor buffer so it always points to the most recent
* client content
*/
if (!contains(
{
void const* const impossible_user_id = this;
}
give_
}
The issue is that ready_to_ composite_ queue.size( ) == 1, somehow, and so we're actually dropping the newest frame. The complicated swapping logic in the middle (which seems to be an attempt to avoid the problem) appears to be doing nothing, or simply not working.