skia_safe/gpu/ganesh/gl/
interface.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use crate::{gpu::gl::Extensions, prelude::*};
use skia_bindings::{self as sb, GrGLInterface, SkRefCntBase};
use std::{ffi::c_void, fmt, os::raw};

pub type Interface = RCHandle<GrGLInterface>;
require_type_equality!(sb::GrGLInterface_INHERITED, sb::SkRefCnt);

impl NativeRefCountedBase for GrGLInterface {
    type Base = SkRefCntBase;
}

impl fmt::Debug for Interface {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Interface")
            .field("extensions", &self.extensions())
            .finish()
    }
}

impl Interface {
    pub fn new_native() -> Option<Self> {
        Self::from_ptr(unsafe { sb::C_GrGLInterface_MakeNativeInterface() as _ })
    }

    pub fn new_load_with<F>(load_fn: F) -> Option<Self>
    where
        F: FnMut(&str) -> *const c_void,
    {
        Self::from_ptr(unsafe {
            sb::C_GrGLInterface_MakeAssembledInterface(
                &load_fn as *const _ as *mut c_void,
                Some(gl_get_proc_fn_wrapper::<F>),
            ) as _
        })
    }

    pub fn new_load_with_cstr<F>(load_fn: F) -> Option<Self>
    where
        F: FnMut(&std::ffi::CStr) -> *const c_void,
    {
        Self::from_ptr(unsafe {
            sb::C_GrGLInterface_MakeAssembledInterface(
                &load_fn as *const _ as *mut c_void,
                Some(gl_get_proc_fn_wrapper_cstr::<F>),
            ) as _
        })
    }

    pub fn validate(&self) -> bool {
        unsafe { self.native().validate() }
    }

    pub fn extensions(&self) -> &Extensions {
        Extensions::from_native_ref(unsafe {
            &*sb::C_GrGLInterface_extensions(self.native_mut_force())
        })
    }

    pub fn extensions_mut(&mut self) -> &mut Extensions {
        Extensions::from_native_ref_mut(unsafe {
            &mut *sb::C_GrGLInterface_extensions(self.native_mut())
        })
    }

    pub fn has_extension(&self, extension: impl AsRef<str>) -> bool {
        self.extensions().has(extension)
    }
}

unsafe extern "C" fn gl_get_proc_fn_wrapper<F>(
    ctx: *mut c_void,
    name: *const raw::c_char,
) -> *const c_void
where
    F: FnMut(&str) -> *const c_void,
{
    (*(ctx as *mut F))(std::ffi::CStr::from_ptr(name).to_str().unwrap())
}

unsafe extern "C" fn gl_get_proc_fn_wrapper_cstr<F>(
    ctx: *mut c_void,
    name: *const raw::c_char,
) -> *const c_void
where
    F: FnMut(&std::ffi::CStr) -> *const c_void,
{
    (*(ctx as *mut F))(std::ffi::CStr::from_ptr(name))
}