skia_safe/core/
recorder.rs

1use std::{cell::UnsafeCell, fmt};
2
3use crate::prelude::*;
4use skia_bindings::{self as sb, SkRecorder};
5
6pub type Type = skia_bindings::SkRecorder_Type;
7variant_name!(Type::CPU);
8
9pub trait Recorder: sealed::AsRecorderRef + fmt::Debug {
10    fn ty(&self) -> Type;
11    // TODO:
12    // fn cpu_recorder(&mut self) -> &mut cpu::Recorder;
13}
14
15pub(crate) mod sealed {
16    pub trait AsRecorderRef {
17        fn as_recorder_ref(&mut self) -> &mut super::RecorderRef;
18    }
19}
20
21#[repr(transparent)]
22pub struct RecorderRef(UnsafeCell<SkRecorder>);
23
24impl NativeAccess for RecorderRef {
25    type Native = SkRecorder;
26
27    fn native(&self) -> &SkRecorder {
28        unsafe { &*self.0.get() }
29    }
30
31    fn native_mut(&mut self) -> &mut SkRecorder {
32        unsafe { &mut (*self.0.get()) }
33    }
34}
35
36impl fmt::Debug for RecorderRef {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        f.debug_struct("Recorder")
39            .field("type", &self.ty())
40            .finish()
41    }
42}
43
44impl RecorderRef {
45    #[allow(unused)] // ... in non-gpu builds.
46    pub(crate) fn from_ref_mut(native: &mut SkRecorder) -> &mut Self {
47        unsafe { transmute_ref_mut(native) }
48    }
49}
50
51impl Recorder for RecorderRef {
52    fn ty(&self) -> Type {
53        let mut ty = Type::CPU;
54        unsafe {
55            sb::C_SkRecorder_type(self.native(), &mut ty);
56        }
57        ty
58    }
59}
60
61impl sealed::AsRecorderRef for RecorderRef {
62    fn as_recorder_ref(&mut self) -> &mut RecorderRef {
63        self
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::{Recorder, RecorderRef};
70
71    #[allow(deref_nullptr)]
72    fn _passing_the_different_kinds_of_recorder_compiles() {
73        test(None);
74        test(Some(owned_recorder()));
75        test(Some(cpu_recorder()));
76
77        fn test(_recorder: Option<&mut dyn Recorder>) {}
78
79        fn owned_recorder() -> &'static mut RecorderRef {
80            unsafe { &mut *std::ptr::null_mut() }
81        }
82
83        fn cpu_recorder() -> &'static mut crate::cpu::Recorder<'static> {
84            unsafe { &mut *std::ptr::null_mut() }
85        }
86    }
87}