feat(render): dynamic OpenGL/Vulkan backend split and backend-neutral viewer

- Extract libolive-rendercore static library to minimize backend link boundary.
- Add DynamicRenderer adapter with C ABI (oakgl/oakvulkan shared libs).
- Make OAK_ENABLE_DYNAMIC_RENDER_BACKEND default ON with OpenGL fallback.
- Implement VulkanRenderer prototype (textures, shaders, UBO blit, readback).
- Add backend-neutral viewer readback path (offscreen -> QImage -> QPainter).
- Refactor PluginRenderer to be renderer-agnostic; OFX plugins fall back to CPU
  path on non-OpenGL backends while preserving OpenGL render path.
- Add Renderer::AttachOutputTexture/DetachOutputTexture and C ABI forwards.
- Update docs/zh/render-backend-dynamic-plan.md for Phase 3/4/5.
This commit is contained in:
2026-07-13 10:19:29 +08:00
parent 5fc8232671
commit 225f8505c2
42 changed files with 3042 additions and 495 deletions
+28
View File
@@ -45,6 +45,8 @@ QString DynamicRenderer::LibraryFilename() const
const QStringList candidates = {
app_dir.filePath(filename),
app_dir.filePath(QDir(QStringLiteral("render_backends")).filePath(filename)),
app_dir.filePath(QDir(QStringLiteral("../lib")).filePath(filename)),
app_dir.filePath(QDir(QStringLiteral("../../lib")).filePath(filename)),
app_dir.filePath(QDir(QStringLiteral("../app")).filePath(filename)),
app_dir.filePath(QDir(QStringLiteral("../../app")).filePath(filename))
};
@@ -139,6 +141,10 @@ bool DynamicRenderer::ResolveFunctions()
RESOLVE(get_pixel_from_texture_, OakBackendGetPixelFromTextureFn,
"oak_renderer_get_pixel_from_texture");
RESOLVE(blit_, OakBackendBlitFn, "oak_renderer_blit");
RESOLVE(attach_output_texture_, OakBackendAttachOutputTextureFn,
"oak_renderer_attach_output_texture");
RESOLVE(detach_output_texture_, OakBackendDetachOutputTextureFn,
"oak_renderer_detach_output_texture");
RESOLVE(opengl_context_, OakBackendOpenGLContextFn,
"oak_renderer_opengl_context");
#undef RESOLVE
@@ -184,6 +190,8 @@ void DynamicRenderer::ResetFunctions()
flush_ = nullptr;
get_pixel_from_texture_ = nullptr;
blit_ = nullptr;
attach_output_texture_ = nullptr;
detach_output_texture_ = nullptr;
opengl_context_ = nullptr;
}
@@ -271,6 +279,11 @@ QOpenGLContext *DynamicRenderer::OpenGLContext() const
: nullptr;
}
bool DynamicRenderer::IsOpenGL() const
{
return backend_ == QStringLiteral("opengl");
}
void DynamicRenderer::Blit(QVariant shader, AcceleratedJob &job,
Texture *destination, VideoParams destination_params,
bool clear_destination)
@@ -301,4 +314,19 @@ void DynamicRenderer::DestroyInternal()
}
}
void DynamicRenderer::AttachOutputTexture(Texture *texture)
{
if (attach_output_texture_ && texture) {
QVariant id = texture->id();
attach_output_texture_(handle_, &id);
}
}
void DynamicRenderer::DetachOutputTexture()
{
if (detach_output_texture_) {
detach_output_texture_(handle_);
}
}
}
+8
View File
@@ -44,6 +44,12 @@ public:
const QPointF &pt) override;
virtual QOpenGLContext *OpenGLContext() const override;
virtual bool IsOpenGL() const override;
virtual void AttachOutputTexture(Texture *texture) override;
virtual void DetachOutputTexture() override;
protected:
virtual void Blit(QVariant shader, AcceleratedJob &job,
Texture *destination, VideoParams destination_params,
@@ -84,6 +90,8 @@ private:
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;
};
+6 -1
View File
@@ -27,7 +27,9 @@ enum OakRenderBackendCapability {
OAK_RENDER_BACKEND_CAP_SHADERS = 1ULL << 1,
OAK_RENDER_BACKEND_CAP_BLIT = 1ULL << 2,
OAK_RENDER_BACKEND_CAP_READBACK = 1ULL << 3,
OAK_RENDER_BACKEND_CAP_VIEWER_CONTEXT = 1ULL << 4
OAK_RENDER_BACKEND_CAP_VIEWER_CONTEXT = 1ULL << 4,
OAK_RENDER_BACKEND_CAP_INSTANCE = 1ULL << 5,
OAK_RENDER_BACKEND_CAP_DEVICE = 1ULL << 6
};
struct OakRenderBackendInfo {
@@ -81,6 +83,9 @@ typedef void (*OakBackendBlitFn)(OakRenderBackendHandle handle,
void *destination,
const void *destination_params,
bool clear_destination);
typedef void (*OakBackendAttachOutputTextureFn)(OakRenderBackendHandle handle,
const void *texture_id);
typedef void (*OakBackendDetachOutputTextureFn)(OakRenderBackendHandle handle);
typedef void *(*OakBackendOpenGLContextFn)(OakRenderBackendHandle handle);
#ifdef __cplusplus