add Comments
This commit is contained in:
@@ -9,12 +9,16 @@
|
||||
namespace olive
|
||||
{
|
||||
|
||||
// Stores the requested backend name; the actual backend may later become
|
||||
// OpenGL if loading or availability checks require a Vulkan fallback.
|
||||
DynamicRenderer::DynamicRenderer(const QString &backend, QObject *parent)
|
||||
: Renderer(parent)
|
||||
, backend_(backend.toLower())
|
||||
{
|
||||
}
|
||||
|
||||
// Tears down the backend in the reverse order used by Load(): release renderer
|
||||
// resources, destroy the opaque backend object, then unload the shared library.
|
||||
DynamicRenderer::~DynamicRenderer()
|
||||
{
|
||||
Destroy();
|
||||
@@ -28,6 +32,9 @@ DynamicRenderer::~DynamicRenderer()
|
||||
}
|
||||
}
|
||||
|
||||
// Builds the private backend library path for the current platform.
|
||||
// The search is intentionally restricted to Oak-controlled directories so a
|
||||
// system libGL/libvulkan loader is never mistaken for an Oak render backend.
|
||||
QString DynamicRenderer::LibraryFilename() const
|
||||
{
|
||||
const QString base = backend_ == QStringLiteral("vulkan")
|
||||
@@ -58,6 +65,9 @@ QString DynamicRenderer::LibraryFilename() const
|
||||
return candidates.first();
|
||||
}
|
||||
|
||||
// Loads the selected backend, resolves its C ABI table, creates the opaque
|
||||
// backend object, and optionally falls back from Vulkan to OpenGL when runtime
|
||||
// availability checks fail.
|
||||
bool DynamicRenderer::Load()
|
||||
{
|
||||
if (handle_) {
|
||||
@@ -106,6 +116,8 @@ bool DynamicRenderer::Load()
|
||||
return handle_ != nullptr;
|
||||
}
|
||||
|
||||
// Resolves the mandatory C ABI entry points from the loaded shared library.
|
||||
// Optional information probes are resolved after the required render interface.
|
||||
bool DynamicRenderer::ResolveFunctions()
|
||||
{
|
||||
ResetFunctions();
|
||||
@@ -155,6 +167,8 @@ bool DynamicRenderer::ResolveFunctions()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Discards a partially-created backend and restarts loading with the OpenGL
|
||||
// backend. This keeps RenderManager's fallback path inside the adapter.
|
||||
bool DynamicRenderer::FallbackToOpenGL()
|
||||
{
|
||||
if (handle_ && destroy_) {
|
||||
@@ -169,6 +183,8 @@ bool DynamicRenderer::FallbackToOpenGL()
|
||||
return Load();
|
||||
}
|
||||
|
||||
// Clears all cached C function pointers so a failed backend cannot leave stale
|
||||
// call targets behind for a later fallback load.
|
||||
void DynamicRenderer::ResetFunctions()
|
||||
{
|
||||
create_ = nullptr;
|
||||
@@ -195,16 +211,20 @@ void DynamicRenderer::ResetFunctions()
|
||||
opengl_context_ = nullptr;
|
||||
}
|
||||
|
||||
// Returns backend metadata exposed by the dynamic library when available.
|
||||
bool DynamicRenderer::GetBackendInfo(OakRenderBackendInfo *out_info) const
|
||||
{
|
||||
return handle_ && get_info_ && out_info && get_info_(handle_, out_info);
|
||||
}
|
||||
|
||||
// Initializes the loaded backend using its own context/device creation path.
|
||||
bool DynamicRenderer::Init()
|
||||
{
|
||||
return Load() && init_(handle_);
|
||||
}
|
||||
|
||||
// Initializes an OpenGL backend against an existing widget context; non-OpenGL
|
||||
// backends may ignore the context on the library side.
|
||||
bool DynamicRenderer::InitWithOpenGLContext(QOpenGLContext *context)
|
||||
{
|
||||
if (!Load()) {
|
||||
@@ -214,6 +234,8 @@ bool DynamicRenderer::InitWithOpenGLContext(QOpenGLContext *context)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Forwards post-destroy cleanup to the backend while the library is still
|
||||
// loaded and its symbols are still valid.
|
||||
void DynamicRenderer::PostDestroy()
|
||||
{
|
||||
if (handle_ && post_destroy_) {
|
||||
@@ -221,6 +243,8 @@ void DynamicRenderer::PostDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
// Runs backend post-initialization after Init/InitWithOpenGLContext has
|
||||
// established the device or GL context.
|
||||
void DynamicRenderer::PostInit()
|
||||
{
|
||||
if (handle_) {
|
||||
@@ -228,12 +252,15 @@ void DynamicRenderer::PostInit()
|
||||
}
|
||||
}
|
||||
|
||||
// Forwards render target clearing through the C ABI.
|
||||
void DynamicRenderer::ClearDestination(Texture *texture, double r, double g,
|
||||
double b, double a)
|
||||
{
|
||||
clear_destination_(handle_, texture, r, g, b, a);
|
||||
}
|
||||
|
||||
// Creates a backend-native shader and receives the result as an opaque QVariant
|
||||
// because this first-generation ABI still shares C++/Qt types between modules.
|
||||
QVariant DynamicRenderer::CreateNativeShader(ShaderCode code)
|
||||
{
|
||||
QVariant out;
|
||||
@@ -241,11 +268,13 @@ QVariant DynamicRenderer::CreateNativeShader(ShaderCode code)
|
||||
return out;
|
||||
}
|
||||
|
||||
// Releases a backend-native shader handle.
|
||||
void DynamicRenderer::DestroyNativeShader(QVariant shader)
|
||||
{
|
||||
destroy_native_shader_(handle_, &shader);
|
||||
}
|
||||
|
||||
// Uploads CPU pixel data into a backend texture through the dynamic ABI.
|
||||
void DynamicRenderer::UploadToTexture(const QVariant &handle,
|
||||
const VideoParams ¶ms, const void *data,
|
||||
int linesize)
|
||||
@@ -253,6 +282,7 @@ void DynamicRenderer::UploadToTexture(const QVariant &handle,
|
||||
upload_to_texture_(handle_, &handle, ¶ms, data, linesize);
|
||||
}
|
||||
|
||||
// Downloads backend texture data into a caller-provided CPU buffer.
|
||||
void DynamicRenderer::DownloadFromTexture(const QVariant &handle,
|
||||
const VideoParams ¶ms, void *data,
|
||||
int linesize)
|
||||
@@ -260,11 +290,13 @@ void DynamicRenderer::DownloadFromTexture(const QVariant &handle,
|
||||
download_from_texture_(handle_, &handle, ¶ms, data, linesize);
|
||||
}
|
||||
|
||||
// Waits for backend work to become visible to subsequent CPU or GPU consumers.
|
||||
void DynamicRenderer::Flush()
|
||||
{
|
||||
flush_(handle_);
|
||||
}
|
||||
|
||||
// Reads a single pixel through the backend-provided readback hook.
|
||||
Color DynamicRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
|
||||
{
|
||||
Color out;
|
||||
@@ -272,6 +304,8 @@ Color DynamicRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
|
||||
return out;
|
||||
}
|
||||
|
||||
// Exposes the wrapped OpenGL context when the backend is OpenGL; Vulkan returns
|
||||
// null so callers can avoid GL-only paths.
|
||||
QOpenGLContext *DynamicRenderer::OpenGLContext() const
|
||||
{
|
||||
return opengl_context_ && handle_
|
||||
@@ -279,11 +313,13 @@ QOpenGLContext *DynamicRenderer::OpenGLContext() const
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
// Reports the effective backend after any load-time fallback has completed.
|
||||
bool DynamicRenderer::IsOpenGL() const
|
||||
{
|
||||
return backend_ == QStringLiteral("opengl");
|
||||
}
|
||||
|
||||
// Dispatches a shader blit to the loaded backend.
|
||||
void DynamicRenderer::Blit(QVariant shader, AcceleratedJob &job,
|
||||
Texture *destination, VideoParams destination_params,
|
||||
bool clear_destination)
|
||||
@@ -292,6 +328,7 @@ void DynamicRenderer::Blit(QVariant shader, AcceleratedJob &job,
|
||||
clear_destination);
|
||||
}
|
||||
|
||||
// Allocates a backend-native texture and wraps its opaque handle in QVariant.
|
||||
QVariant DynamicRenderer::CreateNativeTexture(int width, int height, int depth,
|
||||
PixelFormat format, int channel_count,
|
||||
const void *data, int linesize)
|
||||
@@ -302,11 +339,14 @@ QVariant DynamicRenderer::CreateNativeTexture(int width, int height, int depth,
|
||||
return out;
|
||||
}
|
||||
|
||||
// Releases a backend-native texture handle.
|
||||
void DynamicRenderer::DestroyNativeTexture(QVariant texture)
|
||||
{
|
||||
destroy_native_texture_(handle_, &texture);
|
||||
}
|
||||
|
||||
// Releases renderer-owned backend resources before the backend object itself is
|
||||
// destroyed.
|
||||
void DynamicRenderer::DestroyInternal()
|
||||
{
|
||||
if (handle_) {
|
||||
@@ -314,6 +354,7 @@ void DynamicRenderer::DestroyInternal()
|
||||
}
|
||||
}
|
||||
|
||||
// Exposes OFX OpenGL output binding through the dynamic backend when supported.
|
||||
void DynamicRenderer::AttachOutputTexture(Texture *texture)
|
||||
{
|
||||
if (attach_output_texture_ && texture) {
|
||||
@@ -322,6 +363,7 @@ void DynamicRenderer::AttachOutputTexture(Texture *texture)
|
||||
}
|
||||
}
|
||||
|
||||
// Clears any OFX output texture binding owned by the backend.
|
||||
void DynamicRenderer::DetachOutputTexture()
|
||||
{
|
||||
if (detach_output_texture_) {
|
||||
|
||||
@@ -11,62 +11,92 @@
|
||||
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;
|
||||
|
||||
// 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_;
|
||||
|
||||
@@ -14,14 +14,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Opaque pointer to the backend-owned C++ renderer object. */
|
||||
typedef void *OakRenderBackendHandle;
|
||||
|
||||
/* Identifies the concrete backend behind a dynamically loaded library. */
|
||||
enum OakRenderBackendKind {
|
||||
OAK_RENDER_BACKEND_UNKNOWN = 0,
|
||||
OAK_RENDER_BACKEND_OPENGL = 1,
|
||||
OAK_RENDER_BACKEND_VULKAN = 2
|
||||
};
|
||||
|
||||
/* Capability bits advertised by a backend through oak_renderer_get_info(). */
|
||||
enum OakRenderBackendCapability {
|
||||
OAK_RENDER_BACKEND_CAP_TEXTURES = 1ULL << 0,
|
||||
OAK_RENDER_BACKEND_CAP_SHADERS = 1ULL << 1,
|
||||
@@ -32,6 +35,7 @@ enum OakRenderBackendCapability {
|
||||
OAK_RENDER_BACKEND_CAP_DEVICE = 1ULL << 6
|
||||
};
|
||||
|
||||
/* Static and runtime metadata returned by the backend. */
|
||||
struct OakRenderBackendInfo {
|
||||
uint32_t abi_version;
|
||||
uint32_t kind;
|
||||
@@ -40,52 +44,74 @@ struct OakRenderBackendInfo {
|
||||
const char *status;
|
||||
};
|
||||
|
||||
/* Creates a backend renderer object. */
|
||||
typedef OakRenderBackendHandle (*OakBackendCreateFn)(void *parent);
|
||||
/* Destroys a backend renderer object created by OakBackendCreateFn. */
|
||||
typedef void (*OakBackendDestroyFn)(OakRenderBackendHandle handle);
|
||||
/* Queries backend metadata and capability bits. */
|
||||
typedef bool (*OakBackendGetInfoFn)(OakRenderBackendHandle handle,
|
||||
struct OakRenderBackendInfo *out_info);
|
||||
/* Checks whether the backend can run on the current machine. */
|
||||
typedef bool (*OakBackendIsAvailableFn)(OakRenderBackendHandle handle);
|
||||
/* Initializes backend-owned device/context resources. */
|
||||
typedef bool (*OakBackendInitFn)(OakRenderBackendHandle handle);
|
||||
/* Initializes the backend against a caller-supplied GL context when applicable. */
|
||||
typedef void (*OakBackendInitWithContextFn)(OakRenderBackendHandle handle,
|
||||
void *context);
|
||||
/* Runs backend post-initialization after the device/context exists. */
|
||||
typedef void (*OakBackendPostInitFn)(OakRenderBackendHandle handle);
|
||||
/* Runs backend post-destroy cleanup before the library unloads. */
|
||||
typedef void (*OakBackendPostDestroyFn)(OakRenderBackendHandle handle);
|
||||
/* Destroys renderer-owned native resources. */
|
||||
typedef void (*OakBackendDestroyInternalFn)(OakRenderBackendHandle handle);
|
||||
/* Clears a texture destination or implicit output target. */
|
||||
typedef void (*OakBackendClearDestinationFn)(OakRenderBackendHandle handle,
|
||||
void *texture, double r, double g,
|
||||
double b, double a);
|
||||
/* Creates a native texture and writes a QVariant-compatible handle. */
|
||||
typedef void (*OakBackendCreateNativeTextureFn)(OakRenderBackendHandle handle,
|
||||
int width, int height, int depth,
|
||||
int format, int channel_count,
|
||||
const void *data, int linesize,
|
||||
void *out_variant);
|
||||
/* Destroys a native texture represented by a QVariant-compatible handle. */
|
||||
typedef void (*OakBackendDestroyNativeTextureFn)(OakRenderBackendHandle handle,
|
||||
const void *variant);
|
||||
/* Creates a native shader and writes a QVariant-compatible handle. */
|
||||
typedef void (*OakBackendCreateNativeShaderFn)(OakRenderBackendHandle handle,
|
||||
const void *shader_code,
|
||||
void *out_variant);
|
||||
/* Destroys a native shader represented by a QVariant-compatible handle. */
|
||||
typedef void (*OakBackendDestroyNativeShaderFn)(OakRenderBackendHandle handle,
|
||||
const void *variant);
|
||||
/* Uploads CPU pixel data to a native texture. */
|
||||
typedef void (*OakBackendUploadToTextureFn)(OakRenderBackendHandle handle,
|
||||
const void *variant,
|
||||
const void *video_params,
|
||||
const void *data, int linesize);
|
||||
/* Downloads native texture pixels into caller-owned CPU memory. */
|
||||
typedef void (*OakBackendDownloadFromTextureFn)(OakRenderBackendHandle handle,
|
||||
const void *variant,
|
||||
const void *video_params,
|
||||
void *data, int linesize);
|
||||
/* Waits for backend work that must be visible to later operations. */
|
||||
typedef void (*OakBackendFlushFn)(OakRenderBackendHandle handle);
|
||||
/* Reads one pixel from a texture. */
|
||||
typedef void (*OakBackendGetPixelFromTextureFn)(OakRenderBackendHandle handle,
|
||||
void *texture, const void *point,
|
||||
void *out_color);
|
||||
/* Executes a shader blit job. */
|
||||
typedef void (*OakBackendBlitFn)(OakRenderBackendHandle handle,
|
||||
const void *shader, void *job,
|
||||
void *destination,
|
||||
const void *destination_params,
|
||||
bool clear_destination);
|
||||
/* Attaches an output texture for OFX OpenGL rendering when supported. */
|
||||
typedef void (*OakBackendAttachOutputTextureFn)(OakRenderBackendHandle handle,
|
||||
const void *texture_id);
|
||||
/* Detaches an OFX output texture when supported. */
|
||||
typedef void (*OakBackendDetachOutputTextureFn)(OakRenderBackendHandle handle);
|
||||
/* Returns the backend OpenGL context, or null for non-OpenGL backends. */
|
||||
typedef void *(*OakBackendOpenGLContextFn)(OakRenderBackendHandle handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user