shithub: dav1d

Download patch

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, &params);
+    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,