/*** Oak - Non-Linear Video Editor Copyright (C) 2026 Oak Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "oakengine/display.h" #include #include #include #include "codec/frame.h" #include "render/job/colortransformjob.h" #include "render/opengl/openglrenderer.h" #include "render/renderer.h" #include "render/texture.h" #ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND #include "render/backend/dynamicrenderer.h" #endif extern "C" { void *oakengine_display_renderer_create_dynamic(const char *backend_name, void *parent) { #ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND QObject *p = static_cast(parent); auto *dyn = new olive::DynamicRenderer( QString::fromUtf8(backend_name ? backend_name : ""), p); if (dyn->load()) { return dyn; } // Backend library failed to load: drop it so the caller can fall back // to the built-in OpenGL renderer. delete dyn; return nullptr; #else (void)backend_name; (void)parent; return nullptr; #endif } void *oakengine_display_renderer_create_opengl(void *parent) { return new olive::OpenGLRenderer(static_cast(parent)); } int oakengine_display_renderer_init(void *renderer, void *gl_context) { olive::Renderer *r = static_cast(renderer); if (!r) { return OAKENGINE_E_INVALID; } if (gl_context) { QOpenGLContext *ctx = static_cast(gl_context); #ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND if (auto *dyn = dynamic_cast(r)) { dyn->init_with_open_gl_context(ctx); dyn->post_init(); return OAKENGINE_OK; } #endif auto *gl = static_cast(r); gl->init(ctx); gl->post_init(); return OAKENGINE_OK; } r->init(); r->post_init(); return OAKENGINE_OK; } void oakengine_display_renderer_destroy(void *renderer) { olive::Renderer *r = static_cast(renderer); if (!r) { return; } r->destroy(); r->post_destroy(); } void oakengine_display_renderer_create_texture(void *renderer, const void *video_params, const void *pixels, int linesize, void *out_texture) { olive::Renderer *r = static_cast(renderer); if (!r || !video_params || !out_texture) { return; } const olive::VideoParams ¶ms = *static_cast(video_params); *static_cast(out_texture) = r->create_texture(params, pixels, linesize); } void oakengine_display_renderer_blit_color_managed(void *renderer, const void *color_job, void *dst_texture, const void *video_params) { olive::Renderer *r = static_cast(renderer); if (!r || !color_job) { return; } const olive::ColorTransformJob &job = *static_cast(color_job); olive::Texture *dst = static_cast(dst_texture); if (video_params) { r->blit_color_managed( job, dst, *static_cast(video_params)); } else if (dst) { r->blit_color_managed(job, dst, dst->params()); } } void oakengine_display_texture_upload(void *texture, void *pixels, int linesize) { olive::Texture *t = static_cast(texture); if (!t) { return; } t->upload(pixels, linesize); } void oakengine_display_texture_download(void *texture, void *pixels, int linesize) { olive::Texture *t = static_cast(texture); if (!t) { return; } t->download(pixels, linesize); } void oakengine_codec_frame_create(void *out_frame) { if (!out_frame) { return; } *static_cast(out_frame) = olive::Frame::create(); } void oakengine_codec_frame_set_video_params(void *frame, const void *video_params) { olive::Frame *f = static_cast(frame); if (!f || !video_params) { return; } f->set_video_params(*static_cast(video_params)); } int oakengine_codec_frame_allocate(void *frame) { olive::Frame *f = static_cast(frame); if (!f) { return 0; } return f->allocate() ? 1 : 0; } } // extern "C"