diff options
author | Marvin Scholz <epirat07@gmail.com> | 2020-05-15 12:57:02 +0300 |
---|---|---|
committer | Marvin Scholz <epirat07@gmail.com> | 2020-05-15 12:57:02 +0300 |
commit | e4a4c8c60b21d226f24cc315af30cb7f1591b29b (patch) | |
tree | 7c3d47e2690e34733a146cef4ed1531cc69646a6 /examples | |
parent | 7f50fc37199b4581d606ffbdf665b8141939b1f9 (diff) |
Dav1dPlay: Split placebo renderer into two
This allows selecting at runtime if placebo should use OpenGL
or Vulkan for rendering.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/dav1dplay.c | 28 | ||||
-rw-r--r-- | examples/dp_renderer.h | 22 | ||||
-rw-r--r-- | examples/dp_renderer_placebo.c | 203 | ||||
-rw-r--r-- | examples/dp_renderer_sdl.c | 11 |
4 files changed, 165 insertions, 99 deletions
diff --git a/examples/dav1dplay.c b/examples/dav1dplay.c index 92e2895..9841b11 100644 --- a/examples/dav1dplay.c +++ b/examples/dav1dplay.c @@ -155,15 +155,9 @@ static void dp_rd_ctx_parse_args(Dav1dPlayRenderContext *rd_ctx, break; case ARG_HIGH_QUALITY: settings->highquality = true; -#ifndef HAVE_RENDERER_PLACEBO - fprintf(stderr, "warning: --highquality requires libplacebo\n"); -#endif break; case 'z': settings->zerocopy = true; -#ifndef HAVE_RENDERER_PLACEBO - fprintf(stderr, "warning: --zerocopy requires libplacebo\n"); -#endif break; case 'r': settings->renderer_name = optarg; @@ -209,7 +203,7 @@ static void dp_rd_ctx_destroy(Dav1dPlayRenderContext *rd_ctx) * \note The Dav1dPlayRenderContext must be destroyed * again by using dp_rd_ctx_destroy. */ -static Dav1dPlayRenderContext *dp_rd_ctx_create(void *rd_data, int argc, char **argv) +static Dav1dPlayRenderContext *dp_rd_ctx_create(int argc, char **argv) { Dav1dPlayRenderContext *rd_ctx; @@ -258,7 +252,7 @@ static Dav1dPlayRenderContext *dp_rd_ctx_create(void *rd_data, int argc, char ** printf("Using %s renderer\n", renderer_info->name); } - rd_ctx->rd_priv = (renderer_info) ? renderer_info->create_renderer(rd_data) : NULL; + rd_ctx->rd_priv = (renderer_info) ? renderer_info->create_renderer() : NULL; if (rd_ctx->rd_priv == NULL) { SDL_DestroyMutex(rd_ctx->lock); dp_fifo_destroy(rd_ctx->fifo); @@ -500,7 +494,6 @@ cleanup: int main(int argc, char **argv) { SDL_Thread *decoder_thread; - SDL_Window *win = NULL; // Check for version mismatch between library and tool const char *version = dav1d_version(); @@ -514,22 +507,8 @@ int main(int argc, char **argv) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) return 10; - // Create Window and Renderer - int window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI; -#if defined(HAVE_PLACEBO_VULKAN) - window_flags |= SDL_WINDOW_VULKAN; -#elif defined(HAVE_PLACEBO_OPENGL) -# ifndef NDEBUG - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); -# endif - window_flags |= SDL_WINDOW_OPENGL; -#endif - win = SDL_CreateWindow("Dav1dPlay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - WINDOW_WIDTH, WINDOW_HEIGHT, window_flags); - SDL_SetWindowResizable(win, SDL_TRUE); - // Create render context - Dav1dPlayRenderContext *rd_ctx = dp_rd_ctx_create(win, argc, argv); + Dav1dPlayRenderContext *rd_ctx = dp_rd_ctx_create(argc, argv); if (rd_ctx == NULL) { fprintf(stderr, "Failed creating render context\n"); return 5; @@ -586,7 +565,6 @@ int main(int argc, char **argv) SDL_WaitThread(decoder_thread, &decoder_ret); dp_rd_ctx_destroy(rd_ctx); - SDL_DestroyWindow(win); return decoder_ret; } diff --git a/examples/dp_renderer.h b/examples/dp_renderer.h index 639ccc7..c3b2378 100644 --- a/examples/dp_renderer.h +++ b/examples/dp_renderer.h @@ -29,7 +29,7 @@ #include "dav1d/dav1d.h" -#include <SDL_config.h> +#include <SDL.h> #ifdef HAVE_PLACEBO # include <libplacebo/config.h> #endif @@ -78,7 +78,7 @@ typedef struct rdr_info // Cookie passed to the renderer implementation callbacks void *cookie; // Callback to create the renderer - void* (*create_renderer)(void *data); + void* (*create_renderer)(); // Callback to destroy the renderer void (*destroy_renderer)(void *cookie); // Callback to the render function that renders a prevously sent frame @@ -91,12 +91,14 @@ typedef struct rdr_info void (*release_pic)(Dav1dPicture *pic, void *cookie); } Dav1dPlayRenderInfo; -extern const Dav1dPlayRenderInfo rdr_placebo; +extern const Dav1dPlayRenderInfo rdr_placebo_vk; +extern const Dav1dPlayRenderInfo rdr_placebo_gl; extern const Dav1dPlayRenderInfo rdr_sdl; // Available renderes ordered by priority static const Dav1dPlayRenderInfo* const dp_renderers[] = { - &rdr_placebo, + &rdr_placebo_vk, + &rdr_placebo_gl, &rdr_sdl, }; @@ -113,3 +115,15 @@ static inline const Dav1dPlayRenderInfo *dp_get_renderer(const char *name) } return NULL; } + +static inline SDL_Window *dp_create_sdl_window(int window_flags) +{ + SDL_Window *win; + window_flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI; + + win = SDL_CreateWindow("Dav1dPlay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + WINDOW_WIDTH, WINDOW_HEIGHT, window_flags); + SDL_SetWindowResizable(win, SDL_TRUE); + + return win; +} diff --git a/examples/dp_renderer_placebo.c b/examples/dp_renderer_placebo.c index 9ac2538..95dba04 100644 --- a/examples/dp_renderer_placebo.c +++ b/examples/dp_renderer_placebo.c @@ -29,19 +29,16 @@ #ifdef HAVE_RENDERER_PLACEBO #include <assert.h> -#include <SDL.h> - #include <libplacebo/renderer.h> #include <libplacebo/utils/upload.h> -#if defined(HAVE_PLACEBO_VULKAN) +#ifdef HAVE_PLACEBO_VULKAN # include <libplacebo/vulkan.h> # include <SDL_vulkan.h> -#elif defined(HAVE_PLACEBO_OPENGL) +#endif +#ifdef HAVE_PLACEBO_OPENGL # include <libplacebo/opengl.h> # include <SDL_opengl.h> -#else -# error Placebo rendering only implemented for Vulkan or OpenGL! #endif @@ -50,18 +47,21 @@ */ typedef struct renderer_priv_ctx { + // SDL window + SDL_Window *win; // Placebo context struct pl_context *ctx; // Placebo renderer struct pl_renderer *renderer; -#if defined(HAVE_PLACEBO_VULKAN) +#ifdef HAVE_PLACEBO_VULKAN // Placebo Vulkan handle const struct pl_vulkan *vk; // Placebo Vulkan instance const struct pl_vk_inst *vk_inst; // Vulkan surface VkSurfaceKHR surf; -#elif defined(HAVE_PLACEBO_OPENGL) +#endif +#ifdef HAVE_PLACEBO_OPENGL // Placebo OpenGL handle const struct pl_opengl *gl; #endif @@ -81,13 +81,20 @@ typedef struct renderer_priv_ctx const struct pl_tex *v_tex; } Dav1dPlayRendererPrivateContext; -static void *placebo_renderer_create(void *data) +static Dav1dPlayRendererPrivateContext* + placebo_renderer_create_common(int window_flags) { + // Create Window + SDL_Window *sdlwin = dp_create_sdl_window(window_flags); + if (sdlwin == NULL) + return NULL; + // Alloc Dav1dPlayRendererPrivateContext *rd_priv_ctx = malloc(sizeof(Dav1dPlayRendererPrivateContext)); if (rd_priv_ctx == NULL) { return NULL; } + rd_priv_ctx->win = sdlwin; // Init libplacebo rd_priv_ctx->ctx = pl_context_create(PL_API_VER, &(struct pl_context_params) { @@ -112,13 +119,95 @@ static void *placebo_renderer_create(void *data) return NULL; } + rd_priv_ctx->y_tex = NULL; + rd_priv_ctx->u_tex = NULL; + rd_priv_ctx->v_tex = NULL; + + rd_priv_ctx->renderer = NULL; + +#ifdef HAVE_PLACEBO_OPENGL + rd_priv_ctx->gl = NULL; +#endif +#ifdef HAVE_PLACEBO_VULKAN + rd_priv_ctx->vk = NULL; +#endif + + return rd_priv_ctx; +} + +#ifdef HAVE_PLACEBO_OPENGL +static void *placebo_renderer_create_gl() +{ + SDL_Window *sdlwin = NULL; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); + + // Common init + Dav1dPlayRendererPrivateContext *rd_priv_ctx = + placebo_renderer_create_common(SDL_WINDOW_OPENGL); + + if (rd_priv_ctx == NULL) + return NULL; + sdlwin = rd_priv_ctx->win; + + // Init OpenGL + struct pl_opengl_params params = pl_opengl_default_params; +# ifndef NDEBUG + params.debug = true; +# endif + + SDL_GLContext glcontext = SDL_GL_CreateContext(sdlwin); + SDL_GL_MakeCurrent(sdlwin, glcontext); + + rd_priv_ctx->gl = pl_opengl_create(rd_priv_ctx->ctx, ¶ms); + if (!rd_priv_ctx->gl) { + fprintf(stderr, "Failed creating opengl device!\n"); + exit(2); + } + + rd_priv_ctx->swapchain = pl_opengl_create_swapchain(rd_priv_ctx->gl, + &(struct pl_opengl_swapchain_params) { + .swap_buffers = (void (*)(void *)) SDL_GL_SwapWindow, + .priv = sdlwin, + }); + + if (!rd_priv_ctx->swapchain) { + fprintf(stderr, "Failed creating opengl swapchain!\n"); + exit(2); + } + + int w = WINDOW_WIDTH, h = WINDOW_HEIGHT; + SDL_GL_GetDrawableSize(sdlwin, &w, &h); + + if (!pl_swapchain_resize(rd_priv_ctx->swapchain, &w, &h)) { + fprintf(stderr, "Failed resizing vulkan swapchain!\n"); + exit(2); + } + + rd_priv_ctx->gpu = rd_priv_ctx->gl->gpu; + + if (w != WINDOW_WIDTH || h != WINDOW_HEIGHT) + printf("Note: window dimensions differ (got %dx%d)\n", w, h); + + return rd_priv_ctx; +} +#endif + +#ifdef HAVE_PLACEBO_VULKAN +static void *placebo_renderer_create_vk() +{ + SDL_Window *sdlwin = NULL; + + // Common init + Dav1dPlayRendererPrivateContext *rd_priv_ctx = + placebo_renderer_create_common(SDL_WINDOW_VULKAN); + + if (rd_priv_ctx == NULL) + return NULL; + sdlwin = rd_priv_ctx->win; -#if defined(HAVE_PLACEBO_VULKAN) // Init Vulkan struct pl_vk_inst_params iparams = pl_vk_inst_default_params; - SDL_Window *sdlwin = data; - unsigned num = 0; if (!SDL_Vulkan_GetInstanceExtensions(sdlwin, &num, NULL)) { fprintf(stderr, "Failed enumerating Vulkan extensions: %s\n", SDL_GetError()); @@ -183,56 +272,13 @@ static void *placebo_renderer_create(void *data) } rd_priv_ctx->gpu = rd_priv_ctx->vk->gpu; -#elif defined(HAVE_PLACEBO_OPENGL) - // Init OpenGL - struct pl_opengl_params params = pl_opengl_default_params; -# ifndef NDEBUG - params.debug = true; -# endif - - SDL_Window *sdlwin = data; - SDL_GLContext glcontext = SDL_GL_CreateContext(sdlwin); - SDL_GL_MakeCurrent(sdlwin, glcontext); - - rd_priv_ctx->gl = pl_opengl_create(rd_priv_ctx->ctx, ¶ms); - if (!rd_priv_ctx->gl) { - fprintf(stderr, "Failed creating opengl device!\n"); - exit(2); - } - - rd_priv_ctx->swapchain = pl_opengl_create_swapchain(rd_priv_ctx->gl, - &(struct pl_opengl_swapchain_params) { - .swap_buffers = (void (*)(void *)) SDL_GL_SwapWindow, - .priv = sdlwin, - }); - - if (!rd_priv_ctx->swapchain) { - fprintf(stderr, "Failed creating opengl swapchain!\n"); - exit(2); - } - - int w = WINDOW_WIDTH, h = WINDOW_HEIGHT; - SDL_GL_GetDrawableSize(sdlwin, &w, &h); - - if (!pl_swapchain_resize(rd_priv_ctx->swapchain, &w, &h)) { - fprintf(stderr, "Failed resizing vulkan swapchain!\n"); - exit(2); - } - - rd_priv_ctx->gpu = rd_priv_ctx->gl->gpu; -#endif if (w != WINDOW_WIDTH || h != WINDOW_HEIGHT) printf("Note: window dimensions differ (got %dx%d)\n", w, h); - rd_priv_ctx->y_tex = NULL; - rd_priv_ctx->u_tex = NULL; - rd_priv_ctx->v_tex = NULL; - - rd_priv_ctx->renderer = NULL; - return rd_priv_ctx; } +#endif static void placebo_renderer_destroy(void *cookie) { @@ -245,14 +291,20 @@ static void placebo_renderer_destroy(void *cookie) pl_tex_destroy(rd_priv_ctx->gpu, &(rd_priv_ctx->v_tex)); pl_swapchain_destroy(&(rd_priv_ctx->swapchain)); -#if defined(HAVE_PLACEBO_VULKAN) - pl_vulkan_destroy(&(rd_priv_ctx->vk)); - vkDestroySurfaceKHR(rd_priv_ctx->vk_inst->instance, rd_priv_ctx->surf, NULL); - pl_vk_inst_destroy(&(rd_priv_ctx->vk_inst)); -#elif defined(HAVE_PLACEBO_OPENGL) - pl_opengl_destroy(&(rd_priv_ctx->gl)); +#ifdef HAVE_PLACEBO_VULKAN + if (rd_priv_ctx->vk) { + pl_vulkan_destroy(&(rd_priv_ctx->vk)); + vkDestroySurfaceKHR(rd_priv_ctx->vk_inst->instance, rd_priv_ctx->surf, NULL); + pl_vk_inst_destroy(&(rd_priv_ctx->vk_inst)); + } +#endif +#ifdef HAVE_PLACEBO_OPENGL + if (rd_priv_ctx->gl) + pl_opengl_destroy(&(rd_priv_ctx->gl)); #endif + SDL_DestroyWindow(rd_priv_ctx->win); + pl_context_destroy(&(rd_priv_ctx->ctx)); } @@ -492,16 +544,35 @@ static void placebo_release_pic(Dav1dPicture *pic, void *cookie) SDL_UnlockMutex(rd_priv_ctx->lock); } -const Dav1dPlayRenderInfo rdr_placebo = { - .name = "placebo", - .create_renderer = placebo_renderer_create, +#ifdef HAVE_PLACEBO_OPENGL +const Dav1dPlayRenderInfo rdr_placebo_vk = { + .name = "placebo-vk", + .create_renderer = placebo_renderer_create_vk, + .destroy_renderer = placebo_renderer_destroy, + .render = placebo_render, + .update_frame = placebo_upload_planes, + .alloc_pic = placebo_alloc_pic, + .release_pic = placebo_release_pic, +}; +#else +const Dav1dPlayRenderInfo rdr_placebo_vk = { NULL }; +#endif + +#ifdef HAVE_PLACEBO_VULKAN +const Dav1dPlayRenderInfo rdr_placebo_gl = { + .name = "placebo-gl", + .create_renderer = placebo_renderer_create_gl, .destroy_renderer = placebo_renderer_destroy, .render = placebo_render, .update_frame = placebo_upload_planes, .alloc_pic = placebo_alloc_pic, .release_pic = placebo_release_pic, }; +#else +const Dav1dPlayRenderInfo rdr_placebo_gl = { NULL }; +#endif #else -const Dav1dPlayRenderInfo rdr_placebo = { NULL }; +const Dav1dPlayRenderInfo rdr_placebo_vk = { NULL }; +const Dav1dPlayRenderInfo rdr_placebo_gl = { NULL }; #endif diff --git a/examples/dp_renderer_sdl.c b/examples/dp_renderer_sdl.c index 4784d98..078d613 100644 --- a/examples/dp_renderer_sdl.c +++ b/examples/dp_renderer_sdl.c @@ -28,13 +28,13 @@ #include <assert.h> -#include <SDL.h> - /** * Renderer context for SDL */ typedef struct renderer_priv_ctx { + // SDL window + SDL_Window *win; // SDL renderer SDL_Renderer *renderer; // Lock protecting access to the texture @@ -43,15 +43,18 @@ typedef struct renderer_priv_ctx SDL_Texture *tex; } Dav1dPlayRendererPrivateContext; -static void *sdl_renderer_create(void *data) +static void *sdl_renderer_create() { - SDL_Window *win = data; + SDL_Window *win = dp_create_sdl_window(0); + if (win == NULL) + return NULL; // Alloc Dav1dPlayRendererPrivateContext *rd_priv_ctx = malloc(sizeof(Dav1dPlayRendererPrivateContext)); if (rd_priv_ctx == NULL) { return NULL; } + rd_priv_ctx->win = win; // Create renderer rd_priv_ctx->renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); |