1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::gpu::SurfaceOrigin;
use crate::prelude::*;
use crate::{gpu, ColorSpace, ColorType, ISize, ImageInfo, SurfaceProps};
use skia_bindings as sb;
use skia_bindings::{
    SkSurfaceCharacterization, SkSurfaceCharacterization_MipMapped,
    SkSurfaceCharacterization_Textureable, SkSurfaceCharacterization_UsesGLFBO0,
    SkSurfaceCharacterization_VulkanSecondaryCBCompatible,
};

pub type SurfaceCharacterization = Handle<SkSurfaceCharacterization>;

impl NativeDrop for SkSurfaceCharacterization {
    fn drop(&mut self) {
        unsafe { sb::C_SkSurfaceCharacterization_destruct(self) }
    }
}

impl NativeClone for SkSurfaceCharacterization {
    fn clone(&self) -> Self {
        construct(|sc| unsafe { sb::C_SkSurfaceCharacterization_CopyConstruct(sc, self) })
    }
}

impl NativePartialEq for SkSurfaceCharacterization {
    fn eq(&self, rhs: &Self) -> bool {
        unsafe { sb::C_SkSurfaceCharacterization_equals(self, rhs) }
    }
}

impl Default for Handle<SkSurfaceCharacterization> {
    fn default() -> Self {
        SurfaceCharacterization::from_native(construct(|sc| unsafe {
            sb::C_SkSurfaceCharacterization_Construct(sc)
        }))
    }
}

// TODO: there is an alterative for when SK_SUPPORT_GPU is not set, of which the
//       layout differs, should we support that?
impl Handle<SkSurfaceCharacterization> {
    pub fn resized(&self, size: impl Into<ISize>) -> SurfaceCharacterization {
        let size = size.into();
        Self::from_native(unsafe { self.native().createResized(size.width, size.height) })
    }

    // TODO: contextInfo() / refContextInfo()

    pub fn cache_max_resource_bytes(&self) -> usize {
        self.native().fCacheMaxResourceBytes
    }

    pub fn is_valid(&self) -> bool {
        self.image_info().color_type() != ColorType::Unknown
    }

    pub fn image_info(&self) -> &ImageInfo {
        ImageInfo::from_native_ref(unsafe {
            &*sb::C_SkSurfaceCharacterization_imageInfo(self.native())
        })
    }

    pub fn backend_format(&self) -> &gpu::BackendFormat {
        gpu::BackendFormat::from_native_ref(&self.native().fBackendFormat)
    }

    pub fn origin(&self) -> SurfaceOrigin {
        SurfaceOrigin::from_native(self.native().fOrigin)
    }

    pub fn width(&self) -> i32 {
        self.image_info().width()
    }

    pub fn height(&self) -> i32 {
        self.image_info().height()
    }

    pub fn color_type(&self) -> ColorType {
        self.image_info().color_type()
    }

    #[deprecated(since = "0.17.0", note = "use sample_count()")]
    pub fn stencil_count(&self) -> usize {
        self.sample_count()
    }

    pub fn sample_count(&self) -> usize {
        self.native().fSampleCnt.try_into().unwrap()
    }

    pub fn is_textureable(&self) -> bool {
        self.native().fIsTextureable == SkSurfaceCharacterization_Textureable::kYes
    }

    pub fn is_mip_mapped(&self) -> bool {
        self.native().fIsMipMapped == SkSurfaceCharacterization_MipMapped::kYes
    }

    pub fn uses_glfbo0(&self) -> bool {
        self.native().fUsesGLFBO0 == SkSurfaceCharacterization_UsesGLFBO0::kYes
    }

    pub fn vulkan_secondary_cb_compatible(&self) -> bool {
        self.native().fVulkanSecondaryCBCompatible
            == SkSurfaceCharacterization_VulkanSecondaryCBCompatible::kYes
    }

    pub fn is_protected(&self) -> gpu::Protected {
        gpu::Protected::from_native(self.native().fIsProtected)
    }

    pub fn color_space(&self) -> Option<ColorSpace> {
        self.image_info().color_space()
    }

    pub fn surface_props(&self) -> &SurfaceProps {
        SurfaceProps::from_native_ref(&self.native().fSurfaceProps)
    }

    pub fn is_compatible(&self, backend_texture: &gpu::BackendTexture) -> bool {
        unsafe { self.native().isCompatible(backend_texture.native()) }
    }
}