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&mut DebugStruct<'_, '_>.debug_struct("Interface")
15 .field(name:"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}
89