diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer/audio.c | 4 | ||||
| -rw-r--r-- | src/buffer/clock.c | 11 | ||||
| -rw-r--r-- | src/buffer/frame_queue.h | 4 | ||||
| -rw-r--r-- | src/buffer/peak_buffer.c | 2 | ||||
| -rw-r--r-- | src/buffer/peak_buffer.h | 2 | ||||
| -rw-r--r-- | src/buffer/video.c | 1 | ||||
| -rw-r--r-- | src/cache/handlers/cdio.c | 17 | ||||
| -rw-r--r-- | src/fruits/cmv/cmv.c | 6 | ||||
| -rw-r--r-- | src/fruits/ctv/ctv.c | 56 | ||||
| -rw-r--r-- | src/fruits/droid/ctv/app/src/main/AndroidManifest.xml | 1 | ||||
| -rw-r--r-- | src/fruits/droid/ctv/gradle/libs.versions.toml | 2 | ||||
| -rw-r--r-- | src/liana/client.c | 4 | ||||
| -rw-r--r-- | src/libsink/common.h | 1 | ||||
| -rw-r--r-- | src/libsink/sink.c | 13 | ||||
| -rw-r--r-- | src/render/queue_libplacebo.c | 52 | ||||
| -rw-r--r-- | src/render/queue_tiger.c | 2 | ||||
| -rw-r--r-- | src/render/renderer.h | 2 | ||||
| -rw-r--r-- | src/render/renderer_libplacebo.c | 10 | ||||
| -rw-r--r-- | src/render/renderer_tiger.c | 3 | ||||
| -rw-r--r-- | src/screen/screen.c | 12 | ||||
| -rw-r--r-- | src/screen/screen.h | 3 | ||||
| -rw-r--r-- | src/sink/desktop.c | 7 |
22 files changed, 139 insertions, 76 deletions
diff --git a/src/buffer/audio.c b/src/buffer/audio.c index 5a956ec..c0556e2 100644 --- a/src/buffer/audio.c +++ b/src/buffer/audio.c @@ -143,7 +143,7 @@ static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32 } size_t have = camu_audio_format_samples_to_bytes(&buf->fmt.req, (size_t)sample_count); - size_t peak = camu_peak_buffer_size(&buf->peak); + size_t peak = camu_peak_buffer_get_size(&buf->peak); if (space < have + peak) { al_assert(have < buf->mark.min); camu_peak_buffer_push(&buf->peak, data[0], have); @@ -333,7 +333,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re if (have < req) { // We don't have enough data to fulfill our request. if (flow == FLUSHED) { // Stream is flushed. // Check peak buffer for any remaining data. - ret = camu_peak_buffer_size(&buf->peak); + ret = camu_peak_buffer_get_size(&buf->peak); if (ret > 0) { // This doesn't break single reader, single writer because // pushing data after a flush is not allowed. diff --git a/src/buffer/clock.c b/src/buffer/clock.c index cbf63d5..33118aa 100644 --- a/src/buffer/clock.c +++ b/src/buffer/clock.c @@ -14,8 +14,11 @@ void camu_clock_init(struct camu_clock *clock, void (*callback)(void *, u8), voi static f64 calc_tick_offset(f64 tick, u64 now, u64 target) { - if (now > target) return tick - (now - target) / 1000000.0; - else return tick + (target - now) / 1000000.0; + if (now > target) { + return tick - (now - target) / 1000000.0; + } else { + return tick + (target - now) / 1000000.0; + } } void camu_clock_set(struct camu_clock *clock, f64 base) @@ -107,12 +110,15 @@ f64 camu_clock_get_pts(struct camu_clock *clock, f64 offset) { f64 pause = al_atomic_load(f64)(&clock->pause, AL_ATOMIC_ACQUIRE); if (pause == PAUSED) return -1.0; + f64 current = nn_get_tick(); + f64 tick = al_atomic_load(f64)(&clock->tick, AL_ATOMIC_RELAXED); if (tick == -1.0) { tick = al_atomic_compare_and_swap(f64)(&clock->tick, -1.0, current); if (tick == -1.0) tick = current; } + // pause > 0.0 means running or pause armed. if (pause > 0.0 && current > pause) { current = pause; @@ -121,5 +127,6 @@ f64 camu_clock_get_pts(struct camu_clock *clock, f64 offset) clock->callback(clock->userdata, CAMU_CLOCK_PAUSED); } } + return clock->base + (current - (tick + clock->offset)) + offset; } diff --git a/src/buffer/frame_queue.h b/src/buffer/frame_queue.h index e3044f1..e40971d 100644 --- a/src/buffer/frame_queue.h +++ b/src/buffer/frame_queue.h @@ -16,10 +16,12 @@ enum { struct camu_frame_queue { struct camu_video_buffer *buf; +#ifdef CAMU_HAVE_FFMPEG + bool (*configure_subtitles)(struct camu_frame_queue *, s32, s32, AVCodecParameters *); +#endif void (*push)(struct camu_frame_queue *, struct camu_codec_frame *, f64); #ifdef CAMU_HAVE_FFMPEG void (*push_av_frame)(struct camu_frame_queue *, AVFrame *, f64); - bool (*configure_subtitles)(struct camu_frame_queue *, s32, s32, AVCodecParameters *); void (*push_subtitle)(struct camu_frame_queue *, AVPacket *); #endif void (*flush)(struct camu_frame_queue *); diff --git a/src/buffer/peak_buffer.c b/src/buffer/peak_buffer.c index eec031a..9687a1f 100644 --- a/src/buffer/peak_buffer.c +++ b/src/buffer/peak_buffer.c @@ -13,7 +13,7 @@ void camu_peak_buffer_push(struct camu_peak_buffer *buf, u8 *data, size_t size) nn_buffer_append(&buf->buf, data, size); } -size_t camu_peak_buffer_size(struct camu_peak_buffer *buf) +size_t camu_peak_buffer_get_size(struct camu_peak_buffer *buf) { return nn_buffer_get_size(&buf->buf); } diff --git a/src/buffer/peak_buffer.h b/src/buffer/peak_buffer.h index ebb9939..9bd3316 100644 --- a/src/buffer/peak_buffer.h +++ b/src/buffer/peak_buffer.h @@ -9,6 +9,6 @@ struct camu_peak_buffer { void camu_peak_buffer_init(struct camu_peak_buffer *buf, size_t size); void camu_peak_buffer_push(struct camu_peak_buffer *buf, u8 *data, size_t size); -size_t camu_peak_buffer_size(struct camu_peak_buffer *buf); +size_t camu_peak_buffer_get_size(struct camu_peak_buffer *buf); u8 *camu_peak_buffer_flush(struct camu_peak_buffer *buf); void camu_peak_buffer_free(struct camu_peak_buffer *buf); diff --git a/src/buffer/video.c b/src/buffer/video.c index 94c452d..245f3d2 100644 --- a/src/buffer/video.c +++ b/src/buffer/video.c @@ -47,7 +47,6 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code const char *format_name = camu_pixel_format_name(fmt->format); if (!format_name) format_name = "unknown"; al_log_info("video_buffer", "Stream: %s (%dx%d) %s.", format_name, fmt->width, fmt->height, "IMAGE"); - break; } #ifdef CAMU_HAVE_FFMPEG diff --git a/src/cache/handlers/cdio.c b/src/cache/handlers/cdio.c index b10bbf1..ffaaa62 100644 --- a/src/cache/handlers/cdio.c +++ b/src/cache/handlers/cdio.c @@ -14,11 +14,12 @@ static void cdio_log_messages(struct cch_handler_cdio *cdio) { char *error_messages = cdio_cddap_errors(cdio->drive); - char *messages = cdio_cddap_messages(cdio->drive); if (error_messages) { al_log_error("cdio", "\n%s", error_messages); cdio_cddap_free_messages(error_messages); } + + char *messages = cdio_cddap_messages(cdio->drive); if (messages) { al_log_info("cdio", "\n%s", messages); cdio_cddap_free_messages(messages); @@ -34,7 +35,8 @@ static bool handler_cdio_can_seek(struct cch_handler *handler) static nn_thread_result NNWT_THREADCALL cd_read_thread(void *userdata) { struct cch_handler_cdio *cdio = (struct cch_handler_cdio *)userdata; - while (1) { + + for (;;) { if (!al_atomic_load(s32)(&cdio->running, AL_ATOMIC_RELAXED)) { // We don't care about how complete the disc read was. return 0; @@ -72,11 +74,13 @@ static nn_thread_result NNWT_THREADCALL cd_read_thread(void *userdata) break; } } + if (cdio->sector <= cdio->end) { al_log_warn("cdio", "Disc read cut short (sectors: %zd, end: %zd).", cdio->sector, cdio->end); // We didn't read the full disc, disable waiters. cch_threaded_waits_disable_all(&cdio->handler); } + return 0; } @@ -148,9 +152,10 @@ static bool open_cd_drive(struct cch_handler_cdio *cdio) al_log_warn("cdio", "Failed to set drive speed (%d).", ret); } - // Not sure what this is based on, but it can seemingly just be wrong. track_t tracks = cdio_cddap_tracks(drive); - al_log_info("cdio", "CD with %d tracks loaded.", tracks); + track_t first_track = cdio_get_first_track_num(drive->p_cdio); + track_t last_track = cdio_get_last_track_num(drive->p_cdio); + al_log_info("cdio", "CD with %d tracks loaded (%d-%d).", tracks, first_track, last_track); al_array_reserve(cdio->handler.entry->chapters, tracks); lsn_t start = cdio_cddap_disc_firstsector(drive); @@ -196,7 +201,9 @@ struct cch_entry *cch_handler_cdio_create(void) entry->handler->free = handler_cdio_free; entry->handler->entry = entry; al_str_from(&entry->handler->liana, "cdio"); - if (!open_cd_drive(cdio)) return NULL; + if (!open_cd_drive(cdio)) { + return NULL; + } al_atomic_store(s32)(&cdio->running, 0, AL_ATOMIC_RELAXED); nn_buffer_init(&cdio->buffer); nn_buffer_ensure_space(&cdio->buffer, BYTES_PER_STEP); diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c index 8509485..6fd1f38 100644 --- a/src/fruits/cmv/cmv.c +++ b/src/fruits/cmv/cmv.c @@ -12,7 +12,11 @@ #include "../common.h" +#ifndef CAMU_SINK_ONLY +#ifndef _WIN32 static str *CMV_UNIX_PATH = al_str_c("/tmp/cmv_sock"); +#endif +#endif struct cmv { struct nn_event_loop loop; @@ -87,7 +91,7 @@ s32 wmain(s32 argc, wchar_t **argv) addr = CAMU_TEST_ADDR; } #else - type = NNWT_SOCKET_TCP; addr = CAMU_SERVER_IP; + type = NNWT_SOCKET_TCP; addr = CAMU_TEST_ADDR; #endif #ifndef CAMU_SINK_ONLY diff --git a/src/fruits/ctv/ctv.c b/src/fruits/ctv/ctv.c index c7bd250..b350c8a 100644 --- a/src/fruits/ctv/ctv.c +++ b/src/fruits/ctv/ctv.c @@ -8,7 +8,9 @@ #include "../../mixer/audio_null.h" #include "../../mixer/audio_miniaudio.h" #include "../../sink/common.h" -#include "../../server/common.c" +#include "../../server/common.h" + +#include "../common.h" struct ctv { struct nn_event_loop loop; @@ -44,37 +46,44 @@ static nn_thread_result NNWT_THREADCALL event_loop_thread(void *userdata) return 0; } +static void to_be_removed_inline_create_client(struct ctv *c, GLFMDisplay *display) +{ + c->scr.callback = screen_callback; + c->scr.userdata = c; + camu_screen_init(&c->scr, display); + camu_screen_create_window(&c->scr, "ctv"); + c->renderer = camu_renderer_lp_create(); + camu_screen_create_renderer(&c->scr, c->renderer); + + camu_mixer_init(&c->mixer, camu_audio_miniaudio_create()); + c->mixer.audio->configure_stream(c->mixer.audio, NULL); + camu_mixer_pick_format(&c->mixer, &c->mixer.fmt); + + nn_event_loop_init(&c->loop); + + camu_sink_init(&c->sink, &c->loop, &c->mixer, c->renderer); + al_str_from(&c->sink.default_list, "default"); + c->sink.callback = sink_callback; + c->sink.userdata = c; + camu_sink_connect(&c->sink, NNWT_SOCKET_TCP, CAMU_TEST_IP, CAMU_PORT, al_str_c("ctv")); + + nn_thread_create(&c->thread, event_loop_thread, c); +} + static void onSurfaceCreated(GLFMDisplay *display, s32 width, s32 height) { struct ctv *c = (struct ctv *)glfmGetUserData(display); (void)width; (void)height; + GLFMRenderingAPI api = glfmGetRenderingAPI(display); al_log_info("window_glfm", "Created GLES context of version %s.", api == GLFMRenderingAPIOpenGLES32 ? "3.2" : api == GLFMRenderingAPIOpenGLES31 ? "3.1" : api == GLFMRenderingAPIOpenGLES3 ? "3.0" : "2.0"); - if (!c->created) { - c->scr.callback = screen_callback; - c->scr.userdata = c; - camu_screen_init(&c->scr, display); - camu_screen_create_window(&c->scr, "ctv"); - c->renderer = camu_renderer_lp_create(); - camu_screen_create_renderer(&c->scr, c->renderer); - - camu_mixer_init(&c->mixer, camu_audio_miniaudio_create()); - c->mixer.audio->configure_stream(c->mixer.audio, NULL); - camu_mixer_pick_format(&c->mixer, &c->mixer.fmt); - - nn_event_loop_init(&c->loop); - - camu_sink_init(&c->sink, &c->loop, &c->mixer, c->renderer); - c->sink.callback = sink_callback; - c->sink.userdata = c; - camu_sink_connect(&c->sink, NNWT_SOCKET_TCP, CAMU_SERVER_IP, CAMU_PORT, al_str_c("ctv")); - - nn_thread_create(&c->thread, event_loop_thread, c); + if (!c->created) { + to_be_removed_inline_create_client(c, display); c->created = true; } } @@ -87,8 +96,9 @@ static void onSurfaceDestroyed(GLFMDisplay *display) static void onDraw(GLFMDisplay *display) { struct ctv *c = (struct ctv *)glfmGetUserData(display); - if (camu_screen_tick(&c->scr)) { - c->renderer->render(c->renderer, &c->scr); + bool force; + if (camu_screen_tick(&c->scr, &force)) { + c->renderer->render(c->renderer, &c->scr, force); } } diff --git a/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml b/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml index 00f96c1..cca763f 100644 --- a/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml +++ b/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-feature android:name="android.software.leanback" android:required="false" /> <uses-feature android:name="android.hardware.touchscreen" diff --git a/src/fruits/droid/ctv/gradle/libs.versions.toml b/src/fruits/droid/ctv/gradle/libs.versions.toml index c474f95..ea02696 100644 --- a/src/fruits/droid/ctv/gradle/libs.versions.toml +++ b/src/fruits/droid/ctv/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.7.2" +agp = "8.7.3" [libraries] diff --git a/src/liana/client.c b/src/liana/client.c index 1ba09cc..e9dd536 100644 --- a/src/liana/client.c +++ b/src/liana/client.c @@ -208,10 +208,10 @@ void lia_client_connect(struct lia_client *client, struct nn_event_loop *loop, u lia_vcr_init(&client->vcr, client->loop, &client->data); al_str_clone(&client->addr, addr); client->port = port; - if (!nn_packet_stream_init(&client->data, type, connection_callback, connection_closed_callback, client)) { + if (!nn_packet_stream_init(&client->data, type, CAMU_MULTIPLEX_LIANA, + connection_callback, connection_closed_callback, client)) { connection_closed_callback(client, &client->data); } - nn_packet_stream_set_multiplex(&client->data, CAMU_MULTIPLEX_LIANA); client->renderer = renderer; nn_packet_stream_connect(&client->data, client->loop, &client->addr, client->port); } diff --git a/src/libsink/common.h b/src/libsink/common.h index 0bb3ded..dc0b207 100644 --- a/src/libsink/common.h +++ b/src/libsink/common.h @@ -1,6 +1,7 @@ #pragma once #define CAMU_SINK_LOCAL +//#define CAMU_SINK_SCUFFED_LOOP enum { CAMU_SINK_SET = 0, diff --git a/src/libsink/sink.c b/src/libsink/sink.c index 9b5c05e..12b8bca 100644 --- a/src/libsink/sink.c +++ b/src/libsink/sink.c @@ -433,12 +433,12 @@ static void maybe_add_to_previous(struct camu_sink *sink, struct camu_sink_entry } } - // If neither the entries audio or video buffer is ADDED, we don't care about adding it + // If neither of the entries audio or video buffer is ADDED, we don't care about adding it // to previous (waiting for the next added entry to remove it). #ifndef CAMU_SINK_NO_VIDEO if (!(previous->audio.state == BUFFER_ADDED || previous->video.state == BUFFER_ADDED) || target->ended) { #else - if (!(previous->audio.state == BUFFER_ADDED) || target->ended) + if (!(previous->audio.state == BUFFER_ADDED) || target->ended) { #endif remove_entry_buffers(sink, previous); return; @@ -629,6 +629,15 @@ static void pause_and_swap_to(struct camu_sink *sink, struct camu_sink_entry *ta static bool end_entry_and_advance_queue(struct camu_sink *sink, struct camu_sink_entry *entry) { +#ifdef CAMU_SINK_SCUFFED_LOOP + al_log_info("sink", "Looping."); + queue_cmd(sink, (struct camu_sink_cmd){ + .op = SEEK, + .value.f = 0.0, + .opaque = entry + }); + return true; +#endif al_log_info("sink", "Entry ended."); entry->ended = true; queue_cmd(sink, (struct camu_sink_cmd){ diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c index 07ce379..dfaa190 100644 --- a/src/render/queue_libplacebo.c +++ b/src/render/queue_libplacebo.c @@ -9,6 +9,31 @@ #include "queue_libplacebo.h" +#ifdef CAMU_HAVE_FFMPEG +static bool queue_lp_configure_subtitiles(struct camu_frame_queue *queue, s32 width, s32 height, AVCodecParameters *codecpar) +{ + struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)queue; + if (!lq->ass) return false; + lq->ass_renderer = ass_renderer_init(lq->ass); + if (!lq->ass_renderer) { + al_log_error("frame_queue_libplacebo", "Failed to initialize ass renderer."); + return false; + } + lq->ass_track = ass_new_track(lq->ass); + if (!lq->ass_track) { + al_log_error("frame_queue_libplacebo", "Failed to create ass track."); + return false; + } + ass_set_frame_size(lq->ass_renderer, width, height); + ass_set_storage_size(lq->ass_renderer, width, height); + ass_set_fonts(lq->ass_renderer, NULL, NULL, ASS_FONTPROVIDER_AUTODETECT, NULL, 0); + ass_process_codec_private(lq->ass_track, (const char *)codecpar->extradata, + codecpar->extradata_size); + lq->have_subtitles = true; + return true; +} +#endif + static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src, struct pl_frame *out_frame) { @@ -264,29 +289,6 @@ static void queue_lp_push_av_frame(struct camu_frame_queue *queue, AVFrame *fram }); } -static bool queue_lp_configure_subtitiles(struct camu_frame_queue *queue, s32 width, s32 height, AVCodecParameters *codecpar) -{ - struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)queue; - if (!lq->ass) return false; - lq->ass_renderer = ass_renderer_init(lq->ass); - if (!lq->ass_renderer) { - al_log_error("frame_queue_libplacebo", "Failed to initialize ass renderer."); - return false; - } - lq->ass_track = ass_new_track(lq->ass); - if (!lq->ass_track) { - al_log_error("frame_queue_libplacebo", "Failed to create ass track."); - return false; - } - ass_set_frame_size(lq->ass_renderer, width, height); - ass_set_storage_size(lq->ass_renderer, width, height); - ass_set_fonts(lq->ass_renderer, NULL, NULL, ASS_FONTPROVIDER_AUTODETECT, NULL, 0); - ass_process_codec_private(lq->ass_track, (const char *)codecpar->extradata, - codecpar->extradata_size); - lq->have_subtitles = true; - return true; -} - static void queue_lp_push_subtitle(struct camu_frame_queue *queue, AVPacket *pkt) { struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)queue; @@ -350,10 +352,12 @@ struct camu_frame_queue *camu_frame_queue_lp_create(void) struct camu_frame_queue_lp *lq = al_alloc_object(struct camu_frame_queue_lp); al_array_init(lq->overlays); lq->have_subtitles = false; +#ifdef CAMU_HAVE_FFMPEG + lq->q.configure_subtitles = queue_lp_configure_subtitiles; +#endif lq->q.push = queue_lp_push; #ifdef CAMU_HAVE_FFMPEG lq->q.push_av_frame = queue_lp_push_av_frame; - lq->q.configure_subtitles = queue_lp_configure_subtitiles; lq->q.push_subtitle = queue_lp_push_subtitle; #endif lq->q.flush = queue_lp_flush; diff --git a/src/render/queue_tiger.c b/src/render/queue_tiger.c index bbc2b6e..d21236d 100644 --- a/src/render/queue_tiger.c +++ b/src/render/queue_tiger.c @@ -3,6 +3,8 @@ #include "queue_tiger.h" +#define GL_UNPACK_ROW_LENGTH 0x0CF2 + static void upload_texture(struct camu_frame_queue_tiger *tq, u8 *data, s32 width, s32 height, s32 format, s32 linesize) { glGenTextures(1, &tq->texture_id); diff --git a/src/render/renderer.h b/src/render/renderer.h index b304fdf..7afd8de 100644 --- a/src/render/renderer.h +++ b/src/render/renderer.h @@ -33,7 +33,7 @@ struct camu_renderer { struct camu_frame_queue *(*create_queue)(struct camu_renderer *); u32 (*get_latency)(struct camu_renderer *); void (*resize)(struct camu_renderer *, s32 *, s32 *); - void (*render)(struct camu_renderer *, struct camu_screen *); + void (*render)(struct camu_renderer *, struct camu_screen *, bool); #ifdef CAMU_HAVE_FFMPEG s32 (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, s32 flags); void *opaque; diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c index 9fedc5f..8359798 100644 --- a/src/render/renderer_libplacebo.c +++ b/src/render/renderer_libplacebo.c @@ -6,6 +6,7 @@ #endif #include "../screen/screen.h" +#include "../libsink/common.h" #include "../util/color_palette.h" #include "renderer_libplacebo.h" @@ -189,7 +190,7 @@ static u32 renderer_lp_get_latency(struct camu_renderer *renderer) return (u32)pl_swapchain_latency(lr->swapchain); } -static void renderer_lp_render(struct camu_renderer *renderer, struct camu_screen *scr) +static void renderer_lp_render(struct camu_renderer *renderer, struct camu_screen *scr, bool force) { struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer; @@ -243,6 +244,13 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree } pl_swapchain_submit_frame(lr->swapchain); + +#ifdef CAMU_SINK_SCUFFED_LOOP + if (scr->videos.size == 0 && !force) { + return; + } +#endif + pl_swapchain_swap_buffers(lr->swapchain); } diff --git a/src/render/renderer_tiger.c b/src/render/renderer_tiger.c index 74d9238..74db594 100644 --- a/src/render/renderer_tiger.c +++ b/src/render/renderer_tiger.c @@ -221,10 +221,11 @@ static mat4x4 model = { 0 }; static GLuint texture0 = 0; #endif -static void renderer_tiger_render(struct camu_renderer *renderer, struct camu_screen *scr) +static void renderer_tiger_render(struct camu_renderer *renderer, struct camu_screen *scr, bool force) { #ifdef CAMU_RENDERER_OPENGL struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; + (void)force; tr->make_current(tr->priv); diff --git a/src/screen/screen.c b/src/screen/screen.c index 17f4e3b..c323204 100644 --- a/src/screen/screen.c +++ b/src/screen/screen.c @@ -38,13 +38,15 @@ static void resize_callback(void *userdata, s32 width, s32 height) al_array_foreach_ptr(scr->videos, i, video) { camu_view_calculate(&video->view, scr->width, scr->height); } + scr->force_render = true; } static void refresh_callback(void *userdata) { struct camu_screen *scr = (struct camu_screen *)userdata; if (scr->renderer) { - scr->renderer->render(scr->renderer, scr); + // The thread-safety of this is questionable. + scr->renderer->render(scr->renderer, scr, true); } } @@ -512,12 +514,16 @@ bool camu_screen_poll(struct camu_screen *scr, bool block) #endif } -bool camu_screen_tick(struct camu_screen *scr) +bool camu_screen_tick(struct camu_screen *scr, bool *force) { s32 state = al_atomic_load(s32)(&scr->state, AL_ATOMIC_RELAXED); al_assert(state != CAMU_SCREEN_STOPPED); bool paused = state == CAMU_SCREEN_PAUSED; - return camu_screen_poll(scr, paused) || !paused; + bool render = camu_screen_poll(scr, paused) || !paused; + render |= scr->force_render; + *force = scr->force_render; + scr->force_render = false; + return render; } void camu_screen_wake(struct camu_screen *scr) diff --git a/src/screen/screen.h b/src/screen/screen.h index 80f888c..d567521 100644 --- a/src/screen/screen.h +++ b/src/screen/screen.h @@ -56,6 +56,7 @@ struct camu_screen { struct nn_thread thread; #endif struct camu_renderer *renderer; + bool force_render; s32 width; s32 height; u64 last_click_ts; @@ -83,6 +84,6 @@ void camu_screen_clear(struct camu_screen *scr); #endif void camu_screen_set_state(struct camu_screen *scr, s32 state); bool camu_screen_poll(struct camu_screen *scr, bool block); -bool camu_screen_tick(struct camu_screen *scr); +bool camu_screen_tick(struct camu_screen *scr, bool *force); void camu_screen_wake(struct camu_screen *scr); void camu_screen_close(struct camu_screen *scr); diff --git a/src/sink/desktop.c b/src/sink/desktop.c index 4a1b9ca..5529a3b 100644 --- a/src/sink/desktop.c +++ b/src/sink/desktop.c @@ -86,7 +86,7 @@ bool camu_desktop_init(struct camu_desktop *c, const char *name) if (!camu_screen_create_renderer(&c->scr, c->renderer)) { return false; } - c->renderer->render(c->renderer, &c->scr); + c->renderer->render(c->renderer, &c->scr, true); if (!camu_mixer_init(&c->mixer, camu_audio_miniaudio_create())) { //if (!camu_mixer_init(&c->mixer, (struct camu_audio *)&audio_plugin_null)) { return false; @@ -113,8 +113,9 @@ bool camu_desktop_connect(struct camu_desktop *c, u8 type, struct nn_event_loop bool camu_desktop_tick(struct camu_desktop *c) { - if (!c->should_quit && camu_screen_tick(&c->scr)) { - c->renderer->render(c->renderer, &c->scr); + bool force; + if (!c->should_quit && camu_screen_tick(&c->scr, &force)) { + c->renderer->render(c->renderer, &c->scr, force); } return !c->should_quit; } |