15
15
#include <limits.h>
16
16
#include <float.h>
17
17
#include <assert.h>
18
+ #include <time.h>
18
19
19
20
#include <xf86drm.h>
20
21
#include <xf86drmMode.h>
@@ -118,32 +119,30 @@ struct {
118
119
119
120
pthread_t io_thread_id ;
120
121
pthread_t platform_thread_id ;
121
- struct LinkedTaskListElement task_list_head_sentinel = {
122
+ struct FlutterPiTask tasklist = {
122
123
.next = NULL ,
123
124
.is_vblank_event = false,
124
125
.target_time = 0 ,
125
126
.task = {.runner = NULL , .task = 0 }
126
127
};
127
- pthread_mutex_t task_list_lock ;
128
- bool should_notify_platform_thread = false;
129
- sigset_t sigusr1_set ;
130
-
128
+ pthread_mutex_t tasklist_lock = PTHREAD_MUTEX_INITIALIZER ;
129
+ pthread_cond_t task_added = PTHREAD_COND_INITIALIZER ;
131
130
132
131
133
132
/*********************
134
133
* FLUTTER CALLBACKS *
135
134
*********************/
136
135
bool make_current (void * userdata ) {
137
136
if (eglMakeCurrent (egl .display , egl .surface , egl .surface , egl .context ) != EGL_TRUE ) {
138
- fprintf (stderr , "Could not make the context current.\n" );
137
+ fprintf (stderr , "make_current: could not make the context current.\n" );
139
138
return false;
140
139
}
141
140
142
141
return true;
143
142
}
144
143
bool clear_current (void * userdata ) {
145
144
if (eglMakeCurrent (egl .display , EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT ) != EGL_TRUE ) {
146
- fprintf (stderr , "Could not clear the current context.\n" );
145
+ fprintf (stderr , "clear_current: could not clear the current context.\n" );
147
146
return false;
148
147
}
149
148
@@ -165,10 +164,12 @@ struct drm_fb* drm_fb_get_from_bo(struct gbm_bo *bo) {
165
164
uint32_t width , height , format , strides [4 ] = {0 }, handles [4 ] = {0 }, offsets [4 ] = {0 }, flags = 0 ;
166
165
int ok = -1 ;
167
166
167
+ // if the buffer object already has some userdata associated with it,
168
+ // it's the framebuffer we allocated.
168
169
struct drm_fb * fb = gbm_bo_get_user_data (bo );
169
-
170
170
if (fb ) return fb ;
171
171
172
+ // if there's no framebuffer for the bo, we need to create one.
172
173
fb = calloc (1 , sizeof (struct drm_fb ));
173
174
fb -> bo = bo ;
174
175
@@ -197,7 +198,7 @@ struct drm_fb* drm_fb_get_from_bo(struct gbm_bo *bo) {
197
198
198
199
if (ok ) {
199
200
if (flags )
200
- fprintf (stderr , "Modifiers failed!\n" );
201
+ fprintf (stderr , "drm_fb_get_from_bo: modifiers failed!\n" );
201
202
202
203
memcpy (handles , (uint32_t [4 ]){gbm_bo_get_handle (bo ).u32 ,0 ,0 ,0 }, 16 );
203
204
memcpy (strides , (uint32_t [4 ]){gbm_bo_get_stride (bo ),0 ,0 ,0 }, 16 );
@@ -207,7 +208,7 @@ struct drm_fb* drm_fb_get_from_bo(struct gbm_bo *bo) {
207
208
}
208
209
209
210
if (ok ) {
210
- fprintf (stderr , "failed to create fb: %s\n" , strerror (errno ));
211
+ fprintf (stderr , "drm_fb_get_from_bo: failed to create fb: %s\n" , strerror (errno ));
211
212
free (fb );
212
213
return NULL ;
213
214
}
@@ -286,7 +287,7 @@ void cut_word_from_string(char* string, char* word) {
286
287
} while (word_in_str [i ++ + word_length ] != 0 );
287
288
}
288
289
}
289
- const GLubyte * hacked_glGetString (GLenum name ) {
290
+ const GLubyte * hacked_glGetString (GLenum name ) {
290
291
if (name == GL_EXTENSIONS ) {
291
292
static GLubyte * extensions ;
292
293
@@ -365,7 +366,7 @@ const GLubyte* hacked_glGetString(GLenum name) {
365
366
return glGetString (name );
366
367
}
367
368
}
368
- void * proc_resolver (void * userdata , const char * name ) {
369
+ void * proc_resolver (void * userdata , const char * name ) {
369
370
if (name == NULL ) return NULL ;
370
371
371
372
/*
@@ -405,58 +406,36 @@ void handle_sigusr1(int _) {}
405
406
bool init_message_loop () {
406
407
platform_thread_id = pthread_self ();
407
408
408
- // first, initialize the task heap mutex
409
- if (pthread_mutex_init (& task_list_lock , NULL ) != 0 ) {
410
- fprintf (stderr , "Could not initialize task list mutex\n" );
411
- return false;
412
- }
413
-
414
- sigemptyset (& sigusr1_set );
415
- sigaddset (& sigusr1_set , SIGUSR1 );
416
- sigaction (SIGUSR1 , & (struct sigaction ) {.sa_handler = & handle_sigusr1 }, NULL );
417
- pthread_sigmask (SIG_UNBLOCK , & sigusr1_set , NULL );
418
-
419
409
return true;
420
410
}
421
411
bool message_loop (void ) {
422
- should_notify_platform_thread = true;
412
+ struct timespec abstargetspec ;
413
+ uint64_t currenttime , abstarget ;
423
414
424
415
while (true) {
425
- pthread_mutex_lock (& task_list_lock );
426
- if (task_list_head_sentinel .next == NULL ) {
427
- pthread_mutex_unlock (& task_list_lock );
428
- sigwaitinfo (& sigusr1_set , NULL );
429
- continue ;
430
- } else {
431
- uint64_t target_time = task_list_head_sentinel .next -> target_time ;
432
- uint64_t current_time = FlutterEngineGetCurrentTime ();
433
-
434
- if (target_time > current_time ) {
435
- uint64_t diff = target_time - current_time ;
436
-
437
- struct timespec target_timespec = {
438
- .tv_sec = (uint64_t ) (diff / 1000000000ull ),
439
- .tv_nsec = (uint64_t ) (diff % 1000000000ull )
440
- };
416
+ pthread_mutex_lock (& tasklist_lock );
441
417
442
- pthread_mutex_unlock (& task_list_lock );
443
- sigtimedwait (& sigusr1_set , NULL , & target_timespec );
444
- continue ;
445
- }
418
+ // wait for a task to be inserted into the list
419
+ while ((tasklist .next == NULL ))
420
+ pthread_cond_wait (& task_added , & tasklist_lock );
421
+
422
+ // wait for a task to be ready to be run
423
+ while (tasklist .target_time > (currenttime = FlutterEngineGetCurrentTime ())) {
424
+ clock_gettime (CLOCK_REALTIME , & abstargetspec );
425
+ abstarget = abstargetspec .tv_nsec + abstargetspec .tv_sec * 1000000000ull - currenttime ;
426
+ abstargetspec .tv_nsec = abstarget % 1000000000 ;
427
+ abstargetspec .tv_sec = abstarget / 1000000000 ;
428
+
429
+ pthread_cond_timedwait (& task_added , & tasklist_lock , & abstargetspec );
446
430
}
447
431
448
- FlutterTask task = task_list_head_sentinel .next -> task ;
449
- bool is_vblank_event = task_list_head_sentinel .next -> is_vblank_event ;
450
- drmVBlankReply vbl = task_list_head_sentinel .next -> vbl ;
432
+ FlutterTask task = tasklist .next -> task ;
433
+ struct FlutterPiTask * new_first = tasklist .next -> next ;
434
+ free (tasklist .next );
435
+ tasklist .next = new_first ;
451
436
452
- struct LinkedTaskListElement * new_first = task_list_head_sentinel .next -> next ;
453
- free (task_list_head_sentinel .next );
454
- task_list_head_sentinel .next = new_first ;
455
- pthread_mutex_unlock (& task_list_lock );
456
-
457
- if (is_vblank_event ) {
458
-
459
- } else if (FlutterEngineRunTask (engine , & task ) != kSuccess ) {
437
+ pthread_mutex_unlock (& tasklist_lock );
438
+ if (FlutterEngineRunTask (engine , & task ) != kSuccess ) {
460
439
fprintf (stderr , "Error running platform task\n" );
461
440
return false;
462
441
};
@@ -465,24 +444,22 @@ bool message_loop(void) {
465
444
return true;
466
445
}
467
446
void post_platform_task (FlutterTask task , uint64_t target_time , void * userdata ) {
468
- struct LinkedTaskListElement * to_insert = malloc (sizeof (struct LinkedTaskListElement ));
447
+ // prepare the task to be inserted into the tasklist.
448
+ struct FlutterPiTask * to_insert = malloc (sizeof (struct FlutterPiTask ));
469
449
to_insert -> next = NULL ;
470
- to_insert -> is_vblank_event = false;
471
450
to_insert -> task = task ;
472
451
to_insert -> target_time = target_time ;
473
452
474
- pthread_mutex_lock (& task_list_lock );
475
- struct LinkedTaskListElement * this = & task_list_head_sentinel ;
476
- while ((this -> next ) != NULL && (target_time > this -> next -> target_time ))
477
- this = this -> next ;
478
-
479
- to_insert -> next = this -> next ;
480
- this -> next = to_insert ;
481
- pthread_mutex_unlock (& task_list_lock );
482
-
483
- if (should_notify_platform_thread ) {
484
- pthread_kill (platform_thread_id , SIGUSR1 );
485
- }
453
+ // insert the task at a fitting position. (the tasks are ordered by target time)
454
+ pthread_mutex_lock (& tasklist_lock );
455
+ struct FlutterPiTask * this = & tasklist ;
456
+ while ((this -> next ) != NULL && (target_time > this -> next -> target_time ))
457
+ this = this -> next ;
458
+
459
+ to_insert -> next = this -> next ;
460
+ this -> next = to_insert ;
461
+ pthread_mutex_unlock (& tasklist_lock );
462
+ pthread_cond_signal (& task_added );
486
463
}
487
464
bool runs_platform_tasks_on_current_thread (void * userdata ) {
488
465
return pthread_equal (pthread_self (), platform_thread_id ) != 0 ;
@@ -572,7 +549,7 @@ bool init_display(void) {
572
549
573
550
// only update the physical size of the display if the values
574
551
// are not yet initialized / not set with a commandline option
575
- if (!(( width_mm == 0 ) && (height_mm == 0 ) )) {
552
+ if (( width_mm == 0 ) && (height_mm == 0 )) {
576
553
if ((conn -> mmWidth == 160 ) && (conn -> mmHeight == 90 )) {
577
554
// if width and height is exactly 160mm x 90mm, the values are probably bogus.
578
555
width_mm = 0 ;
@@ -939,6 +916,7 @@ bool init_application(void) {
939
916
940
917
return true;
941
918
}
919
+
942
920
void destroy_application (void ) {
943
921
int ok ;
944
922
0 commit comments