skia_safe/gpu/ganesh/
recording_context.rs

1use std::fmt;
2
3use crate::{
4    cpu,
5    gpu::{BackendAPI, BackendFormat, DirectContext, Renderable},
6    prelude::*,
7    recorder::RecorderRef,
8    ColorType, TextureCompressionType,
9};
10use skia_bindings::{self as sb, GrRecordingContext, SkRefCntBase};
11
12pub type RecordingContext = RCHandle<GrRecordingContext>;
13
14impl NativeRefCountedBase for GrRecordingContext {
15    type Base = SkRefCntBase;
16}
17
18impl From<DirectContext> for RecordingContext {
19    fn from(direct_context: DirectContext) -> Self {
20        unsafe { std::mem::transmute(direct_context) }
21    }
22}
23
24impl fmt::Debug for RecordingContext {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        f.debug_struct("RecordingContext")
27            .field("backend", &self.backend())
28            .field("max_texture_size", &self.max_texture_size())
29            .field("max_render_target_size", &self.max_render_target_size())
30            .finish()
31    }
32}
33
34impl RecordingContext {
35    // From GrContext_Base
36    pub fn as_direct_context(&mut self) -> Option<DirectContext> {
37        DirectContext::from_unshared_ptr(unsafe {
38            sb::C_GrRecordingContext_asDirectContext(self.native_mut())
39        })
40    }
41
42    // From GrContext_Base
43    pub fn backend(&self) -> BackendAPI {
44        unsafe { sb::C_GrRecordingContext_backend(self.native()) }
45    }
46
47    pub fn default_backend_format(&self, ct: ColorType, renderable: Renderable) -> BackendFormat {
48        let mut format = BackendFormat::new_invalid();
49        unsafe {
50            sb::C_GrRecordingContext_defaultBackendFormat(
51                self.native(),
52                ct.into_native(),
53                renderable,
54                format.native_mut(),
55            )
56        };
57        format
58    }
59
60    // From GrContext_Base
61    pub fn compressed_backend_format(
62        &self,
63        compression_type: TextureCompressionType,
64    ) -> BackendFormat {
65        let mut format = BackendFormat::new_invalid();
66        unsafe {
67            sb::C_GrRecordingContext_compressedBackendFormat(
68                self.native(),
69                compression_type,
70                format.native_mut(),
71            )
72        }
73        format
74    }
75
76    // TODO: GrContext_Base::threadSafeProxy
77
78    pub fn abandoned(&mut self) -> bool {
79        unsafe { sb::C_GrRecordingContext_abandoned(self.native_mut()) }
80    }
81
82    pub fn color_type_supported_as_surface(&self, color_type: ColorType) -> bool {
83        unsafe {
84            sb::C_GrRecordingContext_colorTypeSupportedAsSurface(
85                self.native(),
86                color_type.into_native(),
87            )
88        }
89    }
90
91    pub fn max_texture_size(&self) -> i32 {
92        unsafe { self.native().maxTextureSize() }
93    }
94
95    pub fn max_render_target_size(&self) -> i32 {
96        unsafe { self.native().maxRenderTargetSize() }
97    }
98
99    pub fn color_type_supported_as_image(&self, color_type: ColorType) -> bool {
100        unsafe {
101            self.native()
102                .colorTypeSupportedAsImage(color_type.into_native())
103        }
104    }
105
106    pub fn supports_protected_content(&self) -> bool {
107        unsafe { self.native().supportsProtectedContent() }
108    }
109
110    pub fn max_surface_sample_count_for_color_type(&self, color_type: ColorType) -> usize {
111        unsafe {
112            sb::C_GrRecordingContext_maxSurfaceSampleCountForColorType(
113                self.native(),
114                color_type.into_native(),
115            )
116        }
117        .try_into()
118        .unwrap()
119    }
120
121    pub fn as_recorder(&mut self) -> &mut RecorderRef {
122        RecorderRef::from_ref_mut(unsafe { &mut *self.native_mut().asRecorder() })
123    }
124
125    pub fn make_cpu_recorder(&mut self) -> cpu::Recorder<'_> {
126        cpu::Recorder::from_owned(unsafe {
127            &mut *sb::C_GrRecordingContext_makeCPURecorder(self.native_mut())
128        })
129    }
130
131    // TODO: Wrap Arenas (if used).
132}