summaryrefslogtreecommitdiff
path: root/src/screen
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen')
-rw-r--r--src/screen/screen.c69
-rw-r--r--src/screen/screen.h1
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
};