Skip to content

Commit 63a72af

Browse files
committed
frame scheduler: fix deadlock when responding to frame timings request
1 parent ac32acc commit 63a72af

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

src/frame_scheduler.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ struct frame_scheduler {
4040
DEFINE_REF_OPS(frame_scheduler, n_refs)
4141
DEFINE_STATIC_LOCK_OPS(frame_scheduler, mutex)
4242

43-
struct frame_scheduler *
44-
frame_scheduler_new(bool uses_frame_requests, enum present_mode present_mode, fl_vsync_callback_t vsync_cb, void *userdata) {
43+
struct frame_scheduler *frame_scheduler_new(
44+
bool uses_frame_requests,
45+
enum present_mode present_mode,
46+
fl_vsync_callback_t vsync_cb,
47+
void *userdata
48+
) {
4549
// uses_frame_requests? => vsync_cb != NULL
4650
assert(!uses_frame_requests || vsync_cb != NULL);
4751

@@ -99,11 +103,11 @@ void frame_scheduler_on_fl_vsync_request(struct frame_scheduler *scheduler, intp
99103
// as well if we draw too many frames at once. (Especially considering one framebuffer is probably busy with scanout right now)
100104
//
101105

106+
bool begin_now = false;
107+
102108
if (scheduler->present_mode == kTripleBufferedVsync_PresentMode) {
103109
/// TODO: Query actual frame interval and vblank timestamp here
104-
uint64_t now = get_monotonic_time();
105-
uint64_t now_plus_frame_interval = now + 1000000000/60;
106-
scheduler->vsync_cb(scheduler->userdata, vsync_baton, now, now_plus_frame_interval);
110+
begin_now = true;
107111
} else if (scheduler->present_mode == kDoubleBufferedVsync_PresentMode) {
108112
frame_scheduler_lock(scheduler);
109113

@@ -113,15 +117,19 @@ void frame_scheduler_on_fl_vsync_request(struct frame_scheduler *scheduler, intp
113117
scheduler->pending_frame_timings_request = vsync_baton;
114118
} else {
115119
/// TODO: Query actual frame interval and vblank timestamp here
116-
uint64_t now = get_monotonic_time();
117-
uint64_t now_plus_frame_interval = now + 1000000000/60;
118-
scheduler->vsync_cb(scheduler->userdata, vsync_baton, now, now_plus_frame_interval);
120+
begin_now = true;
119121
}
120122

121123
frame_scheduler_unlock(scheduler);
122124
} else {
123125
UNREACHABLE();
124126
}
127+
128+
if (begin_now) {
129+
uint64_t now = get_monotonic_time();
130+
uint64_t now_plus_frame_interval = now + 1000000000/60;
131+
scheduler->vsync_cb(scheduler->userdata, vsync_baton, now, now_plus_frame_interval);
132+
}
125133
}
126134

127135
void frame_scheduler_on_rendering_complete(struct frame_scheduler *scheduler) {

src/kms/resources.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,4 +796,3 @@ static inline double mode_get_vrefresh(const drmModeModeInfo *mode) {
796796
}
797797

798798
#endif
799-

0 commit comments

Comments
 (0)