skia_safe/gpu/ganesh/gl/
interface.rs

1use crate::{gpu::gl::Extensions, prelude::*};
2use skia_bindings::{self as sb, GrGLInterface, SkRefCntBase};
3use std::{ffi::c_void, fmt, os::raw};
4
5pub type Interface = RCHandle<GrGLInterface>;
6require_type_equality!(sb::GrGLInterface_INHERITED, sb::SkRefCnt);
7
8impl NativeRefCountedBase for GrGLInterface {
9    type Base = SkRefCntBase;
10}
11
12impl fmt::Debug for Interface {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        f.debug_struct("Interface")
15            .field("extensions", &self.extensions())
16            .finish()
17    }
18}
19
20impl Interface {
21    pub fn new_native() -> Option<Self> {
22        Self::from_ptr(unsafe { sb::C_GrGLInterface_MakeNativeInterface() as _ })
23    }
24
25    pub fn new_load_with<F>(load_fn: F) -> Option<Self>
26    where
27        F: FnMut(&str) -> *const c_void,
28    {
29        Self::from_ptr(unsafe {
30            sb::C_GrGLInterface_MakeAssembledInterface(
31                &load_fn as *const _ as *mut c_void,
32                Some(gl_get_proc_fn_wrapper::<F>),
33            ) as _
34        })
35    }
36
37    pub fn new_load_with_cstr<F>(load_fn: F) -> Option<Self>
38    where
39        F: FnMut(&std::ffi::CStr) -> *const c_void,
40    {
41        Self::from_ptr(unsafe {
42            sb::C_GrGLInterface_MakeAssembledInterface(
43                &load_fn as *const _ as *mut c_void,
44                Some(gl_get_proc_fn_wrapper_cstr::<F>),
45            ) as _
46        })
47    }
48
49    pub fn validate(&self) -> bool {
50        unsafe { self.native().validate() }
51    }
52
53    pub fn extensions(&self) -> &Extensions {
54        Extensions::from_native_ref(unsafe {
55            &*sb::C_GrGLInterface_extensions(self.native_mut_force())
56        })
57    }
58
59    pub fn extensions_mut(&mut self) -> &mut Extensions {
60        Extensions::from_native_ref_mut(unsafe {
61            &mut *sb::C_GrGLInterface_extensions(self.native_mut())
62        })
63    }
64
65    pub fn has_extension(&self, extension: impl AsRef<str>) -> bool {
66        self.extensions().has(extension)
67    }
68}
69
70unsafe extern "C" fn gl_get_proc_fn_wrapper<F>(
71    ctx: *mut c_void,
72    name: *const raw::c_char,
73) -> *const c_void
74where
75    F: FnMut(&str) -> *const c_void,
76{
77    (*(ctx as *mut F))(std::ffi::CStr::from_ptr(name).to_str().unwrap())
78}
79
80unsafe extern "C" fn gl_get_proc_fn_wrapper_cstr<F>(
81    ctx: *mut c_void,
82    name: *const raw::c_char,
83) -> *const c_void
84where
85    F: FnMut(&std::ffi::CStr) -> *const c_void,
86{
87    (*(ctx as *mut F))(std::ffi::CStr::from_ptr(name))
88}