ref: 41e0819960eb2eadc0bfeb550fa2a04f86467d73
parent: 9c56be26dcdb5f32584c5e7e810a7884a9ad4fff
author: Marvin Scholz <epirat07@gmail.com>
date: Tue Apr 28 13:48:08 EDT 2020
Dav1dPlay: Add support for OpenGL with libplacebo
--- a/examples/dav1dplay.c
+++ b/examples/dav1dplay.c
@@ -83,14 +83,22 @@
void (*release_pic)(Dav1dPicture *pic, void *cookie);
} Dav1dPlayRenderInfo;
-#ifdef HAVE_PLACEBO_VULKAN
+#if defined(HAVE_PLACEBO_VULKAN) || defined(HAVE_PLACEBO_OPENGL)
#include <libplacebo/renderer.h>
#include <libplacebo/utils/upload.h>
-#include <libplacebo/vulkan.h>
-#include <SDL_vulkan.h>
+#if defined(HAVE_PLACEBO_VULKAN)
+# include <libplacebo/vulkan.h>
+# include <SDL_vulkan.h>
+#elif defined(HAVE_PLACEBO_OPENGL)
+# include <libplacebo/opengl.h>
+# include <SDL_opengl.h>
+#else
+# error Placebo rendering only implemented for Vulkan or OpenGL!
+#endif
+
/**
* Renderer context for libplacebo
*/
@@ -100,6 +108,7 @@
struct pl_context *ctx;
// Placebo renderer
struct pl_renderer *renderer;
+#if defined(HAVE_PLACEBO_VULKAN)
// Placebo Vulkan handle
const struct pl_vulkan *vk;
// Placebo Vulkan instance
@@ -106,6 +115,12 @@
const struct pl_vk_inst *vk_inst;
// Vulkan surface
VkSurfaceKHR surf;
+#elif defined(HAVE_PLACEBO_OPENGL)
+ // Placebo OpenGL handle
+ const struct pl_opengl *gl;
+#endif
+ // Placebo GPU
+ const struct pl_gpu *gpu;
// Placebo swapchain
const struct pl_swapchain *swapchain;
// Lock protecting access to the texture
@@ -122,6 +137,7 @@
static void *placebo_renderer_create(void *data)
{
+ fprintf(stderr, "Using placebo renderer\n");
// Alloc
Dav1dPlayRendererPrivateContext *rd_priv_ctx = malloc(sizeof(Dav1dPlayRendererPrivateContext));
if (rd_priv_ctx == NULL) {
@@ -151,6 +167,8 @@
return NULL;
}
+
+#if defined(HAVE_PLACEBO_VULKAN)
// Init Vulkan
struct pl_vk_inst_params iparams = pl_vk_inst_default_params;
@@ -219,6 +237,46 @@
exit(2);
}
+ 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);
@@ -237,13 +295,19 @@
assert(rd_priv_ctx != NULL);
pl_renderer_destroy(&(rd_priv_ctx->renderer));
- pl_tex_destroy(rd_priv_ctx->vk->gpu, &(rd_priv_ctx->y_tex));
- pl_tex_destroy(rd_priv_ctx->vk->gpu, &(rd_priv_ctx->u_tex));
- pl_tex_destroy(rd_priv_ctx->vk->gpu, &(rd_priv_ctx->v_tex));
+ pl_tex_destroy(rd_priv_ctx->gpu, &(rd_priv_ctx->y_tex));
+ pl_tex_destroy(rd_priv_ctx->gpu, &(rd_priv_ctx->u_tex));
+ 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));
+#endif
+
pl_context_destroy(&(rd_priv_ctx->ctx));
}
@@ -260,7 +324,7 @@
// Prepare rendering
if (rd_priv_ctx->renderer == NULL) {
- rd_priv_ctx->renderer = pl_renderer_create(rd_priv_ctx->ctx, rd_priv_ctx->vk->gpu);
+ rd_priv_ctx->renderer = pl_renderer_create(rd_priv_ctx->ctx, rd_priv_ctx->gpu);
}
struct pl_swapchain_frame frame;
@@ -375,9 +439,9 @@
}
bool ok = true;
- ok &= pl_upload_plane(rd_priv_ctx->vk->gpu, &(rd_priv_ctx->y_plane), &(rd_priv_ctx->y_tex), &data_y);
- ok &= pl_upload_plane(rd_priv_ctx->vk->gpu, &(rd_priv_ctx->u_plane), &(rd_priv_ctx->u_tex), &data_u);
- ok &= pl_upload_plane(rd_priv_ctx->vk->gpu, &(rd_priv_ctx->v_plane), &(rd_priv_ctx->v_tex), &data_v);
+ ok &= pl_upload_plane(rd_priv_ctx->gpu, &(rd_priv_ctx->y_plane), &(rd_priv_ctx->y_tex), &data_y);
+ ok &= pl_upload_plane(rd_priv_ctx->gpu, &(rd_priv_ctx->u_plane), &(rd_priv_ctx->u_tex), &data_u);
+ ok &= pl_upload_plane(rd_priv_ctx->gpu, &(rd_priv_ctx->v_plane), &(rd_priv_ctx->v_tex), &data_v);
pl_chroma_location_offset(PL_CHROMA_LEFT, &rd_priv_ctx->u_plane.shift_x, &rd_priv_ctx->u_plane.shift_y);
pl_chroma_location_offset(PL_CHROMA_LEFT, &rd_priv_ctx->v_plane.shift_x, &rd_priv_ctx->v_plane.shift_y);
@@ -399,7 +463,7 @@
assert(rd_priv_ctx != NULL);
SDL_LockMutex(rd_priv_ctx->lock);
- const struct pl_gpu *gpu = rd_priv_ctx->vk->gpu;
+ const struct pl_gpu *gpu = rd_priv_ctx->gpu;
int ret = DAV1D_ERR(ENOMEM);
// Copied from dav1d_default_picture_alloc
@@ -478,7 +542,7 @@
assert(pic->allocator_data);
SDL_LockMutex(rd_priv_ctx->lock);
- const struct pl_gpu *gpu = rd_priv_ctx->vk->gpu;
+ const struct pl_gpu *gpu = rd_priv_ctx->gpu;
pl_buf_destroy(gpu, (const struct pl_buf **) &pic->allocator_data);
SDL_UnlockMutex(rd_priv_ctx->lock);
}
@@ -738,13 +802,13 @@
break;
case ARG_HIGH_QUALITY:
settings->highquality = true;
-#ifndef HAVE_PLACEBO_VULKAN
+#if !defined(HAVE_PLACEBO_VULKAN) && !defined(HAVE_PLACEBO_OPENGL)
fprintf(stderr, "warning: --highquality requires libplacebo\n");
#endif
break;
case 'z':
settings->zerocopy = true;
-#ifndef HAVE_PLACEBO_VULKAN
+#if !defined(HAVE_PLACEBO_VULKAN) && !defined(HAVE_PLACEBO_OPENGL)
fprintf(stderr, "warning: --zerocopy requires libplacebo\n");
#endif
break;
@@ -1082,8 +1146,13 @@
// Create Window and Renderer
int window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI;
-#ifdef HAVE_PLACEBO_VULKAN
+#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);
@@ -1121,6 +1190,10 @@
if (SDL_WaitEvent(&e)) {
if (e.type == SDL_QUIT) {
dp_rd_ctx_request_shutdown(rd_ctx);
+ } else if (e.type == SDL_WINDOWEVENT) {
+ if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+ // TODO: Handle window resizes
+ }
} else if (e.type == rd_ctx->renderer_event_type) {
if (e.user.code == DAV1D_EVENT_NEW_FRAME) {
// Dequeue frame and update the render context with it
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -44,11 +44,18 @@
placebo_dependency = dependency('libplacebo', version: '>= 1.18.0', required: false)
vulkan_dependency = dependency('vulkan', required: false)
sdl_has_vulkan = cc.has_header('SDL_vulkan.h', dependencies: [sdl2_dependency])
+ sdl_has_opengl = cc.has_header('SDL_opengl.h', dependencies: [sdl2_dependency])
cflag_placebo = []
deps_placebo = []
- if placebo_dependency.found() and vulkan_dependency.found() and sdl_has_vulkan
- cflag_placebo += '-DHAVE_PLACEBO_VULKAN=1'
- deps_placebo = [vulkan_dependency, placebo_dependency]
+ if placebo_dependency.found()
+ deps_placebo += placebo_dependency
+ if vulkan_dependency.found() and sdl_has_vulkan
+ cflag_placebo += '-DHAVE_PLACEBO_VULKAN=1'
+ deps_placebo += vulkan_dependency
+ endif
+ if sdl_has_opengl
+ cflag_placebo += '-DHAVE_PLACEBO_OPENGL=1'
+ endif
endif
dav1dplay = executable('dav1dplay',
dav1dplay_sources,