core: merge oak-common into oak-core
CI / Build & test (Linux) (push) Successful in 24m6s
CI / Build & test (Windows) (push) Successful in 31m14s

oak-common is gone; its modules (configstore, xmlutils, ocioutils,
oiioutils, colormath, colortransform, videoparams, ffmpegutils, ...)
now live in oak-core alongside the value types. The render value/GPU
types moved too: backend (wgpu context + DisplayRenderer), color
(ColorProcessor over ocio-rs), texture, frame, and the commonutil
config helpers.

Fix-ups to make the merged tree build and pass tests:

- oak-core Cargo.toml: wgpu back to 25 (the moved backend code is
  written against that API generation); add the toml/quick-xml/image
  deps oak-common carried.
- lib.rs: drop the duplicate 'pub mod error;'.
- error.rs: unified OAKCORE_* codes; restore Error::new() and
  From<OcioError> from oak-common's error type.
- backend.rs/color.rs: oak_core::/oak_render:: self-references
  rewritten to crate::; the shaderfx-dependent GPU effect test moved
  to oak-render's shaderfx tests (shaderfx depends on oak-node and
  cannot live in oak-core).
- oak-render's error module re-exports oak_core::error::{Error,
  Result}; the OAKRENDER_* codes stay as the public-code contract.
- oak-node jobs.rs: ColorProcessor imported from oak_core::color.
- Integration tests repointed at oak_core::{texture, frame, backend,
  color, colormath}.
- the display-ICC regression test treats an empty OAK_DISPLAY_ICC as
  unset, matching displayicc::env_override_icc.
