Skip to main content

skia_safe/gpu/ganesh/
recording_context.rs

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