diff options
Diffstat (limited to 'src/screen')
| -rw-r--r-- | src/screen/screen.c | 69 | ||||
| -rw-r--r-- | src/screen/screen.h | 1 |
2 files changed, 53 insertions, 17 deletions
diff --git a/src/screen/screen.c b/src/screen/screen.c index bd6547f..b10d486 100644 --- a/src/screen/screen.c +++ b/src/screen/screen.c @@ -184,6 +184,9 @@ static bool key_callback(void *userdata, u8 state, u8 button) case 0x12: // e scr->callback(scr->userdata, CAMU_SCREEN_RESEEK, NULL); break; + case 0x16: // u + scr->callback(scr->userdata, CAMU_SCREEN_UNSET, NULL); + break; case 0x13: { // r struct camu_view *view = get_view_from_mouse_pos(scr); if (view) { @@ -331,6 +334,10 @@ bool camu_screen_create_renderer(struct camu_screen *scr, struct camu_renderer * static void add_buffer_internal(struct camu_screen *scr, struct camu_video_buffer *buf) { + struct camu_screen_video *rvideo; + al_array_foreach_ptr(scr->videos, i, rvideo) { + al_assert(rvideo->buf != buf); + } struct camu_screen_video video = { .buf = buf }; @@ -355,6 +362,7 @@ static void add_buffer_internal(struct camu_screen *scr, struct camu_video_buffe #ifdef CAMU_SCREEN_THREADED al_atomic_store(u8)(&buf->ref, 1, AL_ATOMIC_RELAXED); #endif + al_array_push(scr->videos, video); } @@ -373,12 +381,48 @@ static void remove_buffer_internal(struct camu_screen *scr, struct camu_video_bu } } +#ifdef CAMU_SCREEN_THREADED +static void run_queue_internal(struct camu_screen *scr) +{ + struct camu_video_buffer *buf; + al_array_foreach(scr->rem_queue, i, buf) { + remove_buffer_internal(scr, buf); + } + scr->rem_queue.size = 0; + // src->videos cannot be touched outside of the add/remove queue context. + // For example, reserving space inside of screen_add_buffer() instead + // of here would be very wrong. + al_array_reserve(scr->videos, scr->videos.size + scr->add_queue.size); + al_array_foreach(scr->add_queue, i, buf) { + add_buffer_internal(scr, buf); + } + scr->add_queue.size = 0; +} +#endif + void camu_screen_add_buffer(struct camu_screen *scr, struct camu_video_buffer *buf) { #ifdef CAMU_SCREEN_THREADED aki_mutex_lock(&scr->mutex); + struct camu_video_buffer *rbuf; + al_array_foreach(scr->add_queue, i, rbuf) { + if (rbuf == buf) { + aki_mutex_unlock(&scr->mutex); + return; + } + } + al_array_foreach_rev(scr->rem_queue, i, rbuf) { + if (rbuf == buf) { + al_array_remove_at(scr->rem_queue, i); + bool queue_empty = scr->add_queue.size + scr->rem_queue.size == 0; + if (queue_empty) { + al_atomic_store(u8)(&scr->queued, 0, AL_ATOMIC_RELAXED); + } + aki_mutex_unlock(&scr->mutex); + return; + } + } al_array_push(scr->add_queue, buf); - al_array_reserve(scr->videos, scr->videos.size + scr->add_queue.size); al_atomic_store(u8)(&scr->queued, 1, AL_ATOMIC_RELAXED); aki_mutex_unlock(&scr->mutex); #else @@ -387,27 +431,18 @@ void camu_screen_add_buffer(struct camu_screen *scr, struct camu_video_buffer *b camu_screen_wake(scr); } -#ifdef CAMU_SCREEN_THREADED -static void run_queue_internal(struct camu_screen *scr) -{ - struct camu_video_buffer *buf; - al_array_foreach(scr->add_queue, i, buf) { - add_buffer_internal(scr, buf); - } - scr->add_queue.size = 0; - al_array_foreach(scr->rem_queue, i, buf) { - remove_buffer_internal(scr, buf); - } - scr->rem_queue.size = 0; -} -#endif - void camu_screen_remove_buffer(struct camu_screen *scr, struct camu_video_buffer *buf) { #ifdef CAMU_SCREEN_THREADED aki_mutex_lock(&scr->mutex); struct camu_video_buffer *rbuf; - al_array_foreach(scr->add_queue, i, rbuf) { + al_array_foreach(scr->rem_queue, i, rbuf) { + if (rbuf == buf) { + aki_mutex_unlock(&scr->mutex); + return; + } + } + al_array_foreach_rev(scr->add_queue, i, rbuf) { if (rbuf == buf) { al_array_remove_at(scr->add_queue, i); bool queue_empty = scr->add_queue.size + scr->rem_queue.size == 0; diff --git a/src/screen/screen.h b/src/screen/screen.h index b81b5e5..23a85d0 100644 --- a/src/screen/screen.h +++ b/src/screen/screen.h @@ -34,6 +34,7 @@ enum { CAMU_SCREEN_TOGGLE_PAUSE, CAMU_SCREEN_SEEK, CAMU_SCREEN_RESEEK, + CAMU_SCREEN_UNSET, CAMU_SCREEN_VOLUME, CAMU_SCREEN_CLOSE }; |