This commit is contained in:
2026-09-03 17:42:20 +08:00
parent 49fed365a4
commit 4babbf5de8
150 changed files with 3052 additions and 4030 deletions
+6 -6
View File
@@ -24,7 +24,7 @@
//! clip handle 即 `&props`)。
//!
//! 单库化后 oakrender 的 ffi 已删除:帧访问走
//! [`oak_render::texture::Texture::to_frame`] 值路径(GPU 纹理经后端
//! [`oak_core::texture::Texture::to_frame`] 值路径(GPU 纹理经后端
//! 下载、CPU 纹理克隆),帧释放随值 drop 自动发生(原
//! `texture_get_frame`/`frame_free` 句柄调用面随桩删除)。
@@ -89,7 +89,7 @@ impl ClipInstance {
props.set_one(
crate::host::PROP_CLIP_COLOURSPACE,
crate::property::Value::String(
std::ffi::CString::new(oak_render::color::pipeline_working_ofx_name()).unwrap(),
std::ffi::CString::new(oak_core::color::pipeline_working_ofx_name()).unwrap(),
),
);
}
@@ -192,8 +192,8 @@ impl ClipInstance {
scale: RenderScale,
region: Option<OfxRectD>,
) -> crate::error::Result<crate::image::Image> {
use crate::render::PIXEL_FORMAT_F32;
use crate::error::Error;
use crate::render::PIXEL_FORMAT_F32;
let _ = (time, scale);
if region.is_some() {
@@ -333,7 +333,7 @@ impl ClipInstance {
/// 输出纹理由 oakrender 侧创建并经 [`Self::set_output_texture`]
/// 挂入——本函数取该纹理的 CPU 帧(GPU 纹理经后端下载,写回后
/// 对 `Texture::Gpu` 再经
/// [`oak_render::backend::GpuContextLike::upload`] 上传),按帧
/// [`oak_core::backend::GpuContextLike::upload`] 上传),按帧
/// 参数校验 F32 与尺寸后整帧拷贝图像像素(全链路 F32;C++
/// pluginrenderer 的 `readback/wrap` 路径第 1 期以 CPU 拷贝表达,
/// GL 走 [`crate::render`] 的 `// [P2]`)。未挂输出纹理
@@ -343,8 +343,8 @@ impl ClipInstance {
&self,
image: &crate::image::Image,
) -> crate::error::Result<crate::render::Texture> {
use crate::render::{texture_get_frame, PIXEL_FORMAT_F32};
use crate::error::Error;
use crate::render::{texture_get_frame, PIXEL_FORMAT_F32};
let texture = self
.output_texture
@@ -396,7 +396,7 @@ impl ClipInstance {
/// 本 clip 的时间域(clipGetFrameRange)。
///
/// `// TODO(value-model)`:输入范围经 oakrender 帧的时间基推导
/// (time_base)——随 clip 迁移到 `oak_render::texture::Texture`
/// (time_base)——随 clip 迁移到 `oak_core::texture::Texture`
/// 值模型落地。
pub fn frame_range(&self) -> crate::error::Result<OfxRangeD> {
let _ = OfxRangeD::default();
+23 -23
View File
@@ -48,7 +48,7 @@ use oak_node::factory::{DynNodeConstructor, DynamicNodeMeta};
use oak_node::input::{flags as input_flags, Input};
use oak_node::node::{Category, NodeBehavior, NodeCore};
use oak_node::nodes::plugin::{
PluginInstanceHandle, PluginNode, SOURCE_CLIP, TEXTURE_INPUT,
PluginInstanceHandle, PluginNode, SOURCE_CLIP, TEXTURE_INPUT,
};
use oak_node::value::{NodeValue, ValueType};
@@ -832,10 +832,10 @@ fn set_text_param(inst: &Instance, key: &str, text: &str) {
/// executor 槽实现:JobSpec::Plugin → render_driver::render_frame。
fn execute_plugin_job(
req: &oak_render::eval::PluginJobRequest<'_>,
) -> oak_render::error::Result<oak_render::texture::Texture> {
use oak_render::error::Error;
) -> oak_render::error::Result<oak_core::texture::Texture> {
use oak_render::error::Error;
let oak_render::eval::JobSpec::Plugin {
let oak_render::eval::JobSpec::Plugin {
instance,
time,
effect_input_id,
@@ -880,7 +880,7 @@ fn execute_plugin_job(
)?;
let job = crate::render_driver::RenderJob {
time: *time,
dst: oak_render::texture::Texture::wrap_frame(dst_frame),
dst: oak_core::texture::Texture::wrap_frame(dst_frame),
src: Some(req.src.clone()),
effect_input_id: effect_input_id.clone(),
inputs: inputs.clone(),
@@ -962,9 +962,9 @@ fn shared_plugin_instance(identifier: &str) -> Option<u64> {
#[cfg(test)]
mod tests {
use super::*;
use super::*;
/// Records what the mock plugin entry saw, so the push-button test can
/// Records what the mock plugin entry saw, so the push-button test can
/// assert the kOfxActionInstanceChanged routing and its inArgs.
static PUSH_ENTRY_CALLS: std::sync::Mutex<Vec<String>> = std::sync::Mutex::new(Vec::new());
@@ -1174,10 +1174,10 @@ mod tests {
};
let out = execute_plugin_job(&oak_render::eval::PluginJobRequest {
spec: &spec,
src: oak_render::texture::Texture::wrap_frame(frame),
src: oak_core::texture::Texture::wrap_frame(frame),
})
.expect("the GL-capable render succeeds (no MissingHostFeature purple)");
let oak_render::texture::Texture::Cpu(out_frame) = &out else {
let oak_core::texture::Texture::Cpu(out_frame) = &out else {
panic!("a CPU frame comes back");
};
let mut px = [0f32; 4];
@@ -1191,14 +1191,14 @@ mod tests {
/// 构造一个只含 push-button 参数的最小实例(直接登记进注册表)。
fn instance_with_push_button() -> u64 {
use std::ffi::{c_char, c_void};
use std::sync::atomic::AtomicU32;
use crate::descriptor::EffectDescriptor;
use crate::handle::RefBox;
use crate::host::Plugin;
use crate::param::{ParamDef, ParamInstance, ParamSetInstance};
use crate::descriptor::EffectDescriptor;
use crate::handle::RefBox;
use crate::host::Plugin;
use crate::param::{ParamDef, ParamInstance, ParamSetInstance};
use std::ffi::{c_char, c_void};
use std::sync::atomic::AtomicU32;
unsafe extern "C" fn dummy_entry(
unsafe extern "C" fn dummy_entry(
action: *const c_char,
_: *const c_void,
in_args: *mut c_void,
@@ -1289,14 +1289,14 @@ mod tests {
/// 构造一个带 parametric 参数(维度 2、自定义 range、双维 UI 颜色
/// 已配置)与一个 String 参数的实例(直接登记进注册表)。
fn instance_with_parametric() -> u64 {
use std::ffi::{c_char, c_void};
use std::sync::atomic::AtomicU32;
use crate::descriptor::EffectDescriptor;
use crate::handle::RefBox;
use crate::host::Plugin;
use crate::param::{ParamDef, ParamInstance, ParamSetInstance};
use crate::descriptor::EffectDescriptor;
use crate::handle::RefBox;
use crate::host::Plugin;
use crate::param::{ParamDef, ParamInstance, ParamSetInstance};
use std::ffi::{c_char, c_void};
use std::sync::atomic::AtomicU32;
unsafe extern "C" fn dummy_entry(
unsafe extern "C" fn dummy_entry(
_: *const c_char,
_: *const c_void,
_: *mut c_void,
+30 -30
View File
@@ -17,19 +17,19 @@
//! oakrender 桥(single-lib unification):纹理/帧值类型与渲染调用面。
//!
//! oakrender 的 C ABI 已删除(单库化):纹理是
//! [`oak_render::texture::Texture`](value enum,无句柄),CPU 帧是
//! [`oak_render::texture::Frame`]。本 crate 的 render 驱动与 GL suite
//! [`oak_core::texture::Texture`](value enum,无句柄),CPU 帧是
//! [`oak_core::texture::Frame`]。本 crate 的 render 驱动与 GL suite
//! 直接持值类型:
//!
//! - [`Texture`] = [`oak_render::texture::Texture`](值别名;
//! - [`Texture`] = [`oak_core::texture::Texture`](值别名;
//! clone 即引用语义,drop 自动释放后端 token——原 `texture_free`/
//! `frame_free` 调用面随值模型删除);
//! - [`Frame`] = [`oak_render::texture::Frame`](值别名);
//! - [`Renderer`] = `Arc<dyn oak_render::backend::GpuContextLike>`
//! - [`Frame`] = [`oak_core::texture::Frame`](值别名);
//! - [`Renderer`] = `Arc<dyn oak_core::backend::GpuContextLike>`
//! (渲染器即 oakrender 后端上下文,facade 经
//! [`oak_render::backend::GpuContext::create`] 创建);
//! [`oak_core::backend::GpuContext::create`] 创建);
//! - [`VideoParams`] 直接别名 oakrender 的
//! [`oak_render::frame::VideoParamsPod`](同布局 POD);
//! [`oak_core::frame::VideoParamsPod`](同布局 POD);
//! - 像素格式常量直接别名 [`oak_core::PixelFormat`]。
//!
//! 保留桩(GPU 相关、wgpu 模型无直接 Rust 等价物):
@@ -42,7 +42,7 @@
/// `oakrender_video_params` POD — single-lib unification: aliases the
/// oakrender crate's struct (identical layout;
/// include/render/renderer.h:78).
pub type VideoParams = oak_render::frame::VideoParamsPod;
pub type VideoParams = oak_core::frame::VideoParamsPod;
/// olive::PixelFormat::Format 的 f32 值。
pub const PIXEL_FORMAT_F32: i32 = oak_core::PixelFormat::F32 as i32;
@@ -51,13 +51,13 @@ pub const PIXEL_FORMAT_U8: i32 = oak_core::PixelFormat::U8 as i32;
/// oakrender 渲染器(后端上下文;Arc 共享,GPU 纹理据此 upload/
/// download/blit——无需独立渲染器句柄)。
pub type Renderer = std::sync::Arc<dyn oak_render::backend::GpuContextLike>;
pub type Renderer = std::sync::Arc<dyn oak_core::backend::GpuContextLike>;
/// oakrender 纹理(值型;GPU 或 CPU 包装)。
pub type Texture = oak_render::texture::Texture;
pub type Texture = oak_core::texture::Texture;
/// oakrender CPU 帧(值型)。
pub type Frame = oak_render::texture::Frame;
pub type Frame = oak_core::texture::Frame;
// ---- 桥调用面(值型实现;原 CHandle 桩随单库化重写)----------------------
@@ -138,10 +138,10 @@ pub fn texture_id(_texture: &Texture) -> i32 {
0
}
/// 渲染器是否为 OpenGL 后端([`oak_render::backend::BackendKind::Gl`];
/// 渲染器是否为 OpenGL 后端([`oak_core::backend::BackendKind::Gl`];
/// 原 `renderer_is_open_gl` 的句柄形态改为后端上下文 kind 查询)。
pub fn renderer_is_open_gl(renderer: &Renderer) -> bool {
renderer.kind() == oak_render::backend::BackendKind::Gl
renderer.kind() == oak_core::backend::BackendKind::Gl
}
/// A GL-kind marker context for [`RenderJob::renderer`]. The field's only
@@ -154,22 +154,22 @@ pub fn renderer_is_open_gl(renderer: &Renderer) -> bool {
/// oak-worker, where gl_bridge creates its own offscreen context.
pub struct GlKindMarker;
impl oak_render::backend::GpuContextLike for GlKindMarker {
fn kind(&self) -> oak_render::backend::BackendKind {
oak_render::backend::BackendKind::Gl
impl oak_core::backend::GpuContextLike for GlKindMarker {
fn kind(&self) -> oak_core::backend::BackendKind {
oak_core::backend::BackendKind::Gl
}
fn destroy_texture(&self, _token: u64) {}
fn upload(&self, _token: u64, _frame: &oak_render::texture::Frame) -> oak_render::error::Result<()> {
fn upload(&self, _token: u64, _frame: &oak_core::texture::Frame) -> oak_render::error::Result<()> {
Ok(())
}
fn download(&self, _token: u64) -> oak_render::error::Result<oak_render::texture::Frame> {
Ok(oak_render::texture::Frame::new())
fn download(&self, _token: u64) -> oak_render::error::Result<oak_core::texture::Frame> {
Ok(oak_core::texture::Frame::new())
}
fn blit(
&self,
_src: u64,
_dst: u64,
_processor: Option<&oak_render::color::ColorProcessor>,
&self,
_src: u64,
_dst: u64,
_processor: Option<&oak_core::color::ColorProcessor>,
) -> oak_render::error::Result<()> {
Ok(())
}
@@ -181,9 +181,9 @@ mod tests {
/// 测试渲染器:最小 GpuContextLike 假实现(无 GPU 适配器需求)。
struct FakeGpu;
impl oak_render::backend::GpuContextLike for FakeGpu {
fn kind(&self) -> oak_render::backend::BackendKind {
oak_render::backend::BackendKind::Cpu
impl oak_core::backend::GpuContextLike for FakeGpu {
fn kind(&self) -> oak_core::backend::BackendKind {
oak_core::backend::BackendKind::Cpu
}
fn destroy_texture(&self, _token: u64) {}
fn upload(&self, _token: u64, _frame: &Frame) -> oak_render::error::Result<()> {
@@ -193,10 +193,10 @@ mod tests {
Ok(Frame::new())
}
fn blit(
&self,
_src: u64,
_dst: u64,
_processor: Option<&oak_render::color::ColorProcessor>,
&self,
_src: u64,
_dst: u64,
_processor: Option<&oak_core::color::ColorProcessor>,
) -> oak_render::error::Result<()> {
Ok(())
}
+1 -1
View File
@@ -269,7 +269,7 @@ unsafe extern "C" fn clip_get_property_set(clip: *mut c_void, out: *mut *mut c_v
/// (HS:2003-2049;`getImage` 失败 → Failed)。
///
/// `// TODO(clip)`:fetch_image 待 clip 迁移到
/// `oak_render::texture::Texture` 值模型(当前帧访问为本地桩)。
/// `oak_core::texture::Texture` 值模型(当前帧访问为本地桩)。
unsafe extern "C" fn clip_get_image(
clip: *mut c_void,
time: c_double,
+11 -11
View File
@@ -334,26 +334,26 @@ mod tests {
assert!(gl_ctx().is_none());
// 最小 GpuContextLike 假实现(无 GPU 适配器需求)。
struct FakeGpu;
impl oak_render::backend::GpuContextLike for FakeGpu {
fn kind(&self) -> oak_render::backend::BackendKind {
oak_render::backend::BackendKind::Cpu
impl oak_core::backend::GpuContextLike for FakeGpu {
fn kind(&self) -> oak_core::backend::BackendKind {
oak_core::backend::BackendKind::Cpu
}
fn destroy_texture(&self, _token: u64) {}
fn upload(
&self,
_token: u64,
_frame: &oak_render::texture::Frame,
_frame: &oak_core::texture::Frame,
) -> oak_render::error::Result<()> {
Ok(())
}
fn download(&self, _token: u64) -> oak_render::error::Result<oak_render::texture::Frame> {
Ok(oak_render::texture::Frame::new())
fn download(&self, _token: u64) -> oak_render::error::Result<oak_core::texture::Frame> {
Ok(oak_core::texture::Frame::new())
}
fn blit(
&self,
_src: u64,
_dst: u64,
_processor: Option<&oak_render::color::ColorProcessor>,
&self,
_src: u64,
_dst: u64,
_processor: Option<&oak_core::color::ColorProcessor>,
) -> oak_render::error::Result<()> {
Ok(())
}
@@ -369,7 +369,7 @@ mod tests {
let got = gl_ctx().unwrap();
assert_eq!(
got.renderer.kind(),
oak_render::backend::BackendKind::Cpu
oak_core::backend::BackendKind::Cpu
);
assert!(got.output_texture.is_dummy());
assert_eq!(got.gl_pixel_depth, "OfxBitDepthFloat");