ref: e4a4c8c60b21d226f24cc315af30cb7f1591b29b
parent: 7f50fc37199b4581d606ffbdf665b8141939b1f9
author: Marvin Scholz <epirat07@gmail.com>
date: Fri May 15 07:57:02 EDT 2020
Dav1dPlay: Split placebo renderer into two This allows selecting at runtime if placebo should use OpenGL or Vulkan for rendering.
--- a/examples/dav1dplay.c
+++ b/examples/dav1dplay.c
@@ -155,15 +155,9 @@
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 @@
* \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 @@
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 @@
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 @@
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 @@
SDL_WaitThread(decoder_thread, &decoder_ret);
dp_rd_ctx_destroy(rd_ctx);
- SDL_DestroyWindow(win);
return decoder_ret;
}
--- 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 @@
// 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 @@
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,
};
@@ -112,4 +114,16 @@
}
}
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;
}
--- 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,11 +47,13 @@
*/
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
@@ -61,7 +60,8 @@
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 @@
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 @@
return NULL;
}
+ rd_priv_ctx->y_tex = NULL;
+ rd_priv_ctx->u_tex = NULL;
+ rd_priv_ctx->v_tex = NULL;
-#if defined(HAVE_PLACEBO_VULKAN)
+ 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;
+
// 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 @@
}
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 @@
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,9 +544,10 @@
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,
@@ -501,7 +554,25 @@
.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 = { NULL };
+const Dav1dPlayRenderInfo rdr_placebo_gl = { NULL };
+#endif
+
+#else
+const Dav1dPlayRenderInfo rdr_placebo_vk = { NULL };
+const Dav1dPlayRenderInfo rdr_placebo_gl = { NULL };
#endif
--- 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,9 +43,11 @@
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));
@@ -52,6 +54,7 @@
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);