diff options
| author | 2025-05-25 18:49:20 -0400 | |
|---|---|---|
| committer | 2025-05-25 18:49:20 -0400 | |
| commit | 2fa7ea95c891981684a55b41977172d040c2cc55 (patch) | |
| tree | d349e810b3178045a420b625f6dbe5634b64807b /src/render | |
| parent | 01f852081b1291da7fc342976bf5228ffb618736 (diff) | |
| download | camu-2fa7ea95c891981684a55b41977172d040c2cc55.tar.gz camu-2fa7ea95c891981684a55b41977172d040c2cc55.tar.bz2 camu-2fa7ea95c891981684a55b41977172d040c2cc55.zip | |
Support Windows XP (Old FFmpeg and build fixes)
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/meson.build | 53 | ||||
| -rw-r--r-- | src/render/momo/meson.build | 12 | ||||
| -rw-r--r-- | src/render/momo/momo.c | 35 | ||||
| -rw-r--r-- | src/render/momo/momo.h | 25 | ||||
| -rw-r--r-- | src/render/queue_libplacebo.c | 1 | ||||
| -rw-r--r-- | src/render/queue_momo.c | 68 | ||||
| -rw-r--r-- | src/render/queue_momo.h | 9 | ||||
| -rw-r--r-- | src/render/queue_tiger.c | 130 | ||||
| -rw-r--r-- | src/render/queue_tiger.h | 18 | ||||
| -rw-r--r-- | src/render/renderer.h | 20 | ||||
| -rw-r--r-- | src/render/renderer_libplacebo.c | 73 | ||||
| -rw-r--r-- | src/render/renderer_libplacebo.h | 12 | ||||
| -rw-r--r-- | src/render/renderer_momo.c | 97 | ||||
| -rw-r--r-- | src/render/renderer_momo.h | 19 | ||||
| -rw-r--r-- | src/render/renderer_tiger.c | 320 | ||||
| -rw-r--r-- | src/render/renderer_tiger.h | 31 |
16 files changed, 378 insertions, 545 deletions
diff --git a/src/render/meson.build b/src/render/meson.build index 98b86ec..7e3e394 100644 --- a/src/render/meson.build +++ b/src/render/meson.build @@ -2,23 +2,20 @@ render_src = [] render_deps = [] render_args = [] -if get_option('renderer') == 'tiger' - render_src += ['renderer_tiger.c', 'queue_tiger.c'] - linmath_h = subproject('linmath.h').get_variable('linmath_h') - render_deps += [linmath_h] - libm = compiler.find_library('m', required: false) - if libm.found() - render_deps += [libm] - endif - render_args += ['-DCAMU_RENDERER_TIGER'] +if get_option('renderer') == 'momo' + render_src += ['renderer_momo.c', 'queue_momo.c'] + subdir('momo') + render_deps += [momo] + render_args += ['-DCAMU_RENDERER_MOMO'] elif get_option('renderer') == 'libplacebo' libplacebo_opts = ['warning_level=2', 'demos=false', 'tests=false', 'bench=false', 'fuzz=false', 'glslang=disabled', 'gl-proc-addr=disabled', 'vk-proc-addr=disabled', - 'lcms=disabled', - 'dovi=disabled', - 'libdovi=disabled' + 'lcms=auto', + 'dovi=auto', + 'libdovi=auto', + 'xxhash=auto' ] if get_option('renderer-api') == 'vulkan' or get_option('renderer-api') == 'dx11' @@ -27,12 +24,19 @@ elif get_option('renderer') == 'libplacebo' render_deps += [shaderc] else shaderc_opts = cmake.subproject_options() + shaderc_opts.set_override_option('warning_level', '0') # Doesn't work. reltype = is_minsize ? 'MinSizeRel' : 'Release' shaderc_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_INSTALL': true }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_TESTS': true }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_EXAMPLES': true }) shaderc_opts.add_cmake_defines({ 'SHADERC_SKIP_COPYRIGHT_CHECK': true }) + shaderc_opts.add_cmake_defines({ 'ENABLE_GLSLANG_BINARIES': false }) + shaderc_opts.add_cmake_defines({ 'ENABLE_SPVREMAPPER': false }) + shaderc_opts.add_cmake_defines({ 'ENABLE_HLSL': false }) + spirv_optimizer = true + shaderc_opts.add_cmake_defines({ 'ENABLE_OPT': spirv_optimizer }) + shaderc_opts.add_cmake_defines({ 'ENABLE_EXCEPTIONS_ON_MSVC': false }) shaderc_proj = cmake.subproject('shaderc', options: shaderc_opts) shaderc = shaderc_proj.dependency('shaderc') meson.override_dependency('shaderc', shaderc) @@ -43,20 +47,31 @@ elif get_option('renderer') == 'libplacebo' shaderc_proj.dependency('OSDependent'), shaderc_proj.dependency('GenericCodeGen'), shaderc_proj.dependency('SPIRV'), - shaderc_proj.dependency('SPIRV-Tools-opt'), shaderc_proj.dependency('SPIRV-Tools-static') ] + if spirv_optimizer + render_deps += [ + shaderc_proj.dependency('SPIRV-Tools-opt'), + ] + endif endif #glslang = dependency('glslang', required: false, allow_fallback: false) #if glslang.found() # render_deps += [glslang] #else + # #spirv_tools_opts = cmake.subproject_options() + # #spirv_tools_opts.set_override_option('warning_level', '0') + # #reltype = is_minsize ? 'MinSizeRel' : 'Release' + # #spirv_tools_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) + # #spirv_tools_proj = cmake.subproject('SPIRV-Tools', options: spirv_tools_opts) # glslang_opts = cmake.subproject_options() + # glslang_opts.set_override_option('warning_level', '0') # reltype = is_minsize ? 'MinSizeRel' : 'Release' # glslang_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) + # #glslang_opts.add_cmake_defines({ 'ALLOW_EXTERNAL_SPIRV_TOOLS': true }) # glslang_opts.add_cmake_defines({ 'ENABLE_OPT': '0' }) # glslang_proj = cmake.subproject('glslang', options: glslang_opts) - # message('CMake targets:\n - ' + '\n - '.join(glslang_proj.target_list())) + # #message('CMake targets:\n - ' + '\n - '.join(glslang_proj.target_list())) # glslang = glslang_proj.dependency('glslang') # spirv = glslang_proj.dependency('SPIRV') # glslang_default_resource_limits = glslang_proj.dependency('glslang-default-resource-limits') @@ -118,22 +133,27 @@ if get_option('subtitles').enabled() default_options: [ 'doc=disabled', 'nls=disabled', - 'tests=disabled', 'tools=disabled', 'cache-build=disabled' ]) + else + libass_opts += ['directwrite=enabled'] endif # libass(e46aede):meson.build:84 # fontconfig(72b9a48):meson.build:28 freetype = dependency('freetype2', version: '>=9.17.3', default_options: [ - 'harfbuzz=disabled' + 'warning_level=0', + 'harfbuzz=disabled', + 'png=disabled' ]) # libass(e46aede):meson.build:90 fribidi = dependency('fribidi', version: '>=0.19.1', default_options: [ + 'warning_level=0', + 'c_args=-Wno-stringop-overflow', # This doesn't work. 'docs=false', 'tests=false', 'bin=false' @@ -143,7 +163,6 @@ if get_option('subtitles').enabled() version: '>=2.0.0', default_options: [ 'freetype=disabled', - 'tests=disabled', 'introspection=disabled', 'docs=disabled', 'utilities=disabled', diff --git a/src/render/momo/meson.build b/src/render/momo/meson.build new file mode 100644 index 0000000..092293a --- /dev/null +++ b/src/render/momo/meson.build @@ -0,0 +1,12 @@ +momo_src = ['momo.c'] +momo_deps = [] +momo_args = [] + +libm = compiler.find_library('m', required: false) +if libm.found() + momo_deps += [libm] +endif +linmath_h = subproject('linmath.h').get_variable('linmath_h') +momo_deps += [linmath_h] + +momo = declare_dependency(sources: momo_src, dependencies: momo_deps, compile_args: momo_args) diff --git a/src/render/momo/momo.c b/src/render/momo/momo.c new file mode 100644 index 0000000..5239efd --- /dev/null +++ b/src/render/momo/momo.c @@ -0,0 +1,35 @@ +#define AL_LOG_SECTION "momo" +#include <al/log.h> + +#include "momo.h" + +bool MOMO_Init(MOMO_Renderer *mmr, +#ifdef STELA_API_OPENGL + bool (*MakeCurrent)(void *), + void (*ReleaseCurrent)(void *), + void (*SwapBuffers)(void *), +#endif + void *Private) +{ + mmr->Private = Private; +#ifdef STELA_API_OPENGL + mmr->GL.MakeCurrent = MakeCurrent; + mmr->GL.ReleaseCurrent = ReleaseCurrent; + mmr->GL.SwapBuffers = SwapBuffers; + mmr->GL.MakeCurrent(mmr->Private); + const char *gl_version = (const char *)glGetString(GL_VERSION); + if (gl_version) { + log_info("GL context version: %s.", gl_version); + } else { + log_warn("Somehow failed to retrive GL_VERSION."); + } +#endif + return true; +} + +void MOMO_Render(MOMO_Renderer *mmr) +{ +#ifdef STELA_API_OPENGL + mmr->GL.SwapBuffers(mmr->Private); +#endif +} diff --git a/src/render/momo/momo.h b/src/render/momo/momo.h new file mode 100644 index 0000000..76686ba --- /dev/null +++ b/src/render/momo/momo.h @@ -0,0 +1,25 @@ +#pragma once + +#include <al/types.h> + +#ifdef STELA_API_OPENGL +#include <stl/gl.h> +#endif + +typedef struct { + struct { + bool (*MakeCurrent)(void *); + void (*ReleaseCurrent)(void *); + void (*SwapBuffers)(void *); + } GL; + void *Private; +} MOMO_Renderer; + +bool MOMO_Init(MOMO_Renderer *mmr, +#ifdef STELA_API_OPENGL + bool (*MakeCurrent)(void *), + void (*ReleaseCurrent)(void *), + void (*SwapBuffers)(void *), +#endif + void *Private); +void MOMO_Render(MOMO_Renderer *mmr); diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c index 7fe9258..5932944 100644 --- a/src/render/queue_libplacebo.c +++ b/src/render/queue_libplacebo.c @@ -30,6 +30,7 @@ static bool queue_lp_configure_subtitles(struct camu_frame_queue *queue, u32 wid 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_set_hinting(lq->ass_renderer, ASS_HINTING_NONE); AVCodecParameters *codecpar = stream->av.stream->codecpar; ass_process_codec_private(lq->ass_track, (const char *)codecpar->extradata, codecpar->extradata_size); diff --git a/src/render/queue_momo.c b/src/render/queue_momo.c new file mode 100644 index 0000000..8e8d7e3 --- /dev/null +++ b/src/render/queue_momo.c @@ -0,0 +1,68 @@ +#include "queue_momo.h" + +static void queue_momo_push(struct camu_frame_queue *queue, struct camu_codec_frame *frame, f64 pts) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + (void)pts; + camu_codec_frame_discard(frame); +} + +#ifdef CAMU_HAVE_FFMPEG +static void queue_momo_push_av_frame(struct camu_frame_queue *queue, AVFrame *frame, f64 pts) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + (void)pts; + av_frame_free(&frame); +} +#endif + +static void queue_momo_flush(struct camu_frame_queue *queue) +{ + (void)queue; +} + +static s32 queue_momo_count(struct camu_frame_queue *queue) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + return 1; +} + +static u8 queue_momo_read(struct camu_frame_queue *queue, f64 pts, void *out) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)queue; + (void)mq; + (void)pts; + (void)out; + return CAMU_QUEUE_OK; +} + +static void queue_momo_reset(struct camu_frame_queue *queue) +{ + struct camu_frame_queue_momo *tq = (struct camu_frame_queue_momo *)queue; + (void)tq; +} + +static void queue_momo_free(struct camu_frame_queue **queue) +{ + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)*queue; + al_free(mq); + *queue = NULL; +} + +struct camu_frame_queue *camu_frame_queue_momo_create(void) +{ + struct camu_frame_queue_momo *mq = al_alloc_object(struct camu_frame_queue_momo); + mq->q.push = queue_momo_push; +#ifdef CAMU_HAVE_FFMPEG + mq->q.push_av_frame = queue_momo_push_av_frame; +#endif + mq->q.flush = queue_momo_flush; + mq->q.count = queue_momo_count; + mq->q.read = queue_momo_read; + mq->q.reset = queue_momo_reset; + mq->q.free = queue_momo_free; + return (struct camu_frame_queue *)mq; +} diff --git a/src/render/queue_momo.h b/src/render/queue_momo.h new file mode 100644 index 0000000..c4bf5d1 --- /dev/null +++ b/src/render/queue_momo.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../buffer/frame_queue.h" + +struct camu_frame_queue_momo { + struct camu_frame_queue q; +}; + +struct camu_frame_queue *camu_frame_queue_momo_create(void); diff --git a/src/render/queue_tiger.c b/src/render/queue_tiger.c deleted file mode 100644 index df072d2..0000000 --- a/src/render/queue_tiger.c +++ /dev/null @@ -1,130 +0,0 @@ -#include <al/lib.h> -#include <stl/gl.h> - -#include "queue_tiger.h" - -#define GL_UNPACK_ROW_LENGTH 0x0CF2 - -static void upload_texture(struct camu_frame_queue_tiger *tq, u8 *data, u32 width, u32 height, s32 format, s32 linesize) -{ - glGenTextures(1, &tq->texture_id); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tq->texture_id); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //if (frame->flags & CAMU_FRAME_DEVICE_ALLOCATED) { - // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, tq->tr->texture_buffer); - //} - glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize); - glPixelStorei(GL_UNPACK_ALIGNMENT, 0); - switch (format) { - case CAMU_PIXEL_FORMAT_RGBA: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - break; - case CAMU_PIXEL_FORMAT_RGB: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, - 0, GL_RGB, GL_UNSIGNED_BYTE, data); - break; - default: - al_assert(false); - } - //glGenerateMipmap(GL_TEXTURE_2D); -} - -static void queue_tiger_push(struct camu_frame_queue *queue, struct camu_codec_frame *frame, f64 pts) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)pts; - tq->queued_frame = frame; -} - -#ifdef CAMU_HAVE_FFMPEG -static void queue_tiger_push_av_frame(struct camu_frame_queue *queue, AVFrame *frame, f64 pts) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)pts; - tq->queued_av_frame = frame; -} -#endif - -static void queue_tiger_flush(struct camu_frame_queue *queue) -{ - (void)queue; -} - -static s32 queue_tiger_count(struct camu_frame_queue *queue) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)tq; - return 1; -} - -static u8 queue_tiger_read(struct camu_frame_queue *queue, f64 pts, void *out) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)pts; - if (tq->queued_frame) { - struct camu_codec_frame *frame = tq->queued_frame; - s32 linesize = frame->video.width; - upload_texture(tq, frame->data, frame->video.width, frame->video.height, frame->format, linesize); - camu_codec_frame_discard(frame); - tq->queued_frame = NULL; - tq->uploaded = true; - } -#ifdef CAMU_HAVE_FFMPEG - if (tq->queued_av_frame) { - AVFrame *frame = tq->queued_av_frame; - s32 linesize = frame->linesize[0]; - switch (frame->format) { - case CAMU_PIXEL_FORMAT_RGBA: - linesize /= 4; - break; - case CAMU_PIXEL_FORMAT_RGB: - linesize /= 3; - break; - } - upload_texture(tq, frame->data[0], frame->width, frame->height, frame->format, linesize); - av_frame_free(&frame); - tq->queued_av_frame = NULL; - tq->uploaded = true; - } -#endif - if (!tq->uploaded) return CAMU_QUEUE_MORE; - *((GLuint *)out) = tq->texture_id; - return CAMU_QUEUE_OK; -} - -static void queue_tiger_reset(struct camu_frame_queue *queue) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)queue; - (void)tq; -} - -static void queue_tiger_free(struct camu_frame_queue **queue) -{ - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)*queue; - glDeleteTextures(1, &tq->texture_id); - al_free(tq); - *queue = NULL; -} - -struct camu_frame_queue *camu_frame_queue_tiger_create(void) -{ - struct camu_frame_queue_tiger *tq = al_alloc_object(struct camu_frame_queue_tiger); - tq->queued_frame = NULL; - tq->queued_av_frame = NULL; - tq->uploaded = false; - tq->q.push = queue_tiger_push; -#ifdef CAMU_HAVE_FFMPEG - tq->q.push_av_frame = queue_tiger_push_av_frame; -#endif - tq->q.flush = queue_tiger_flush; - tq->q.count = queue_tiger_count; - tq->q.read = queue_tiger_read; - tq->q.reset = queue_tiger_reset; - tq->q.free = queue_tiger_free; - return (struct camu_frame_queue *)tq; -} diff --git a/src/render/queue_tiger.h b/src/render/queue_tiger.h deleted file mode 100644 index af0e229..0000000 --- a/src/render/queue_tiger.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include <stl/gl.h> - -#include "../buffer/frame_queue.h" - -struct camu_frame_queue_tiger { - struct camu_frame_queue q; - GLuint texture_id; - struct camu_renderer_tiger *tr; - struct camu_codec_frame *queued_frame; -#ifdef CAMU_HAVE_FFMPEG - struct AVFrame *queued_av_frame; -#endif - bool uploaded; -}; - -struct camu_frame_queue *camu_frame_queue_tiger_create(void); diff --git a/src/render/renderer.h b/src/render/renderer.h index 1e6ffc0..d2590b1 100644 --- a/src/render/renderer.h +++ b/src/render/renderer.h @@ -7,14 +7,9 @@ #endif #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 -#elif defined STELA_API_DX11 -#define CAMU_RENDERER_DX11 #endif #include "../codec/codec.h" @@ -24,28 +19,32 @@ enum { CAMU_SCALING_NEAREST }; +enum { + CAMU_BACKGROUND_DEFAULT = 0, + CAMU_BACKGROUND_TRANSPARENT +}; + struct camu_frame_queue; struct camu_screen; struct camu_renderer { bool (*create_renderer)( struct camu_renderer *, u32 *, u32 *, -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *), const char *const *(*vk_get_extensions)(u32 *), -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 HWND win32_window, -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL #ifdef STELA_USE_EGL EGLDisplay display, EGLContext context, #endif - void (*get_gl_proc_address(char const *procname))(void), + void (*get_gl_proc_address(char const *))(void), bool (*gl_load_loader)(void *), bool (*gl_make_current)(void *), void (*gl_release_current)(void *), void (*gl_swap_buffers)(void *), -#elif defined CAMU_RENDERER_DX11 #endif void *priv); struct camu_frame_queue *(*create_queue)(struct camu_renderer *); @@ -54,6 +53,7 @@ struct camu_renderer { void (*resize)(struct camu_renderer *, u32 *, u32 *); void (*set_fullscreen)(struct camu_renderer *, bool); void (*set_scaling)(struct camu_renderer *, u8); + void (*set_background)(struct camu_renderer *, u8); void (*render)(struct camu_renderer *, struct camu_screen *, bool); #ifdef CAMU_HAVE_FFMPEG s32 (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, s32 flags); diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c index a2105d6..bfe8c47 100644 --- a/src/render/renderer_libplacebo.c +++ b/src/render/renderer_libplacebo.c @@ -9,7 +9,7 @@ #include "../screen/screen.h" #include "../util/color_palette.h" -#ifdef CAMU_RENDERER_DX11 +#ifdef STELA_API_DX11 #include <nnwt/windows.h> #define COBJMACROS #include <libplacebo/d3d11.h> @@ -42,7 +42,7 @@ static void renderer_lp_resize(struct camu_renderer *renderer, u32 *width, u32 * } } -#ifdef CAMU_RENDERER_DX11 +#ifdef STELA_API_DX11 static void renderer_lp_set_fullscreen(struct camu_renderer *renderer, bool fullscreen) { struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer; @@ -69,6 +69,21 @@ static void renderer_lp_set_scaling(struct camu_renderer *renderer, u8 mode) } } +static void renderer_lp_set_background(struct camu_renderer *renderer, u8 mode) +{ + struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer; + switch (mode) { + case CAMU_BACKGROUND_DEFAULT: + clear_color[3] = 1.f; + lr->params.background = PL_CLEAR_TILES; + break; + case CAMU_BACKGROUND_TRANSPARENT: + clear_color[3] = 0.f; + lr->params.background = PL_CLEAR_SKIP; + break; + } +} + static void log_callback(void *userdata, enum pl_log_level level, const char *message) { (void)userdata; @@ -79,19 +94,34 @@ static void log_callback(void *userdata, enum pl_log_level level, const char *me } } +#ifdef CAMU_HAVE_SUBTITLES +// level = 0(FATAL)-7(VERBOSE). +static void ass_log_callback(s32 level, const char *fmt, va_list args, void *userdata) +{ + (void)userdata; + if (level <= 1) { + al_logv(AL_LOG_ERROR, "ass", fmt, args); + } else { +#ifdef AL_DEBUG + al_logv(AL_LOG_DEBUG, "ass", fmt, args); +#endif + } +} +#endif + static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *width, u32 *height, -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *), const char *const *(*vk_get_extensions)(u32 *), -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 HWND win32_window, -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL #ifdef STELA_USE_EGL EGLDisplay display, EGLContext context, #endif - void (*get_gl_proc_address(char const *procname))(void), + void (*get_gl_proc_address(char const *))(void), bool (*gl_load_loader)(void *), bool (*gl_make_current)(void *), void (*gl_release_current)(void *), @@ -111,13 +141,18 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid clear_color[2] = 255.f; */ +//#define LIBPLACEBO_LOG_TRACE lr->logger = pl_log_create(PL_API_VER, pl_log_params( .log_cb = log_callback, .log_priv = NULL, +#ifdef LIBPLACEBO_LOG_TRACE + .log_level = PL_LOG_TRACE +#else .log_level = PL_LOG_INFO +#endif )); -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VkResult err; u32 num; @@ -153,6 +188,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid lr->swapchain = pl_vulkan_create_swapchain(lr->vk, pl_vulkan_swapchain_params( .surface = lr->surface, .present_mode = VK_PRESENT_MODE_FIFO_KHR + //.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR )); if (!lr->swapchain) { log_error("Failed to create vulkan swapchain."); @@ -162,7 +198,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid lr->gpu = lr->vk->gpu; log_info("Using Vulkan."); -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 (void)priv; lr->d3d11 = pl_d3d11_create(lr->logger, pl_d3d11_params( .debug = false @@ -183,7 +219,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid lr->gpu = lr->d3d11->gpu; log_info("Using DirectX 11."); -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL (void)gl_load_loader; lr->gl = pl_opengl_create(lr->logger, pl_opengl_params( .debug = false, @@ -230,8 +266,17 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid // Clear manually so we can draw multiple images per frame. lr->params.border = PL_CLEAR_SKIP; + lr->params.background = PL_CLEAR_TILES; + /* + lr->params.background_color[0] = clear_color[0]; + lr->params.background_color[1] = clear_color[1]; + lr->params.background_color[2] = clear_color[2]; + lr->params.background_transparency = clear_color[3]; + */ + // Prioritize a more consistent image. lr->params.correct_subpixel_offsets = true; + //lr->params.distort_params = pl_distort_params(.unscaled = false); #if 0 struct nn_file file; @@ -254,6 +299,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid #ifdef CAMU_HAVE_SUBTITLES lr->ass = ass_library_init(); + ass_set_message_cb(lr->ass, ass_log_callback, lr); #endif lr->last_render_tick = nn_get_tick(); @@ -339,7 +385,7 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree if (mix.frames) { // 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. + // Terrible hack. Lets us distinguish single frames with the same dimensions. // Tied to a libplacebo patch to consider info_priv in the hash. // Also, add in reset_pts to account for buffer resets. This is a completely // broken "hash" of the f64 pts value but hopefully it works for now. @@ -413,8 +459,8 @@ void renderer_lp_free(struct camu_renderer **renderer) struct camu_renderer_lp *lr = (struct camu_renderer_lp *)*renderer; if (lr->renderer) pl_renderer_destroy(&lr->renderer); if (lr->swapchain) pl_swapchain_destroy(&lr->swapchain); -#if defined CAMU_RENDERER_VULKAN -#elif defined CAMU_RENDERER_OPENGL +#if defined STELA_API_VULKAN +#elif defined STELA_API_OPENGL if (lr->gl) pl_opengl_destroy(&lr->gl); #endif if (lr->logger) pl_log_destroy(&lr->logger); @@ -433,12 +479,13 @@ struct camu_renderer *camu_renderer_lp_create(void) lr->r.add_font = renderer_lp_add_font; lr->r.get_latency = renderer_lp_get_latency; lr->r.resize = renderer_lp_resize; -#ifdef CAMU_RENDERER_DX11 +#ifdef STELA_API_DX11 lr->r.set_fullscreen = renderer_lp_set_fullscreen; #else lr->r.set_fullscreen = NULL; #endif lr->r.set_scaling = renderer_lp_set_scaling; + lr->r.set_background = renderer_lp_set_background; lr->r.render = renderer_lp_render; lr->r.free = renderer_lp_free; return (struct camu_renderer *)lr; diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h index 7b1cfa2..a0125ba 100644 --- a/src/render/renderer_libplacebo.h +++ b/src/render/renderer_libplacebo.h @@ -10,23 +10,23 @@ #include "renderer.h" -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN #include <libplacebo/vulkan.h> -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 #include <libplacebo/d3d11.h> -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL #include <libplacebo/opengl.h> #endif struct camu_renderer_lp { struct camu_renderer r; -#if defined CAMU_RENDERER_VULKAN +#if defined STELA_API_VULKAN VkSurfaceKHR surface; pl_vulkan vk; pl_vk_inst vk_inst; -#elif defined CAMU_RENDERER_DX11 +#elif defined STELA_API_DX11 pl_d3d11 d3d11; -#elif defined CAMU_RENDERER_OPENGL +#elif defined STELA_API_OPENGL pl_opengl gl; #endif pl_gpu gpu; diff --git a/src/render/renderer_momo.c b/src/render/renderer_momo.c new file mode 100644 index 0000000..9f217bf --- /dev/null +++ b/src/render/renderer_momo.c @@ -0,0 +1,97 @@ +#define AL_LOG_SECTION "renderer_momo" +#include <al/log.h> + +#include "renderer_momo.h" +#include "queue_momo.h" + +static void renderer_momo_resize(struct camu_renderer *renderer, u32 *width, u32 *height) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + (void)mr; + (void)width; + (void)height; +} + +static bool renderer_momo_create_renderer(struct camu_renderer *renderer, u32 *width, u32 *height, +#if defined STELA_API_OPENGL +#ifdef STELA_USE_EGL + EGLDisplay display, + EGLContext context, +#endif + void (*get_gl_proc_address(char const *))(void), + bool (*gl_load_loader)(void *), + bool (*gl_make_current)(void *), + void (*gl_release_current)(void *), + void (*gl_swap_buffers)(void *), +#endif + void *priv) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + (void)width; + (void)height; +#if defined STELA_API_OPENGL +#ifdef STELA_USE_EGL + (void)display; + (void)context; +#endif + (void)get_gl_proc_address; + (void)gl_load_loader; + MOMO_Init(&mr->mmr, gl_make_current, gl_release_current, gl_swap_buffers, priv); +#endif +#ifdef CAMU_HAVE_SUBTITLES + mr->ass = ass_library_init(); + // Just to keep these linked in the exe for platform testing. + ASS_Renderer *ar = ass_renderer_init(mr->ass); + ASS_Track *at = ass_new_track(mr->ass); + (void)at; + u32 w = *width, h = *height; + ass_set_frame_size(ar, w, h); + ass_set_storage_size(ar, w, h); + ass_set_fonts(ar, NULL, NULL, ASS_FONTPROVIDER_AUTODETECT, NULL, 0); + ass_set_hinting(ar, ASS_HINTING_NONE); +#endif + return true; +} + +static struct camu_frame_queue *renderer_momo_create_queue(struct camu_renderer *renderer) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + struct camu_frame_queue *q = camu_frame_queue_momo_create(); + struct camu_frame_queue_momo *mq = (struct camu_frame_queue_momo *)q; + (void)mr; + (void)mq; + return q; +} + +static u32 renderer_momo_get_latency(struct camu_renderer *renderer) +{ + (void)renderer; + return 0; +} + +static void renderer_momo_render(struct camu_renderer *renderer, struct camu_screen *scr, bool force) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)renderer; + (void)scr; + (void)force; + MOMO_Render(&mr->mmr); +} + +static void renderer_momo_free(struct camu_renderer **renderer) +{ + struct camu_renderer_momo *mr = (struct camu_renderer_momo *)*renderer; + al_free(mr); + *renderer = NULL; +} + +struct camu_renderer *camu_renderer_momo_create(void) +{ + struct camu_renderer_momo *mr = al_alloc_object(struct camu_renderer_momo); + mr->r.create_renderer = renderer_momo_create_renderer; + mr->r.create_queue = renderer_momo_create_queue; + mr->r.get_latency = renderer_momo_get_latency; + mr->r.resize = renderer_momo_resize; + mr->r.render = renderer_momo_render; + mr->r.free = renderer_momo_free; + return (struct camu_renderer *)mr; +} diff --git a/src/render/renderer_momo.h b/src/render/renderer_momo.h new file mode 100644 index 0000000..3b9084b --- /dev/null +++ b/src/render/renderer_momo.h @@ -0,0 +1,19 @@ +#pragma once + +#ifdef CAMU_HAVE_SUBTITLES +#include <ass/ass.h> +#endif + +#include "momo/momo.h" + +#include "renderer.h" + +struct camu_renderer_momo { + struct camu_renderer r; + MOMO_Renderer mmr; +#ifdef CAMU_HAVE_SUBTITLES + ASS_Library *ass; +#endif +}; + +struct camu_renderer *camu_renderer_momo_create(void); diff --git a/src/render/renderer_tiger.c b/src/render/renderer_tiger.c deleted file mode 100644 index eb99e0c..0000000 --- a/src/render/renderer_tiger.c +++ /dev/null @@ -1,320 +0,0 @@ -#define AL_LOG_SECTION "renderer_tiger" -#include <al/log.h> -#include <al/lib.h> -#include <linmath.h> - -#include "../screen/view.h" -#include "../screen/screen.h" -#include "../util/color_palette.h" - -#include "renderer_tiger.h" -#include "queue_tiger.h" - -#ifdef CAMU_RENDERER_OPENGL -static const GLfloat default_vertices[] = { - 0.f, 0.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, 1.f, - 1.f, 0.f, 0.f, 1.f, 0.f, - 1.f, 0.f, 0.f, 1.f, 0.f, - 0.f, 1.f, 0.f, 0.f, 1.f, - 1.f, 1.f, 0.f, 1.f, 1.f -}; - -static GLfloat clear_color[4] = { 0.f, 0.f, 0.f, 1.f }; - -static const GLchar *default_vs = \ - "#version 100\n" \ - "attribute vec3 a_Position;\n" \ - "attribute vec2 a_TexCoord;\n" \ - "varying vec2 v_TexCoord;\n" \ - "uniform mat4 g_ModelViewProjectionMatrix;\n" \ - "void main() {\n" \ - " gl_Position = g_ModelViewProjectionMatrix * vec4(a_Position, 1.0);\n" \ - " v_TexCoord = a_TexCoord;\n" \ - "}"; - -static const GLchar *default_fs = \ - "#version 100\n" \ - "precision mediump float;\n" \ - "varying vec2 v_TexCoord;\n" \ - "uniform sampler2D g_Texture0;\n" \ - "void main() {\n" \ - " gl_FragColor = texture2D(g_Texture0, v_TexCoord);\n" \ - "}"; - -static bool compile(GLuint shader, const GLchar *source, GLchar *error) -{ - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - - GLint status; - - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - - if (status == GL_FALSE) { - glGetShaderInfoLog(shader, 256, NULL, error); - return false; - } - - return true; -} - -static bool compile_shaders(struct camu_renderer_tiger *tr) -{ - tr->program = glCreateProgram(); - - GLchar error[256]; - - GLuint vs_shader = glCreateShader(GL_VERTEX_SHADER); - if (!compile(vs_shader, default_vs, error)) { - log_error("Failed to compile vertex shader (%.*s)", sizeof(error), error); - return false; - } - - GLuint fs_shader = glCreateShader(GL_FRAGMENT_SHADER); - if (!compile(fs_shader, default_fs, error)) { - log_error("Failed to compile fragment shader (%.*s)", sizeof(error), error); - return false; - } - - glAttachShader(tr->program, vs_shader); - glAttachShader(tr->program, fs_shader); - glLinkProgram(tr->program); - - return true; -} -#endif - -static void renderer_tiger_resize(struct camu_renderer *renderer, u32 *width, u32 *height) -{ - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - (void)tr; - (void)width; - (void)height; -} - -static bool renderer_tiger_create_renderer(struct camu_renderer *renderer, u32 *width, u32 *height, -#if defined CAMU_RENDERER_VULKAN - VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), - void (*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 *), - void (*gl_release_current)(void *), - void (*gl_swap_buffers)(void *), -#endif - void *priv) -{ - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - (void)width; - (void)height; -#ifdef CAMU_RENDERER_OPENGL - (void)display; - (void)context; - (void)get_gl_proc_address; - - tr->load_loader = gl_load_loader; - tr->make_current = gl_make_current; - tr->release_current = gl_release_current; - tr->swap_buffers = gl_swap_buffers; - tr->priv = priv; - - tr->make_current(tr->priv); - - if (!tr->load_loader(tr->priv)) { - return false; - } - - clear_color[0] = ((global_color_palette.colors[0] >> 16) & 0xff) / 255.f; - clear_color[1] = ((global_color_palette.colors[0] >> 8) & 0xff) / 255.f; - clear_color[2] = ((global_color_palette.colors[0]) & 0xff) / 255.f; - - glClearColor(clear_color[0], clear_color[1], clear_color[2], 1.f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glGenBuffers(1, &tr->vbo); - glBindBuffer(GL_ARRAY_BUFFER, tr->vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(default_vertices), default_vertices, GL_STATIC_DRAW); - - if (!compile_shaders(tr)) return false; - - glUseProgram(tr->program); - - GLint pos = glGetAttribLocation(tr->program, "a_Position"); - glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)0); - if (stl_gl_check_error()) { - log_error("glVertexAttribPointer returned error, use GLES context."); - al_assert_and_return(false); - } - glEnableVertexAttribArray(pos); - GLint texcoord = glGetAttribLocation(tr->program, "a_TexCoord"); - glVertexAttribPointer(texcoord, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)12); - glEnableVertexAttribArray(texcoord); - - //glGenBuffers(1, &tr->texture_buffer); -#endif - -#ifdef CAMU_HAVE_FFMPEG - tr->r.get_buffer2 = NULL; - tr->r.opaque = NULL; -#endif - - return true; -} - -static struct camu_frame_queue *renderer_tiger_create_queue(struct camu_renderer *renderer) -{ -#ifdef CAMU_RENDERER_OPENGL - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - struct camu_frame_queue *q = camu_frame_queue_tiger_create(); - struct camu_frame_queue_tiger *tq = (struct camu_frame_queue_tiger *)q; - tq->tr = tr; - return q; -#endif -} - -static u32 renderer_tiger_get_latency(struct camu_renderer *renderer) -{ - (void)renderer; - return 0; -} - -static void set_uniform(struct camu_renderer_tiger *tr, const GLchar *name, - u8 type, void *value) -{ -#ifdef CAMU_RENDERER_OPENGL - GLint loc = glGetUniformLocation(tr->program, name); - if (loc == -1) return; - - switch (type) - { - case TYPE_FLOAT: - glUniform1f(loc, *((GLfloat *)value)); - break; - case TYPE_SAMPLER2D: - glUniform1i(loc, (GLuint)(*((GLfloat *)value))); - break; - case TYPE_VEC2: - glUniform2fv(loc, 1, (GLfloat *)value); - break; - case TYPE_VEC3: - glUniform3fv(loc, 1, (GLfloat *)value); - break; - case TYPE_VEC4: - glUniform4fv(loc, 1, (GLfloat *)value); - break; - case TYPE_MAT4: - glUniformMatrix4fv(loc, 1, GL_FALSE, (GLfloat *)value); - break; - case TYPE_MAT3: - glUniformMatrix3fv(loc, 1, GL_FALSE, (GLfloat *)value); - break; - case TYPE_INVALID: - break; - } -#endif -} - -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); - - glClear(GL_COLOR_BUFFER_BIT); - - glUseProgram(tr->program); - glBindBuffer(GL_ARRAY_BUFFER, tr->vbo); - glActiveTexture(GL_TEXTURE0); - -#ifdef CAMU_SCREEN_THREADED - if (al_atomic_load(u8)(&scr->queued, AL_ATOMIC_RELAXED)) { - camu_screen_run_queue(scr); - } -#endif - - if (scr->videos.count > 0) { - struct camu_screen_video *video = &al_array_last(scr->videos); - - GLuint texture_id; - bool weighted; - if (camu_video_buffer_read(video->buf, &texture_id, &weighted)) { - glBindTexture(GL_TEXTURE_2D, texture_id); - - mat4x4 model; - mat4x4_identity(model); - mat4x4_ortho(model, 0.f, (f32)scr->width, (f32)scr->height, 0.f, -1.f, 1.f); - mat4x4_translate_in_place(model, (f32)video->view.x_offset, (f32)video->view.y_offset, 0.f); - mat4x4_scale_aniso(model, model, (f32)video->view.zoom, (f32)video->view.zoom, 1.f); - mat4x4_scale_aniso(model, model, (f32)video->view.width, (f32)video->view.height, 1.f); - set_uniform(tr, "g_ModelViewProjectionMatrix", TYPE_MAT4, model); - - GLuint texture0 = 0; - set_uniform(tr, "g_Texture0", TYPE_SAMPLER2D, &texture0); - - glViewport(0, 0, scr->width, scr->height); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - } - - tr->swap_buffers(tr->priv); -#endif - - tr->release_current(tr->priv); -} - -/* -static void *renderer_tiger_get_device_ptr(struct camu_renderer *renderer, size_t length) -{ - (void)renderer; - (void)length; - return NULL; -#ifdef CAMU_RENDERER_OPENGL - //struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - //glBindBuffer(GL_PIXEL_UNPACK_BUFFER, tr->texture_buffer); - //glBufferData(GL_PIXEL_UNPACK_BUFFER, length, NULL, GL_STREAM_DRAW); - //return glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, length, GL_MAP_WRITE_BIT); -#endif -} - -static void renderer_tiger_commit_device_ptr(struct camu_renderer *renderer) -{ - (void)renderer; -#ifdef CAMU_RENDERER_OPENGL - //struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)renderer; - //glBindBuffer(GL_PIXEL_UNPACK_BUFFER, tr->texture_buffer); - //glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); -#endif -} -*/ - -static void renderer_tiger_free(struct camu_renderer **renderer) -{ - struct camu_renderer_tiger *tr = (struct camu_renderer_tiger *)*renderer; - glDeleteProgram(tr->program); - glDeleteBuffers(1, &tr->vbo); - al_free(tr); - *renderer = NULL; -} - -struct camu_renderer *camu_renderer_tiger_create(void) -{ - struct camu_renderer_tiger *tr = al_alloc_object(struct camu_renderer_tiger); - tr->r.create_renderer = renderer_tiger_create_renderer; - tr->r.create_queue = renderer_tiger_create_queue; - tr->r.get_latency = renderer_tiger_get_latency; - tr->r.resize = renderer_tiger_resize; - tr->r.render = renderer_tiger_render; - tr->r.free = renderer_tiger_free; - return (struct camu_renderer *)tr; -} diff --git a/src/render/renderer_tiger.h b/src/render/renderer_tiger.h deleted file mode 100644 index 5891c20..0000000 --- a/src/render/renderer_tiger.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include <stl/gl.h> - -#include "renderer.h" - -enum { - TYPE_INVALID = 0, - TYPE_FLOAT, - TYPE_VEC4, - TYPE_VEC3, - TYPE_VEC2, - TYPE_MAT4, - TYPE_MAT3, - TYPE_SAMPLER2D -}; - -struct camu_renderer_tiger { - struct camu_renderer r; - GLuint vao; - GLuint vbo; - GLuint program; - GLuint texture_buffer; - bool (*load_loader)(void *); - bool (*make_current)(void *); - void (*release_current)(void *); - void (*swap_buffers)(void *); - void *priv; -}; - -struct camu_renderer *camu_renderer_tiger_create(void); |