#ifndef DYNAMICRENDERER_H #define DYNAMICRENDERER_H #include #include #include "render/backend/renderbackend_c.h" #include "render/opengl/openglcontextprovider.h" #include "render/renderer.h" namespace olive { // C++ Renderer adapter that loads an Oak render backend shared library and // forwards Renderer calls through the backend's C ABI. class DynamicRenderer : public Renderer, public OpenGLContextProvider { Q_OBJECT public: // Stores the requested backend name; Load() may change it after fallback. explicit DynamicRenderer(const QString &backend, QObject *parent = nullptr); // Destroys backend resources and unloads the dynamic library. virtual ~DynamicRenderer() override; using Renderer::Blit; // Loads the backend library, resolves C ABI symbols, and creates the handle. bool Load(); // Initializes an OpenGL backend with a caller-owned viewer context. bool InitWithOpenGLContext(QOpenGLContext *context); // Retrieves backend metadata through the optional info entry point. bool GetBackendInfo(OakRenderBackendInfo *out_info) const; // Returns the effective backend after any load-time fallback. QString backend_name() const { return backend_; } // Initializes the backend using its default device/context path. virtual bool Init() override; // Runs backend post-destroy cleanup. virtual void PostDestroy() override; // Runs backend post-init setup. virtual void PostInit() override; // Clears either a native texture destination or the backend output target. virtual void ClearDestination(Texture *texture = nullptr, double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override; // Creates a native shader through the dynamic backend. virtual QVariant CreateNativeShader(ShaderCode code) override; // Destroys a native shader through the dynamic backend. virtual void DestroyNativeShader(QVariant shader) override; // Uploads CPU pixels to a backend texture. virtual void UploadToTexture(const QVariant &handle, const VideoParams ¶ms, const void *data, int linesize) override; // Downloads backend texture pixels to CPU memory. virtual void DownloadFromTexture(const QVariant &handle, const VideoParams ¶ms, void *data, int linesize) override; // Waits for backend work to complete. virtual void Flush() override; // Reads one pixel from a backend texture. virtual Color GetPixelFromTexture(Texture *texture, const QPointF &pt) override; // Returns the wrapped OpenGL context for OpenGL backends. virtual QOpenGLContext *OpenGLContext() const override; // Reports whether the effective backend is OpenGL. virtual bool IsOpenGL() const override; // Reports whether the effective backend is Vulkan. virtual bool IsVulkan() const override; // Attaches a texture for OFX OpenGL output when supported. virtual void AttachOutputTexture(Texture *texture) override; // Detaches any OFX output texture binding when supported. virtual void DetachOutputTexture() override; protected: // Dispatches a shader blit through the dynamic backend. virtual void Blit(QVariant shader, AcceleratedJob &job, Texture *destination, VideoParams destination_params, bool clear_destination) override; // Allocates a native texture through the dynamic backend. virtual QVariant CreateNativeTexture(int width, int height, int depth, PixelFormat format, int channel_count, const void *data = nullptr, int linesize = 0) override; // Releases a native texture through the dynamic backend. virtual void DestroyNativeTexture(QVariant texture) override; // Releases backend-owned renderer resources. virtual void DestroyInternal() override; private: // Resolves required backend C ABI symbols. bool ResolveFunctions(); // Replaces a failed Vulkan backend with OpenGL. bool FallbackToOpenGL(); // Clears all cached function pointers. void ResetFunctions(); // Resolves the private backend library path. QString LibraryFilename() const; QString backend_; QLibrary library_; OakRenderBackendHandle handle_ = nullptr; OakBackendCreateFn create_ = nullptr; OakBackendDestroyFn destroy_ = nullptr; OakBackendGetInfoFn get_info_ = nullptr; OakBackendIsAvailableFn is_available_ = nullptr; OakBackendInitFn init_ = nullptr; OakBackendInitWithContextFn init_with_context_ = nullptr; OakBackendPostInitFn post_init_ = nullptr; OakBackendPostDestroyFn post_destroy_ = nullptr; OakBackendDestroyInternalFn destroy_internal_ = nullptr; OakBackendClearDestinationFn clear_destination_ = nullptr; OakBackendCreateNativeTextureFn create_native_texture_ = nullptr; OakBackendDestroyNativeTextureFn destroy_native_texture_ = nullptr; OakBackendCreateNativeShaderFn create_native_shader_ = nullptr; OakBackendDestroyNativeShaderFn destroy_native_shader_ = nullptr; OakBackendUploadToTextureFn upload_to_texture_ = nullptr; OakBackendDownloadFromTextureFn download_from_texture_ = nullptr; OakBackendFlushFn flush_ = nullptr; OakBackendGetPixelFromTextureFn get_pixel_from_texture_ = nullptr; OakBackendBlitFn blit_ = nullptr; OakBackendAttachOutputTextureFn attach_output_texture_ = nullptr; OakBackendDetachOutputTextureFn detach_output_texture_ = nullptr; OakBackendOpenGLContextFn opengl_context_ = nullptr; }; } #endif // DYNAMICRENDERER_H