Skip to content

Commit a580b8d

Browse files
committed
frame scheduling: forward flutter vsync requests to frame scheduler
1 parent 30e8dd1 commit a580b8d

File tree

2 files changed

+27
-81
lines changed

2 files changed

+27
-81
lines changed

src/flutter-pi.c

Lines changed: 26 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ struct flutterpi {
262262
bool session_active;
263263

264264
char *desired_videomode;
265+
266+
struct frame_scheduler *scheduler;
265267
};
266268

267269
struct device_id_and_fd {
@@ -470,16 +472,13 @@ struct frame_req {
470472
};
471473

472474
static int on_deferred_begin_frame(void *userdata) {
473-
FlutterEngineResult engine_result;
474-
struct frame_req *req;
475-
476475
ASSERT_NOT_NULL(userdata);
477-
req = userdata;
476+
struct frame_req *req = userdata;
478477

479478
assert(flutterpi_runs_platform_tasks_on_current_thread(req->flutterpi));
480479

481480
TRACER_INSTANT(req->flutterpi->tracer, "FlutterEngineOnVsync");
482-
engine_result = req->flutterpi->flutter.procs.OnVsync(req->flutterpi->flutter.engine, req->baton, req->vblank_ns, req->next_vblank_ns);
481+
FlutterEngineResult engine_result = req->flutterpi->flutter.procs.OnVsync(req->flutterpi->flutter.engine, req->baton, req->vblank_ns, req->next_vblank_ns);
483482

484483
free(req);
485484

@@ -491,88 +490,39 @@ static int on_deferred_begin_frame(void *userdata) {
491490
return 0;
492491
}
493492

494-
UNUSED static void on_begin_frame(void *userdata, uint64_t vblank_ns, uint64_t next_vblank_ns) {
495-
FlutterEngineResult engine_result;
496-
struct frame_req *req;
497-
int ok;
498-
493+
static void on_begin_frame(void *userdata, intptr_t baton, uint64_t vblank_ns, uint64_t next_vblank_ns) {
499494
ASSERT_NOT_NULL(userdata);
500-
req = userdata;
495+
struct flutterpi *flutterpi = userdata;
501496

502-
if (flutterpi_runs_platform_tasks_on_current_thread(req->flutterpi)) {
503-
TRACER_INSTANT(req->flutterpi->tracer, "FlutterEngineOnVsync");
497+
if (flutterpi_runs_platform_tasks_on_current_thread(flutterpi)) {
498+
TRACER_INSTANT(flutterpi->tracer, "FlutterEngineOnVsync");
504499

505-
engine_result = req->flutterpi->flutter.procs.OnVsync(req->flutterpi->flutter.engine, req->baton, vblank_ns, next_vblank_ns);
500+
FlutterEngineResult engine_result = flutterpi->flutter.procs.OnVsync(flutterpi->flutter.engine, baton, vblank_ns, next_vblank_ns);
506501
if (engine_result != kSuccess) {
507502
LOG_ERROR("Couldn't signal frame begin to flutter engine. FlutterEngineOnVsync: %s\n", FLUTTER_RESULT_TO_STRING(engine_result));
508-
goto fail_free_req;
509503
}
510-
511-
free(req);
512504
} else {
505+
struct frame_req *req = malloc(sizeof(struct frame_req));
506+
req->flutterpi = flutterpi;
507+
req->baton = baton;
513508
req->vblank_ns = vblank_ns;
514509
req->next_vblank_ns = next_vblank_ns;
515-
ok = flutterpi_post_platform_task(on_deferred_begin_frame, req);
510+
511+
int ok = flutterpi_post_platform_task(on_deferred_begin_frame, req);
516512
if (ok != 0) {
517513
LOG_ERROR("Couldn't defer signalling frame begin.\n");
518-
goto fail_free_req;
514+
free(req);
519515
}
520516
}
521-
522-
return;
523-
524-
fail_free_req:
525-
free(req);
526-
return;
527517
}
528518

529-
/// Called on some flutter internal thread to request a frame,
530-
/// and also get the vblank timestamp of the pageflip preceding that frame.
531-
UNUSED static void on_frame_request(void *userdata, intptr_t baton) {
532-
FlutterEngineResult engine_result;
533-
struct flutterpi *flutterpi;
534-
struct frame_req *req;
535-
int ok;
536-
519+
static void on_frame_timings_request(void *userdata, intptr_t baton) {
537520
ASSERT_NOT_NULL(userdata);
538-
flutterpi = userdata;
521+
struct flutterpi *flutterpi = userdata;
539522

540-
TRACER_INSTANT(flutterpi->tracer, "on_frame_request");
523+
TRACER_INSTANT(flutterpi->tracer, "on_frame_timings_request");
541524

542-
req = malloc(sizeof *req);
543-
if (req == NULL) {
544-
LOG_ERROR("Out of memory\n");
545-
return;
546-
}
547-
548-
req->flutterpi = flutterpi;
549-
req->baton = baton;
550-
req->vblank_ns = get_monotonic_time();
551-
req->next_vblank_ns = req->vblank_ns + (uint64_t) (1000000000.0 / compositor_get_refresh_rate(flutterpi->compositor));
552-
553-
if (flutterpi_runs_platform_tasks_on_current_thread(req->flutterpi)) {
554-
TRACER_INSTANT(req->flutterpi->tracer, "FlutterEngineOnVsync");
555-
556-
engine_result =
557-
req->flutterpi->flutter.procs.OnVsync(req->flutterpi->flutter.engine, req->baton, req->vblank_ns, req->next_vblank_ns);
558-
if (engine_result != kSuccess) {
559-
LOG_ERROR("Couldn't signal frame begin to flutter engine. FlutterEngineOnVsync: %s\n", FLUTTER_RESULT_TO_STRING(engine_result));
560-
goto fail_free_req;
561-
}
562-
563-
free(req);
564-
} else {
565-
ok = flutterpi_post_platform_task(on_deferred_begin_frame, req);
566-
if (ok != 0) {
567-
LOG_ERROR("Couldn't defer signalling frame begin.\n");
568-
goto fail_free_req;
569-
}
570-
}
571-
572-
return;
573-
574-
fail_free_req:
575-
free(req);
525+
frame_scheduler_on_fl_vsync_request(flutterpi->scheduler, baton);
576526
}
577527

578528
UNUSED static FlutterTransformation on_get_transformation(void *userdata) {
@@ -1351,7 +1301,7 @@ static FlutterEngine create_flutter_engine(
13511301
project_args.update_semantics_custom_action_callback = NULL;
13521302
project_args.persistent_cache_path = paths->asset_bundle_path;
13531303
project_args.is_persistent_cache_read_only = false;
1354-
project_args.vsync_callback = NULL; // on_frame_request, /* broken since 2.2, kinda *
1304+
project_args.vsync_callback = on_frame_timings_request;
13551305
project_args.custom_dart_entrypoint = NULL;
13561306
project_args.custom_task_runners = &custom_task_runners;
13571307
project_args.shutdown_dart_vm_when_done = true;
@@ -2252,7 +2202,6 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
22522202
enum renderer_type renderer_type;
22532203
struct texture_registry *texture_registry;
22542204
struct plugin_registry *plugin_registry;
2255-
struct frame_scheduler *scheduler;
22562205
struct flutter_paths *paths;
22572206
struct view_geometry geometry;
22582207
FlutterEngineAOTData aot_data;
@@ -2273,7 +2222,7 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
22732222
char **engine_argv, *desired_videomode;
22742223
int ok, engine_argc, wakeup_fd;
22752224

2276-
fpi = malloc(sizeof *fpi);
2225+
fpi = calloc(1, sizeof *fpi);
22772226
if (fpi == NULL) {
22782227
return NULL;
22792228
}
@@ -2425,8 +2374,8 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
24252374
goto fail_destroy_drmdev;
24262375
}
24272376

2428-
scheduler = frame_scheduler_new(false, kDoubleBufferedVsync_PresentMode, NULL, NULL);
2429-
if (scheduler == NULL) {
2377+
fpi->scheduler = frame_scheduler_new(true, kDoubleBufferedVsync_PresentMode, on_begin_frame, fpi);
2378+
if (fpi->scheduler == NULL) {
24302379
LOG_ERROR("Couldn't create frame scheduler.\n");
24312380
goto fail_unref_tracer;
24322381
}
@@ -2475,7 +2424,7 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
24752424
if (cmd_args.dummy_display) {
24762425
window = dummy_window_new(
24772426
tracer,
2478-
scheduler,
2427+
fpi->scheduler,
24792428
renderer_type,
24802429
gl_renderer,
24812430
vk_renderer,
@@ -2489,7 +2438,7 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
24892438
window = kms_window_new(
24902439
// clang-format off
24912440
tracer,
2492-
scheduler,
2441+
fpi->scheduler,
24932442
renderer_type,
24942443
gl_renderer,
24952444
vk_renderer,
@@ -2653,7 +2602,6 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
26532602
}
26542603

26552604
// We don't need these anymore.
2656-
frame_scheduler_unref(scheduler);
26572605
window_unref(window);
26582606

26592607
free(cmd_args.bundle_path);
@@ -2715,7 +2663,7 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
27152663
}
27162664

27172665
fail_unref_scheduler:
2718-
frame_scheduler_unref(scheduler);
2666+
frame_scheduler_unref(fpi->scheduler);
27192667

27202668
fail_unref_tracer:
27212669
tracer_unref(tracer);

src/frame_scheduler.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@ DEFINE_STATIC_LOCK_OPS(frame_scheduler, mutex)
4040

4141
struct frame_scheduler *
4242
frame_scheduler_new(bool uses_frame_requests, enum present_mode present_mode, fl_vsync_callback_t vsync_cb, void *userdata) {
43-
struct frame_scheduler *scheduler;
44-
4543
// uses_frame_requests? => vsync_cb != NULL
4644
assert(!uses_frame_requests || vsync_cb != NULL);
4745

48-
scheduler = malloc(sizeof *scheduler);
46+
struct frame_scheduler *scheduler = calloc(1, sizeof *scheduler);
4947
if (scheduler == NULL) {
5048
return NULL;
5149
}

0 commit comments

Comments
 (0)