Skip to content

Commit 0a91be7

Browse files
authored
Merge pull request #92 from ardera/fix/ebusy-on-atomic-commit
Add workaround if nonblocking atomic commits arent working
2 parents 35dcb4d + 7aff7f6 commit 0a91be7

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

include/compositor.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@ struct compositor {
115115
uint32_t gem_bo_handle;
116116
uint32_t *buffer;
117117
} cursor;
118+
119+
/**
120+
* If true, @ref on_present_layers will commit blockingly.
121+
*
122+
* It will also schedule a simulated page flip event on the main thread
123+
* afterwards so the frame queue works.
124+
*
125+
* If false, @ref on_present_layers will commit nonblocking using page flip events,
126+
* like usual.
127+
*/
128+
bool do_blocking_atomic_commits;
118129
};
119130

120131
/*

src/compositor.c

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct compositor compositor = {
5050
.has_applied_modeset = false,
5151
.should_create_window_surface_backing_store = true,
5252
.stale_rendertargets = CPSET_INITIALIZER(CPSET_DEFAULT_MAX_SIZE),
53+
.do_blocking_atomic_commits = false
5354
};
5455

5556
static struct view_cb_data *get_cbs_for_view_id_locked(int64_t view_id) {
@@ -750,6 +751,31 @@ static bool on_create_backing_store(
750751
return true;
751752
}
752753

754+
struct simulated_page_flip_event_data {
755+
unsigned int sec;
756+
unsigned int usec;
757+
};
758+
759+
extern void on_pageflip_event(
760+
int fd,
761+
unsigned int frame,
762+
unsigned int sec,
763+
unsigned int usec,
764+
void *userdata
765+
);
766+
767+
static int execute_simulate_page_flip_event(void *userdata) {
768+
struct simulated_page_flip_event_data *data;
769+
770+
data = userdata;
771+
772+
on_pageflip_event(flutterpi.drm.drmdev->fd, 0, data->sec, data->usec, NULL);
773+
774+
free(data);
775+
776+
return 0;
777+
}
778+
753779
/// PRESENT FUNCS
754780
static bool on_present_layers(
755781
const FlutterLayer **layers,
@@ -772,7 +798,7 @@ static bool on_present_layers(
772798
eglMakeCurrent(flutterpi.egl.display, flutterpi.egl.surface, flutterpi.egl.surface, flutterpi.egl.root_context);
773799
eglSwapBuffers(flutterpi.egl.display, flutterpi.egl.surface);
774800

775-
req_flags = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;
801+
req_flags = 0 /* DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK*/;
776802
if (compositor->has_applied_modeset == false) {
777803
ok = drmdev_atomic_req_put_modeset_props(req, &req_flags);
778804
if (ok != 0) return false;
@@ -1036,11 +1062,42 @@ static bool on_present_layers(
10361062
}
10371063

10381064
eglMakeCurrent(flutterpi.egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1065+
1066+
do_commit:
1067+
if (compositor->do_blocking_atomic_commits) {
1068+
req_flags &= ~(DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT);
1069+
} else {
1070+
req_flags |= DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
1071+
}
1072+
1073+
ok = drmdev_atomic_req_commit(req, req_flags, NULL);
1074+
if ((compositor->do_blocking_atomic_commits == false) && (ok < 0) && (errno == EBUSY)) {
1075+
printf("[compositor] Non-blocking drmModeAtomicCommit failed with EBUSY.\n"
1076+
" Future drmModeAtomicCommits will be executed blockingly.\n"
1077+
" This may have have an impact on performance.\n");
1078+
1079+
compositor->do_blocking_atomic_commits = true;
1080+
goto do_commit;
1081+
}
10391082

1040-
drmdev_atomic_req_commit(req, req_flags, NULL);
1041-
drmdev_destroy_atomic_req(req);
1083+
if (compositor->do_blocking_atomic_commits) {
1084+
uint64_t time = flutterpi.flutter.libflutter_engine.FlutterEngineGetCurrentTime();
1085+
1086+
struct simulated_page_flip_event_data *data = malloc(sizeof(struct simulated_page_flip_event_data));
1087+
if (data == NULL) {
1088+
return false;
1089+
}
10421090

1091+
data->sec = time / 1000000000llu;
1092+
data->usec = (time % 1000000000llu) / 1000;
1093+
1094+
flutterpi_post_platform_task(execute_simulate_page_flip_event, data);
1095+
}
1096+
1097+
drmdev_destroy_atomic_req(req);
10431098
cpset_unlock(&compositor->cbs);
1099+
1100+
return true;
10441101
}
10451102

10461103
int compositor_on_page_flip(

src/flutter-pi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ static int init_main_loop(void) {
10221022
* DISPLAY INITIALIZATION *
10231023
**************************/
10241024
/// Called on the main thread when a pageflip ocurred.
1025-
static void on_pageflip_event(
1025+
void on_pageflip_event(
10261026
int fd,
10271027
unsigned int frame,
10281028
unsigned int sec,

0 commit comments

Comments
 (0)