summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/queue_libplacebo.c2
-rw-r--r--src/render/renderer.h7
-rw-r--r--src/render/renderer_libplacebo.c84
-rw-r--r--src/render/renderer_libplacebo.h3
4 files changed, 72 insertions, 24 deletions
diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c
index dfaa190..861dd5e 100644
--- a/src/render/queue_libplacebo.c
+++ b/src/render/queue_libplacebo.c
@@ -270,7 +270,7 @@ static void discard_av_frame(const struct pl_source_frame *src)
{
AVFrame *frame = src->frame_data;
av_frame_free(&frame);
- al_log_debug("frame_queue_libplacebo", "Dropped frame with PTS %.3f.", src->pts);
+ al_log_warn("frame_queue_libplacebo", "Dropped frame with PTS %.3f.", src->pts);
}
static void queue_lp_push_av_frame(struct camu_frame_queue *queue, AVFrame *frame, f64 pts)
diff --git a/src/render/renderer.h b/src/render/renderer.h
index 7afd8de..a9780e5 100644
--- a/src/render/renderer.h
+++ b/src/render/renderer.h
@@ -8,6 +8,9 @@
#if defined STELA_API_OPENGL
#define CAMU_RENDERER_OPENGL
+#ifdef STELA_USE_EGL
+#include <stl/egl.h>
+#endif
#elif defined STELA_API_VULKAN
#define CAMU_RENDERER_VULKAN
#endif
@@ -22,6 +25,10 @@ struct camu_renderer {
VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *),
const char *const *(*vk_get_extensions)(u32 *),
#elif defined CAMU_RENDERER_OPENGL
+#ifdef STELA_USE_EGL
+ EGLDisplay display,
+ EGLContext context,
+#endif
void (*get_gl_proc_address(char const *procname))(void),
bool (*gl_load_loader)(void *),
bool (*gl_make_current)(void *),
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index c528da5..ad7e7fc 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -6,7 +6,6 @@
#endif
#include "../screen/screen.h"
-#include "../libsink/common.h"
#include "../util/color_palette.h"
#include "renderer_libplacebo.h"
@@ -17,14 +16,20 @@ static f32 clear_color[4] = { 0.0f, 0.0f, 0.0f, 1.f };
static void renderer_lp_resize(struct camu_renderer *renderer, s32 *width, s32 *height)
{
struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer;
- if (lr->swapchain) pl_swapchain_resize(lr->swapchain, width, height);
+ if (lr->swapchain) {
+ if (lr->have_frame) {
+ pl_swapchain_submit_frame(lr->swapchain);
+ lr->have_frame = false;
+ }
+ pl_swapchain_resize(lr->swapchain, width, height);
+ }
}
static void log_callback(void *userdata, enum pl_log_level level, const char *message)
{
(void)userdata;
(void)level;
- al_log_debug("render_libplacebo", message);
+ al_log_info("render_libplacebo", message);
}
static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *width, s32 *height,
@@ -33,6 +38,10 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *wid
VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *),
const char *const *(*vk_get_extensions)(u32 *),
#elif defined CAMU_RENDERER_OPENGL
+#ifdef STELA_USE_EGL
+ EGLDisplay display,
+ EGLContext context,
+#endif
void (*get_gl_proc_address(char const *procname))(void),
bool (*gl_load_loader)(void *),
bool (*gl_make_current)(void *),
@@ -105,6 +114,10 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *wid
.release_current = gl_release_current,
.get_proc_addr = get_gl_proc_address,
.get_proc_addr_ex = NULL,
+#ifdef STELA_USE_EGL
+ .egl_display = display,
+ .egl_context = context,
+#endif
.priv = priv,
));
if (!lr->gl) {
@@ -127,6 +140,8 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *wid
lr->renderer = pl_renderer_create(lr->logger, lr->gpu);
+ lr->have_frame = false;
+
pl_swapchain_resize(lr->swapchain, width, height);
al_memset(&lr->params, 0, sizeof(struct pl_render_params));
@@ -136,8 +151,6 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *wid
//lr->params = pl_render_high_quality_params;
lr->params.deband_params = NULL;
- // Don't let the cache treat different images of the same size as the same frame.
- lr->params.skip_caching_single_frame = true;
// Clear manually so we can draw multiple images per frame.
lr->params.border = PL_CLEAR_SKIP;
// Prioritize a more consistent image.
@@ -164,6 +177,8 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *wid
lr->ass = ass_library_init();
+ lr->last_render_tick = nn_get_tick();
+
return true;
err:
lr->r.free((struct camu_renderer **)&lr);
@@ -200,33 +215,44 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
}
#endif
- struct pl_swapchain_frame frame;
- struct pl_frame target;
+ if (!lr->have_frame) {
+ struct pl_swapchain_frame frame;
+ pl_swapchain_start_frame(lr->swapchain, &frame);
+ pl_frame_from_swapchain(&lr->target, &frame);
+ pl_frame_clear_rgba(lr->gpu, &lr->target, clear_color);
+ lr->have_frame = true;
+ }
+
+ struct pl_frame *target = &lr->target;
struct pl_frame_mix mix;
- pl_swapchain_start_frame(lr->swapchain, &frame);
- pl_frame_from_swapchain(&target, &frame);
- pl_frame_clear_rgba(lr->gpu, &target, clear_color);
+ bool do_gpu_finish = false;
struct camu_screen_video *video;
while (scr->videos.size > 0) {
bool any_eof = false;
al_array_foreach_ptr(scr->videos, i, video) {
- if (camu_video_buffer_read(video->buf, &mix)) {
- // QUEUE_MORE doesn't return a frame obviously but don't treat it like an EOF.
+ bool weighted;
+ if (camu_video_buffer_read(video->buf, &mix, &weighted)) {
+ // If mix.frames is NULL, read() returned QUEUE_MORE.
if (mix.frames) {
- target.crop = mix.frames[0]->crop;
- target.crop.x1 *= video->view.zoom / video->view.stretch;
- target.crop.y1 *= video->view.zoom * video->view.stretch;
- target.crop.x0 += video->view.x_offset;
- target.crop.y0 += video->view.y_offset;
- target.crop.x1 += video->view.x_offset;
- target.crop.y1 += video->view.y_offset;
- target.rotation = video->view.rotation;
+ // weighted is only set when read() returns QUEUE_OK.
+ do_gpu_finish |= weighted;
+ // Terrible hack. Let's us distinguish single frames with the same dimensions.
+ // Tied to a libplacebo patch to consider info_priv in the hash.
+ lr->params.info_priv = video->buf;
+ target->crop = mix.frames[0]->crop;
+ target->crop.x1 *= video->view.zoom / video->view.stretch;
+ target->crop.y1 *= video->view.zoom * video->view.stretch;
+ target->crop.x0 += video->view.x_offset;
+ target->crop.y0 += video->view.y_offset;
+ target->crop.x1 += video->view.x_offset;
+ target->crop.y1 += video->view.y_offset;
+ target->rotation = video->view.rotation;
//lr->params.color_adjustment = pl_color_adjustment(
// .saturation = 0.0
//);
- pl_render_image_mix(lr->renderer, &mix, &target, &lr->params);
+ pl_render_image_mix(lr->renderer, &mix, target, &lr->params);
}
} else {
any_eof = true;
@@ -243,13 +269,25 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
}
}
- pl_swapchain_submit_frame(lr->swapchain);
-
if (scr->videos.size == 0 && !force) {
return;
}
+ pl_swapchain_submit_frame(lr->swapchain);
pl_swapchain_swap_buffers(lr->swapchain);
+ lr->have_frame = false;
+
+ if (do_gpu_finish) {
+ // Block until render completes.
+ pl_gpu_finish(lr->gpu);
+ }
+
+ f64 tick = nn_get_tick();
+ f64 frame_time = tick - lr->last_render_tick;
+ if (frame_time > 0.020) {
+ al_log_info("render_libplacebo", "FRAME_TIME: %fs", frame_time);
+ }
+ lr->last_render_tick = tick;
}
void renderer_lp_free(struct camu_renderer **renderer)
diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h
index eff7a34..38407bb 100644
--- a/src/render/renderer_libplacebo.h
+++ b/src/render/renderer_libplacebo.h
@@ -26,7 +26,10 @@ struct camu_renderer_lp {
pl_gpu gpu;
pl_log logger;
pl_swapchain swapchain;
+ struct pl_frame target;
+ bool have_frame;
pl_renderer renderer;
+ f64 last_render_tick;
struct pl_render_params params;
ASS_Library *ass;
};