diff options
Diffstat (limited to 'src/screen')
| -rw-r--r-- | src/screen/screen.c | 158 | ||||
| -rw-r--r-- | src/screen/screen.h | 14 | ||||
| -rw-r--r-- | src/screen/view.c | 29 | ||||
| -rw-r--r-- | src/screen/view.h | 15 |
4 files changed, 122 insertions, 94 deletions
diff --git a/src/screen/screen.c b/src/screen/screen.c index b4f65c2..cb49188 100644 --- a/src/screen/screen.c +++ b/src/screen/screen.c @@ -5,6 +5,8 @@ #include "view.h" #include "screen.h" +#define SCREEN_INVALID_TS ((u64)-1) + static struct camu_view *get_view_from_mouse_pos(struct camu_screen *scr) { struct camu_view *view = NULL; @@ -27,24 +29,20 @@ static void should_close_callback(void *userdata) scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL); } -static void resize_callback(void *userdata, s32 width, s32 height) +static void resize_callback(void *userdata, u32 width, u32 height) { struct camu_screen *scr = (struct camu_screen *)userdata; - bool fullscreen = scr->window->fullscreen; if (scr->renderer) { - // Checking if window->fullscreen changed here relies on the order of resize events. - // If it's possible for a different resize to be buffered before the resize - // of the fullscreen toggle, this may not work as expected. - scr->renderer->resize(scr->renderer, &width, &height, fullscreen != scr->last_fullscreen); + scr->renderer->resize(scr->renderer, &width, &height); } - scr->width = width; - scr->height = height; - scr->last_fullscreen = fullscreen; + al_assert(width > 0 && height > 0); + scr->width = (u32)width; + scr->height = (u32)height; struct camu_screen_video *video; al_array_foreach_ptr(scr->videos, i, video) { camu_view_calculate(&video->view, scr->width, scr->height); } - scr->force_refresh = true; + al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); } static void refresh_callback(void *userdata) @@ -68,26 +66,25 @@ static bool pointer_pos_callback(void *userdata, f64 x, f64 y) struct camu_screen *scr = (struct camu_screen *)userdata; struct camu_view *view = get_view_from_mouse_pos(scr); bool queue_refresh = false; - if (view) { - if (scr->flags & CAMU_SCREEN_DRAGGING) { - if (!(scr->flags & CAMU_SCREEN_MODIFIER) && - (scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE)) { - f64 dx = x - scr->last_mouse_x; - f64 dy = y - scr->last_mouse_y; - if (camu_view_pan_simple(view, scr->width, scr->height, dx, dy)) { - view->mode = CAMU_VIEW_DETACHED; - queue_refresh = true; - } - if (fabs(dx) + fabs(dy) > 3.0) scr->last_click_ts = 0; - } else { - u64 now = nn_get_timestamp(); - if (!scr->last_click_ts) { - scr->last_click_ts = now; - } - if (now - scr->last_seek_ts > 100000) { - scr->last_seek_ts = now; - seek_to_percent_at_pointer(scr); - } + if (scr->flags & CAMU_SCREEN_DRAGGING) { + if (scr->flags & CAMU_SCREEN_MOD_CONTROL) { + u64 now = nn_get_timestamp(); + if (scr->last_seek_ts == SCREEN_INVALID_TS) { + scr->last_seek_ts = now; + } + if (now - scr->last_seek_ts > 100000) { + scr->last_seek_ts = now; + seek_to_percent_at_pointer(scr); + } + } else if (view && scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE) { + f64 dx = x - scr->last_mouse_x; + f64 dy = y - scr->last_mouse_y; + if (camu_view_pan_simple(view, scr->width, scr->height, dx, dy)) { + view->mode = CAMU_VIEW_DETACHED; + queue_refresh = true; + } + if (fabs(dx) + fabs(dy) > 3.0) { + scr->last_click_ts = SCREEN_INVALID_TS; } } } @@ -105,14 +102,17 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button) case STELA_BUTTON_PRESSED: scr->flags |= CAMU_SCREEN_DRAGGING; scr->last_click_ts = nn_get_timestamp(); + //scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL); break; case STELA_BUTTON_RELEASED: scr->flags &= ~CAMU_SCREEN_DRAGGING; - if (scr->last_click_ts && nn_get_timestamp() - scr->last_click_ts <= 300000) { - if (scr->flags & CAMU_SCREEN_MODIFIER) { + //scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL); + if (scr->last_click_ts != SCREEN_INVALID_TS && + (nn_get_timestamp() - scr->last_click_ts <= 300000)) { + if (scr->flags & CAMU_SCREEN_MOD_CONTROL) { seek_to_percent_at_pointer(scr); } else { - if (scr->last_mouse_x >= scr->width / 2.f) { + if (scr->last_mouse_x >= scr->width / 2.0) { scr->callback(scr->userdata, CAMU_SCREEN_NEXT, NULL); } else { scr->callback(scr->userdata, CAMU_SCREEN_PREVIOUS, NULL); @@ -125,10 +125,10 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button) case STELA_MOUSE2: switch (state) { case STELA_BUTTON_PRESSED: - scr->flags |= CAMU_SCREEN_MODIFIER; + scr->flags |= CAMU_SCREEN_MOD_CONTROL; break; case STELA_BUTTON_RELEASED: - scr->flags &= ~CAMU_SCREEN_MODIFIER; + scr->flags &= ~CAMU_SCREEN_MOD_CONTROL; break; } break; @@ -157,7 +157,7 @@ static bool scroll_callback(void *userdata, f64 y) { struct camu_screen *scr = (struct camu_screen *)userdata; y = -y / SCROLL_MULTIPLIER; - if (!(scr->flags & CAMU_SCREEN_MODIFIER)) { + if (!(scr->flags & CAMU_SCREEN_MOD_CONTROL)) { struct camu_view *view = get_view_from_mouse_pos(scr); if (view) { if (scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE) { @@ -180,8 +180,11 @@ static bool key_callback(void *userdata, u8 state, u8 button) case STELA_BUTTON_PRESSED: //al_printf("%x\n", button); switch (button) { + case 0x2a: // shift + scr->flags |= CAMU_SCREEN_MOD_SHIFT; + break; case 0x1d: // control - scr->flags |= CAMU_SCREEN_MODIFIER; + scr->flags |= CAMU_SCREEN_MOD_CONTROL; break; case 0x10: // q scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL); @@ -215,9 +218,23 @@ static bool key_callback(void *userdata, u8 state, u8 button) case 0x13: { // r struct camu_view *view = get_view_from_mouse_pos(scr); if (view) { - if (!(scr->flags & CAMU_SCREEN_MODIFIER)) { - view->mode = CAMU_DEFAULT_VIEW; - } else { + if (scr->flags & CAMU_SCREEN_MOD_SHIFT) { + switch (view->rotation) { + case CAMU_VIEW_ROTATION_0: + case CAMU_VIEW_ROTATION_360: + view->rotation = CAMU_VIEW_ROTATION_90; + break; + case CAMU_VIEW_ROTATION_270: + view->rotation = CAMU_VIEW_ROTATION_0; + break; + case CAMU_VIEW_ROTATION_180: + view->rotation = CAMU_VIEW_ROTATION_270; + break; + case CAMU_VIEW_ROTATION_90: + view->rotation = CAMU_VIEW_ROTATION_180; + break; + } + } else if (scr->flags & CAMU_SCREEN_MOD_CONTROL) { switch (view->rotation) { case CAMU_VIEW_ROTATION_0: case CAMU_VIEW_ROTATION_360: @@ -233,6 +250,8 @@ static bool key_callback(void *userdata, u8 state, u8 button) view->rotation = CAMU_VIEW_ROTATION_0; break; } + } else { + view->mode = CAMU_DEFAULT_VIEW; } camu_view_calculate(view, scr->width, scr->height); return true; @@ -261,8 +280,11 @@ static bool key_callback(void *userdata, u8 state, u8 button) break; case STELA_BUTTON_RELEASED: switch (button) { + case 0x2a: // shift + scr->flags &= ~CAMU_SCREEN_MOD_SHIFT; + break; case 0x1d: // control - scr->flags &= ~CAMU_SCREEN_MODIFIER; + scr->flags &= ~CAMU_SCREEN_MOD_CONTROL; break; } default: @@ -279,6 +301,10 @@ static void key_immediate_callback(void *userdata, u8 state, u8 button) switch (button) { case 0x21: // f scr->window->toggle_fullscreen(scr->window); + // Least intrusive workaround I can think of for the egl resizing issue. + // Will only work for fullscreening, things like toggling floating state + // on sway are still broken. + al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); break; } break; @@ -301,10 +327,12 @@ bool camu_screen_init(struct camu_screen *scr, void *context) scr->window->should_close_callback = should_close_callback; scr->window->userdata = scr; scr->renderer = NULL; - scr->force_refresh = false; + al_atomic_store(u32)(&scr->force_refresh, 0, AL_ATOMIC_RELAXED); scr->flags = CAMU_SCREEN_ZOOM_PAN_SIMPLE; + scr->last_click_ts = SCREEN_INVALID_TS; scr->last_mouse_x = 0.0; scr->last_mouse_y = 0.0; + scr->last_seek_ts = SCREEN_INVALID_TS; al_array_init(scr->videos); #ifdef CAMU_SCREEN_THREADED al_array_init(scr->add_queue); @@ -334,7 +362,6 @@ bool camu_screen_create_window(struct camu_screen *scr, const char *name) } scr->width = scr->window->width; scr->height = scr->window->height; - scr->last_fullscreen = false; #ifdef STELA_EVENT_BUFFER nn_thread_create(&scr->thread, event_thread, scr); #endif @@ -365,9 +392,9 @@ 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 *added; + al_array_foreach_ptr(scr->videos, i, added) { + al_assert(added->buf != buf); } struct camu_screen_video video = { .buf = buf @@ -383,17 +410,17 @@ static void add_buffer_internal(struct camu_screen *scr, struct camu_video_buffe #endif } else { video.view.mode = CAMU_DEFAULT_VIEW; + video.view.rotation = CAMU_VIEW_ROTATION_0; video.view.width = fmt->width; video.view.height = fmt->height; - video.view.stretch = 1.0; - video.view.rotation = CAMU_VIEW_ROTATION_0; video.view.zindex = 0; + video.view.stretch = 1.0; } camu_view_calculate(&video.view, scr->width, scr->height); #ifdef CAMU_SCREEN_THREADED al_atomic_store(u8)(&buf->ref, 1, AL_ATOMIC_RELAXED); #endif - + //al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); al_array_push(scr->videos, video); } @@ -428,7 +455,6 @@ static void run_queue_internal(struct camu_screen *scr) add_buffer_internal(scr, buf); } scr->add_queue.count = 0; - //scr->force_refresh = scr->videos.count == 0; } #endif @@ -436,15 +462,15 @@ void camu_screen_add_buffer(struct camu_screen *scr, struct camu_video_buffer *b { #ifdef CAMU_SCREEN_THREADED nn_mutex_lock(&scr->mutex); - struct camu_video_buffer *rbuf; - al_array_foreach(scr->add_queue, i, rbuf) { - if (rbuf == buf) { + struct camu_video_buffer *queued; + al_array_foreach(scr->add_queue, i, queued) { + if (queued == buf) { nn_mutex_unlock(&scr->mutex); return; } } - al_array_foreach_rev(scr->rem_queue, i, rbuf) { - if (rbuf == buf) { + al_array_foreach_rev(scr->rem_queue, i, queued) { + if (queued == buf) { al_array_remove_at(scr->rem_queue, i); bool queue_empty = scr->add_queue.count + scr->rem_queue.count == 0; if (queue_empty) { @@ -467,15 +493,15 @@ void camu_screen_remove_buffer(struct camu_screen *scr, struct camu_video_buffer { #ifdef CAMU_SCREEN_THREADED nn_mutex_lock(&scr->mutex); - struct camu_video_buffer *rbuf; - al_array_foreach(scr->rem_queue, i, rbuf) { - if (rbuf == buf) { + struct camu_video_buffer *queued; + al_array_foreach(scr->rem_queue, i, queued) { + if (queued == buf) { nn_mutex_unlock(&scr->mutex); return; } } - al_array_foreach_rev(scr->add_queue, i, rbuf) { - if (rbuf == buf) { + al_array_foreach_rev(scr->add_queue, i, queued) { + if (queued == buf) { al_array_remove_at(scr->add_queue, i); bool queue_empty = scr->add_queue.count + scr->rem_queue.count == 0; if (queue_empty) { @@ -517,12 +543,13 @@ void camu_screen_clear(struct camu_screen *scr) void camu_screen_set_state(struct camu_screen *scr, s32 state) { + // @TODO: What to do if a buffer is queued for removal and we pause here. al_atomic_store(s32)(&scr->state, state, AL_ATOMIC_RELAXED); } void camu_screen_force_refresh(struct camu_screen *scr) { - scr->force_refresh = true; + al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); camu_screen_wake(scr); } @@ -552,9 +579,12 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force) al_assert(state != CAMU_SCREEN_STOPPED); bool paused = state == CAMU_SCREEN_PAUSED; bool do_render = camu_screen_poll(scr, paused) || !paused; - do_render |= scr->force_refresh; - *force = scr->force_refresh; - scr->force_refresh = false; + u32 force_refresh = al_atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE); + do_render |= force_refresh > 0; + *force = force_refresh > 0; + if (force_refresh > 0) { + al_atomic_store(u32)(&scr->force_refresh, 0, AL_ATOMIC_RELEASE); + } return do_render; } diff --git a/src/screen/screen.h b/src/screen/screen.h index e0d1fc3..0b8ed33 100644 --- a/src/screen/screen.h +++ b/src/screen/screen.h @@ -18,9 +18,10 @@ #define CAMU_SCREEN_HEIGHT 700 enum { - CAMU_SCREEN_MODIFIER = 1, - CAMU_SCREEN_DRAGGING = 1 << 1, - CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1 << 2 + CAMU_SCREEN_MOD_SHIFT = 1, + CAMU_SCREEN_MOD_CONTROL = 1 << 1, + CAMU_SCREEN_DRAGGING = 1 << 2, + CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1 << 3 }; enum { @@ -55,11 +56,10 @@ struct camu_screen { struct nn_thread thread; #endif struct camu_renderer *renderer; - bool force_refresh; + atomic(u32) force_refresh; u32 flags; - s32 width; - s32 height; - bool last_fullscreen; + u32 width; + u32 height; u64 last_click_ts; f64 last_mouse_y; f64 last_mouse_x; diff --git a/src/screen/view.c b/src/screen/view.c index 0ca5f4c..b5fade2 100644 --- a/src/screen/view.c +++ b/src/screen/view.c @@ -15,34 +15,33 @@ #define VIEW_ON_ITS_SIDE(view) \ (view->rotation % CAMU_VIEW_ROTATION_180 == CAMU_VIEW_ROTATION_90) -void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_height) +void camu_view_calculate(struct camu_view *view, u32 window_width, u32 window_height) { - f64 width, height; + u32 width, height; if (VIEW_ON_ITS_SIDE(view)) { - width = (f64)view->height; - height = (f64)view->width; - view->stretch = height / width; + width = view->height; + height = view->width; + view->stretch = height / (f64)width; } else { - width = (f64)view->width; - height = (f64)view->height; + width = view->width; + height = view->height; view->stretch = 1.0; } - f64 frame_ratio = width / height; + f64 frame_ratio = width / (f64)height; f64 ratio = window_width / (f64)window_height; - view->ratio = ratio / frame_ratio; switch (view->mode) { case CAMU_VIEW_AUTOFIT: if (frame_ratio > ratio) { - view->zoom = window_width / width; + view->zoom = window_width / (f64)width; } else { - view->zoom = window_height / height; + view->zoom = window_height / (f64)height; } break; case CAMU_VIEW_ZOOM: if (frame_ratio < ratio) { - view->zoom = window_width / width; + view->zoom = window_width / (f64)width; } else { - view->zoom = window_height / height; + view->zoom = window_height / (f64)height; } break; default: @@ -52,7 +51,7 @@ void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_he view->y_offset = (window_height - (height * view->zoom)) / 2.0; } -bool camu_view_pan_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 dx, f64 dy) +bool camu_view_pan_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 dx, f64 dy) { f64 nx = view->x_offset + dx; f64 ny = view->y_offset + dy; @@ -68,7 +67,7 @@ bool camu_view_pan_simple(struct camu_view *view, s32 window_width, s32 window_h return view_changed; } -bool camu_view_zoom_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 x, f64 y, f64 v) +bool camu_view_zoom_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 x, f64 y, f64 v) { x -= view->x_offset; y -= view->y_offset; diff --git a/src/screen/view.h b/src/screen/view.h index 8cd3d28..30b6f64 100644 --- a/src/screen/view.h +++ b/src/screen/view.h @@ -21,17 +21,16 @@ enum { struct camu_view { u8 mode; - s32 width; - s32 height; - f64 ratio; + u8 rotation; + u32 width; + u32 height; + s32 zindex; f64 zoom; f64 x_offset; f64 y_offset; f64 stretch; - s32 rotation; - s32 zindex; }; -void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_height); -bool camu_view_pan_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 dx, f64 dy); -bool camu_view_zoom_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 x, f64 y, f64 v); +void camu_view_calculate(struct camu_view *view, u32 window_width, u32 window_height); +bool camu_view_pan_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 dx, f64 dy); +bool camu_view_zoom_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 x, f64 y, f64 v); |