capi: get rid of Box
and use NonNull
pointers
This commit is contained in:
parent
4946bfc0dd
commit
a00c4e1d88
6 changed files with 68 additions and 36 deletions
|
@ -109,7 +109,7 @@ libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t *preset
|
||||||
* Initialize the OpenGL Context for librashader.
|
* Initialize the OpenGL Context for librashader.
|
||||||
*
|
*
|
||||||
* ## Safety
|
* ## Safety
|
||||||
* Attempting to create a filter chain before initializing the GL context is undefined behaviour.
|
* Attempting to create a filter chain will fail.
|
||||||
*
|
*
|
||||||
* Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
* Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
||||||
* chain objects, and drawing with them causes immediate undefined behaviour.
|
* chain objects, and drawing with them causes immediate undefined behaviour.
|
||||||
|
@ -127,7 +127,7 @@ libra_error_t libra_gl_init_context(gl_loader_t loader);
|
||||||
* - `options` must be either null, or valid and aligned.
|
* - `options` must be either null, or valid and aligned.
|
||||||
* - `out` may be either null or uninitialized, but must be aligned.
|
* - `out` may be either null or uninitialized, but must be aligned.
|
||||||
*/
|
*/
|
||||||
libra_error_t libra_gl_create_filter_chain(libra_shader_preset_t *preset,
|
libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t *preset,
|
||||||
const struct filter_chain_gl_opt_t *options,
|
const struct filter_chain_gl_opt_t *options,
|
||||||
libra_gl_filter_chain_t *out);
|
libra_gl_filter_chain_t *out);
|
||||||
|
|
||||||
|
@ -138,6 +138,8 @@ libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain,
|
||||||
struct libra_draw_framebuffer_gl_t out,
|
struct libra_draw_framebuffer_gl_t out,
|
||||||
const float *mvp);
|
const float *mvp);
|
||||||
|
|
||||||
|
libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t *chain);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::mem::ManuallyDrop;
|
use std::ptr::NonNull;
|
||||||
use librashader::presets::ShaderPreset;
|
use librashader::presets::ShaderPreset;
|
||||||
use crate::error::LibrashaderError;
|
use crate::error::LibrashaderError;
|
||||||
|
|
||||||
pub type libra_shader_preset_t = ManuallyDrop<Option<Box<ShaderPreset>>>;
|
pub type libra_shader_preset_t = Option<NonNull<ShaderPreset>>;
|
||||||
pub type libra_error_t = *const LibrashaderError;
|
pub type libra_error_t = *const LibrashaderError;
|
||||||
|
|
||||||
// #[cfg(feature = "runtime-opengl")]
|
// #[cfg(feature = "runtime-opengl")]
|
||||||
pub type libra_gl_filter_chain_t = ManuallyDrop<Option<Box<librashader::runtime::gl::FilterChainGL>>>;
|
pub type libra_gl_filter_chain_t = Option<NonNull<librashader::runtime::gl::FilterChainGL>>;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct libra_viewport_t {
|
pub struct libra_viewport_t {
|
||||||
|
|
|
@ -49,6 +49,24 @@ macro_rules! assert_some {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_some_ptr {
|
||||||
|
($value:ident) => {
|
||||||
|
if $value.is_none() {
|
||||||
|
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
|
||||||
|
}
|
||||||
|
|
||||||
|
let $value = unsafe { $value.as_ref().unwrap().as_ref() };
|
||||||
|
};
|
||||||
|
(mut $value:ident) => {
|
||||||
|
if $value.is_none() {
|
||||||
|
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
|
||||||
|
}
|
||||||
|
|
||||||
|
let $value = unsafe { $value.as_mut().unwrap().as_mut() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) use assert_non_null;
|
pub(crate) use assert_non_null;
|
||||||
pub(crate) use assert_some;
|
pub(crate) use assert_some;
|
||||||
|
pub(crate) use assert_some_ptr;
|
||||||
use crate::ctypes::libra_error_t;
|
use crate::ctypes::libra_error_t;
|
|
@ -1,14 +1,14 @@
|
||||||
use std::ffi::{c_char, CStr, CString, OsStr};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use std::mem::{ManuallyDrop, MaybeUninit};
|
use std::mem::{MaybeUninit};
|
||||||
use std::panic::catch_unwind;
|
|
||||||
use std::path::Path;
|
|
||||||
use librashader::presets::ShaderPreset;
|
use librashader::presets::ShaderPreset;
|
||||||
use crate::ffi::ffi_body;
|
use crate::ffi::ffi_body;
|
||||||
use crate::ctypes::{libra_error_t, libra_shader_preset_t};
|
use crate::ctypes::{libra_error_t, libra_shader_preset_t};
|
||||||
use crate::error::{assert_non_null, assert_some, LibrashaderError};
|
use crate::error::{assert_non_null, assert_some, assert_some_ptr, LibrashaderError};
|
||||||
use safer_ffi::prelude::*;
|
use std::ptr::NonNull;
|
||||||
use safer_ffi::ffi_export;
|
|
||||||
use safer_ffi::char_p::char_p_ref as CStrRef;
|
// use safer_ffi::prelude::*;
|
||||||
|
// use safer_ffi::ffi_export;
|
||||||
|
// use safer_ffi::char_p::char_p_ref as CStrRef;
|
||||||
|
|
||||||
// extern_fn! {
|
// extern_fn! {
|
||||||
// /// SAFETY:
|
// /// SAFETY:
|
||||||
|
@ -50,7 +50,7 @@ pub unsafe extern "C" fn libra_load_preset(filename: *const c_char, out: *mut Ma
|
||||||
let preset = ShaderPreset::try_parse(filename)?;
|
let preset = ShaderPreset::try_parse(filename)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
out.write(MaybeUninit::new(ManuallyDrop::new(Some(Box::new(preset)))))
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(preset)))))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,8 @@ pub unsafe extern "C" fn libra_preset_free(preset: *mut libra_shader_preset_t) -
|
||||||
assert_non_null!(preset);
|
assert_non_null!(preset);
|
||||||
unsafe {
|
unsafe {
|
||||||
let preset_ptr = &mut *preset;
|
let preset_ptr = &mut *preset;
|
||||||
ManuallyDrop::drop(preset_ptr);
|
let preset = preset_ptr.take();
|
||||||
preset.write(ManuallyDrop::new(None));
|
drop(Box::from_raw(preset.unwrap().as_ptr()));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,7 @@ pub unsafe extern "C" fn libra_preset_set_param(preset: *mut libra_shader_preset
|
||||||
};
|
};
|
||||||
|
|
||||||
let name = name.to_str()?;
|
let name = name.to_str()?;
|
||||||
assert_some!(preset);
|
assert_some_ptr!(mut preset);
|
||||||
let preset = preset.as_mut().unwrap();
|
|
||||||
|
|
||||||
if let Some(param) = preset.parameters.iter_mut().find(|c| c.name == name) {
|
if let Some(param) = preset.parameters.iter_mut().find(|c| c.name == name) {
|
||||||
param.value = value
|
param.value = value
|
||||||
|
@ -102,8 +101,7 @@ pub unsafe extern "C" fn libra_preset_get_param(preset: *mut libra_shader_preset
|
||||||
};
|
};
|
||||||
|
|
||||||
let name = name.to_str()?;
|
let name = name.to_str()?;
|
||||||
assert_some!(preset);
|
assert_some_ptr!(preset);
|
||||||
let preset = preset.as_ref().unwrap();
|
|
||||||
|
|
||||||
if let Some(param) = preset.parameters.iter().find(|c| c.name == name) {
|
if let Some(param) = preset.parameters.iter().find(|c| c.name == name) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -133,8 +131,7 @@ pub type PFN_lbr_preset_get_runtime_param_names = unsafe extern "C" fn (*mut lib
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn libra_preset_get_runtime_param_names(preset: *mut libra_shader_preset_t, mut value: MaybeUninit<*mut *const c_char>) -> libra_error_t {
|
pub unsafe extern "C" fn libra_preset_get_runtime_param_names(preset: *mut libra_shader_preset_t, mut value: MaybeUninit<*mut *const c_char>) -> libra_error_t {
|
||||||
ffi_body!(|preset | {
|
ffi_body!(|preset | {
|
||||||
assert_some!(preset);
|
assert_some_ptr!(preset);
|
||||||
let preset = preset.as_ref().unwrap();
|
|
||||||
|
|
||||||
let iter = librashader::presets::get_parameter_meta(preset)?;
|
let iter = librashader::presets::get_parameter_meta(preset)?;
|
||||||
let mut c_strings = Vec::new();
|
let mut c_strings = Vec::new();
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
use std::ffi::{c_char, c_void, CString};
|
use std::ffi::{c_char, c_void, CString};
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use crate::ctypes::{libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t, libra_viewport_t};
|
use crate::ctypes::{libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t, libra_viewport_t};
|
||||||
use crate::error::{assert_non_null, assert_some, LibrashaderError};
|
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
|
||||||
use crate::ffi::ffi_body;
|
use crate::ffi::ffi_body;
|
||||||
use std::mem::ManuallyDrop;
|
use std::ptr::NonNull;
|
||||||
use std::panic::catch_unwind;
|
|
||||||
use librashader::runtime::FilterChain;
|
use librashader::runtime::FilterChain;
|
||||||
use librashader::runtime::gl::{Framebuffer, GLImage, Viewport};
|
use librashader::runtime::gl::{GLImage, Viewport};
|
||||||
|
|
||||||
pub use librashader::runtime::gl::options::FilterChainOptionsGL;
|
pub use librashader::runtime::gl::options::FilterChainOptionsGL;
|
||||||
use librashader::Size;
|
use librashader::Size;
|
||||||
|
@ -41,27 +40,28 @@ pub unsafe extern "C" fn libra_gl_init_context(loader: gl_loader_t) -> libra_err
|
||||||
/// - `options` must be either null, or valid and aligned.
|
/// - `options` must be either null, or valid and aligned.
|
||||||
/// - `out` may be either null or uninitialized, but must be aligned.
|
/// - `out` may be either null or uninitialized, but must be aligned.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn libra_gl_create_filter_chain(preset: *mut libra_shader_preset_t,
|
pub unsafe extern "C" fn libra_gl_filter_chain_create(preset: *mut libra_shader_preset_t,
|
||||||
options: *const FilterChainOptionsGL,
|
options: *const FilterChainOptionsGL,
|
||||||
out: *mut MaybeUninit<libra_gl_filter_chain_t>) -> libra_error_t {
|
out: *mut MaybeUninit<libra_gl_filter_chain_t>) -> libra_error_t {
|
||||||
ffi_body!({
|
ffi_body!({
|
||||||
assert_non_null!(preset);
|
assert_non_null!(preset);
|
||||||
let preset_ptr = unsafe {
|
let preset = unsafe {
|
||||||
&mut *preset
|
let preset_ptr = &mut *preset;
|
||||||
|
let preset = preset_ptr.take();
|
||||||
|
Box::from_raw(preset.unwrap().as_ptr())
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_some!(preset_ptr);
|
|
||||||
let preset = preset_ptr.take().unwrap();
|
|
||||||
let options = if options.is_null() {
|
let options = if options.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(unsafe { &*options })
|
Some(unsafe { &*options })
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let chain = librashader::runtime::gl::FilterChainGL::load_from_preset(*preset, options)?;
|
let chain = librashader::runtime::gl::FilterChainGL::load_from_preset(*preset, options)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
out.write(MaybeUninit::new(ManuallyDrop::new(Some(Box::new(chain)))))
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(chain)))))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -104,8 +104,7 @@ pub unsafe extern "C" fn libra_gl_filter_chain_frame(chain: *mut libra_gl_filter
|
||||||
|
|
||||||
) -> libra_error_t {
|
) -> libra_error_t {
|
||||||
ffi_body!(mut |chain| {
|
ffi_body!(mut |chain| {
|
||||||
assert_some!(chain);
|
assert_some_ptr!(mut chain);
|
||||||
let chain = chain.as_mut().unwrap();
|
|
||||||
|
|
||||||
let image: GLImage = image.into();
|
let image: GLImage = image.into();
|
||||||
let viewport = Viewport {
|
let viewport = Viewport {
|
||||||
|
@ -119,3 +118,14 @@ pub unsafe extern "C" fn libra_gl_filter_chain_frame(chain: *mut libra_gl_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn libra_gl_filter_chain_free(chain: *mut libra_gl_filter_chain_t) -> libra_error_t {
|
||||||
|
ffi_body!({
|
||||||
|
assert_non_null!(chain);
|
||||||
|
unsafe {
|
||||||
|
let chain_ptr = &mut *chain;
|
||||||
|
let chain = chain_ptr.take();
|
||||||
|
drop(Box::from_raw(chain.unwrap().as_ptr()))
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
|
@ -11,10 +11,15 @@ int main()
|
||||||
std::cout << std::filesystem::current_path() << std::endl;
|
std::cout << std::filesystem::current_path() << std::endl;
|
||||||
libra_shader_preset_t preset;
|
libra_shader_preset_t preset;
|
||||||
auto error = libra_load_preset("../../../slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", &preset);
|
auto error = libra_load_preset("../../../slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", &preset);
|
||||||
|
if (error != NULL) {
|
||||||
|
std::cout << "error happened\n";
|
||||||
|
}
|
||||||
libra_preset_print(&preset);
|
libra_preset_print(&preset);
|
||||||
libra_gl_filter_chain_t chain;
|
libra_gl_filter_chain_t chain;
|
||||||
libra_gl_create_filter_chain(&preset, NULL, &chain);
|
error = libra_gl_create_filter_chain(&preset, NULL, &chain);
|
||||||
|
if (error != NULL) {
|
||||||
|
std::cout << "error happened\n";
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue