skia_safe/gpu/ganesh/
yuva_backend_textures.rsuse crate::gpu::{BackendFormat, BackendTexture, Mipmapped, SurfaceOrigin};
use crate::{prelude::*, YUVAInfo, YUVColorSpace};
use skia_bindings::{self as sb, GrYUVABackendTextureInfo, GrYUVABackendTextures};
use std::{fmt, iter};
pub type YUVABackendTextureInfo = Handle<GrYUVABackendTextureInfo>;
unsafe_send_sync!(YUVABackendTextureInfo);
impl NativeDrop for GrYUVABackendTextureInfo {
fn drop(&mut self) {
unsafe { sb::C_GrYUVABackendTextureInfo_destruct(self) }
}
}
impl NativeClone for GrYUVABackendTextureInfo {
fn clone(&self) -> Self {
construct(|cloned| unsafe { sb::C_GrYUVABackendTextureInfo_CopyConstruct(cloned, self) })
}
}
impl NativePartialEq for GrYUVABackendTextureInfo {
fn eq(&self, rhs: &Self) -> bool {
unsafe { sb::C_GrYUVABackendTextureInfo_equals(self, rhs) }
}
}
impl fmt::Debug for YUVABackendTextureInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("YUVABackendTextureInfo")
.field("yuva_info", &self.yuva_info())
.field("yuv_color_space", &self.yuv_color_space())
.field("mipmapped", &self.mipmapped())
.field("texture_origin", &self.texture_origin())
.field("plane_formats", &self.plane_formats())
.finish()
}
}
impl YUVABackendTextureInfo {
pub const MAX_PLANES: usize = YUVAInfo::MAX_PLANES;
pub fn new(
info: &YUVAInfo,
formats: &[BackendFormat],
mip_mapped: Mipmapped,
origin: SurfaceOrigin,
) -> Option<Self> {
if formats.len() != info.num_planes() {
return None;
}
let mut formats = formats.to_vec();
formats.extend(
iter::repeat_with(BackendFormat::new_invalid).take(Self::MAX_PLANES - formats.len()),
);
assert_eq!(formats.len(), Self::MAX_PLANES);
let n = unsafe {
GrYUVABackendTextureInfo::new(info.native(), formats[0].native(), mip_mapped, origin)
};
Self::native_is_valid(&n).if_true_then_some(|| Self::from_native_c(n))
}
pub fn yuva_info(&self) -> &YUVAInfo {
YUVAInfo::from_native_ref(&self.native().fYUVAInfo)
}
pub fn yuv_color_space(&self) -> YUVColorSpace {
self.yuva_info().yuv_color_space()
}
pub fn mipmapped(&self) -> Mipmapped {
self.native().fMipmapped
}
pub fn texture_origin(&self) -> SurfaceOrigin {
self.native().fTextureOrigin
}
pub fn num_planes(&self) -> usize {
self.yuva_info().num_planes()
}
pub fn plane_format(&self, i: usize) -> Option<&BackendFormat> {
(i < self.num_planes()).if_true_some(BackendFormat::from_native_ref(
&self.native().fPlaneFormats[i],
))
}
pub fn plane_formats(&self) -> &[BackendFormat] {
unsafe {
let formats = BackendFormat::from_native_ref(&self.native().fPlaneFormats[0]);
safer::from_raw_parts(formats, self.num_planes())
}
}
pub(crate) fn native_is_valid(info: &GrYUVABackendTextureInfo) -> bool {
YUVAInfo::native_is_valid(&info.fYUVAInfo)
}
}
pub type YUVABackendTextures = Handle<GrYUVABackendTextures>;
unsafe_send_sync!(YUVABackendTextures);
impl NativeDrop for GrYUVABackendTextures {
fn drop(&mut self) {
unsafe { sb::C_GrYUVABackendTextures_destruct(self) }
}
}
impl fmt::Debug for YUVABackendTextures {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("YUVABackendTextures")
.field("yuva_info", &self.yuva_info())
.field("texture_origin", &self.texture_origin())
.field("textures", &self.textures())
.finish()
}
}
impl YUVABackendTextures {
pub fn new(
info: &YUVAInfo,
textures: &[BackendTexture],
texture_origin: SurfaceOrigin,
) -> Option<Self> {
if textures.len() != info.num_planes() {
return None;
}
let new_invalid = BackendTexture::new_invalid();
let new_invalid_ptr = new_invalid.native() as *const _;
let mut texture_handles = textures
.iter()
.map(|tex| tex.native() as *const _)
.collect::<Vec<_>>();
texture_handles
.extend(iter::repeat(new_invalid_ptr).take(YUVAInfo::MAX_PLANES - textures.len()));
assert_eq!(texture_handles.len(), YUVAInfo::MAX_PLANES);
let n = construct(|cloned| unsafe {
sb::C_GrYUVABackendTextures_construct(
cloned,
info.native(),
texture_handles.as_ptr(),
texture_origin,
)
});
Self::native_is_valid(&n).if_true_then_some(|| Self::from_native_c(n))
}
pub fn textures(&self) -> Vec<BackendTexture> {
unsafe {
let textures_ptr = sb::C_GrYUVABackendTextures_textures(self.native());
let textures = safer::from_raw_parts(textures_ptr, self.num_planes());
textures
.iter()
.map(|native_texture_ref| {
BackendTexture::from_ptr(sb::C_GrBackendTexture_Clone(native_texture_ref))
.unwrap()
})
.collect()
}
}
pub fn texture(&self, i: usize) -> Option<BackendTexture> {
self.textures().get(i).cloned()
}
pub fn yuva_info(&self) -> &YUVAInfo {
YUVAInfo::from_native_ref(unsafe { &*sb::C_GrYUVABackendTextures_yuvaInfo(self.native()) })
}
pub fn num_planes(&self) -> usize {
self.yuva_info().num_planes()
}
pub fn texture_origin(&self) -> SurfaceOrigin {
unsafe { sb::C_GrYUVABackendTextures_textureOrigin(self.native()) }
}
pub(crate) fn native_is_valid(n: &GrYUVABackendTextures) -> bool {
YUVAInfo::native_is_valid(unsafe { &*sb::C_GrYUVABackendTextures_yuvaInfo(n) })
}
}