skia_safe/core/
recorder.rs1use 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 }
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)] 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}