skia_safe/gpu/ganesh/surface_ganesh.rs
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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
use skia_bindings as sb;
use crate::{gpu, prelude::*, surface::BackendHandleAccess, ImageInfo, Surface, SurfaceProps};
/// Returns [`Surface`] on GPU indicated by context. Allocates memory for pixels, based on the
/// width, height, and [`crate::ColorType`] in [`ImageInfo`]. budgeted selects whether allocation
/// for pixels is tracked by context. `image_info` describes the pixel format in
/// [`crate::ColorType`], and transparency in [`crate::AlphaType`], and color matching in
/// [`crate::ColorSpace`].
///
/// `sample_count` requests the number of samples per pixel. Pass zero to disable multi-sample
/// anti-aliasing. The request is rounded up to the next supported count, or rounded down if it is
/// larger than the maximum supported count.
///
/// `surface_origin` pins either the top-left or the bottom-left corner to the origin.
///
/// `should_create_with_mips` hints that [`crate::Image`] returned by [`Surface::image_snapshot`] is
/// mip map.
///
/// * `context` - GPU context
/// * `image_info` - width, height, [`crate::ColorType`], [`crate::AlphaType`],
/// [`crate::ColorSpace`]; width, or height, or both, may be zero
/// * `sample_count` - samples per pixel, or 0 to disable full scene anti-aliasing
/// * `surface_props` - LCD striping orientation and setting for device independent fonts; may be
/// `None`
/// * `should_create_with_mips` - hint that [`Surface`] will host mip map images
///
/// Returns: [`Surface`] if all parameters are valid; otherwise, `None`
#[allow(clippy::too_many_arguments)]
pub fn render_target(
context: &mut gpu::RecordingContext,
budgeted: gpu::Budgeted,
image_info: &ImageInfo,
sample_count: impl Into<Option<usize>>,
surface_origin: impl Into<Option<gpu::SurfaceOrigin>>,
surface_props: Option<&SurfaceProps>,
should_create_with_mips: impl Into<Option<bool>>,
is_protected: impl Into<Option<bool>>,
) -> Option<Surface> {
Surface::from_ptr(unsafe {
sb::C_SkSurfaces_RenderTarget(
context.native_mut(),
budgeted.into_native(),
image_info.native(),
sample_count.into().unwrap_or(0).try_into().unwrap(),
surface_origin
.into()
.unwrap_or(gpu::SurfaceOrigin::BottomLeft),
surface_props.native_ptr_or_null(),
should_create_with_mips.into().unwrap_or(false),
is_protected.into().unwrap_or(false),
)
})
}
/// Wraps a GPU-backed texture into [`Surface`]. Caller must ensure the texture is
/// valid for the lifetime of returned [`Surface`]. If `sample_cnt` greater than zero,
/// creates an intermediate MSAA [`Surface`] which is used for drawing `backend_texture`.
///
/// [`Surface`] is returned if all parameters are valid. `backend_texture` is valid if
/// its pixel configuration agrees with `color_space` and context; for instance, if
/// `backend_texture` has an sRGB configuration, then context must support sRGB,
/// and `color_space` must be present. Further, `backend_texture` width and height must
/// not exceed context capabilities, and the context must be able to support
/// back-end textures.
///
/// * `context` - GPU context
/// * `backend_texture` - texture residing on GPU
/// * `sample_cnt` - samples per pixel, or 0 to disable full scene anti-aliasing
/// * `color_space` - range of colors; may be `None`
/// * `surface_props` - LCD striping orientation and setting for device independent
/// fonts; may be `None`
///
/// Returns: [`Surface`] if all parameters are valid; otherwise, `None`
pub fn wrap_backend_texture(
context: &mut gpu::RecordingContext,
backend_texture: &gpu::BackendTexture,
origin: gpu::SurfaceOrigin,
sample_cnt: impl Into<Option<usize>>,
color_type: crate::ColorType,
color_space: impl Into<Option<crate::ColorSpace>>,
surface_props: Option<&SurfaceProps>,
) -> Option<Surface> {
Surface::from_ptr(unsafe {
sb::C_SkSurfaces_WrapBackendTexture(
context.native_mut(),
backend_texture.native(),
origin,
sample_cnt.into().unwrap_or(0).try_into().unwrap(),
color_type.into_native(),
color_space.into().into_ptr_or_null(),
surface_props.native_ptr_or_null(),
)
})
}
/// Wraps a GPU-backed buffer into [`Surface`]. Caller must ensure `backend_render_target`
/// is valid for the lifetime of returned [`Surface`].
///
/// [`Surface`] is returned if all parameters are valid. `backend_render_target` is valid if
/// its pixel configuration agrees with `color_space` and context; for instance, if
/// `backend_render_target` has an sRGB configuration, then context must support sRGB,
/// and `color_space` must be present. Further, `backend_render_target` width and height must
/// not exceed context capabilities, and the context must be able to support
/// back-end render targets.
///
/// * `context` - GPU context
/// * `backend_render_target` - GPU intermediate memory buffer
/// * `origin` - origin of canvas
/// * `color_type` - type of colors in the buffer
/// * `color_space` - range of colors
/// * `surface_props` - LCD striping orientation and setting for device independent
/// fonts; may be `None`
///
/// Returns: [`Surface`] if all parameters are valid; otherwise, `None`
pub fn wrap_backend_render_target(
context: &mut gpu::RecordingContext,
backend_render_target: &gpu::BackendRenderTarget,
origin: gpu::SurfaceOrigin,
color_type: crate::ColorType,
color_space: impl Into<Option<crate::ColorSpace>>,
surface_props: Option<&SurfaceProps>,
) -> Option<Surface> {
Surface::from_ptr(unsafe {
sb::C_SkSurfaces_WrapBackendRenderTarget(
context.native_mut(),
backend_render_target.native(),
origin,
color_type.into_native(),
color_space.into().into_ptr_or_null(),
surface_props.native_ptr_or_null(),
)
})
}
/// Retrieves the back-end texture. If [`Surface`] has no back-end texture, `None`
/// is returned.
///
/// The returned [`gpu::BackendTexture`] should be discarded if the [`Surface`] is drawn to or deleted.
///
/// Returns: GPU texture reference; `None` on failure
pub fn get_backend_texture(
surface: &mut Surface,
handle_access: BackendHandleAccess,
) -> Option<gpu::BackendTexture> {
unsafe {
let ptr = sb::C_SkSurfaces_GetBackendTexture(surface.native_mut(), handle_access);
gpu::BackendTexture::from_native_if_valid(ptr)
}
}
/// Retrieves the back-end render target. If [`Surface`] has no back-end render target, `None`
/// is returned.
///
/// The returned [`gpu::BackendRenderTarget`] should be discarded if the [`Surface`] is drawn to
/// or deleted.
///
/// Returns: GPU render target reference; `None` on failure
pub fn get_backend_render_target(
surface: &mut Surface,
handle_access: BackendHandleAccess,
) -> Option<gpu::BackendRenderTarget> {
unsafe {
let mut backend_render_target = construct(|rt| sb::C_GrBackendRenderTarget_Construct(rt));
sb::C_SkSurfaces_GetBackendRenderTarget(
surface.native_mut(),
handle_access,
&mut backend_render_target,
);
gpu::BackendRenderTarget::from_native_c_if_valid(backend_render_target)
}
}
/// If a surface is a Ganesh-backed surface, is being drawn with MSAA, and there is a resolve
/// texture, this call will insert a resolve command into the stream of gpu commands. In order
/// for the resolve to actually have an effect, the work still needs to be flushed and submitted
/// to the GPU after recording the resolve command. If a resolve is not supported or the
/// [`Surface`] has no dirty work to resolve, then this call is a no-op.
///
/// This call is most useful when the [`Surface`] is created by wrapping a single sampled gpu
/// texture, but asking Skia to render with MSAA. If the client wants to use the wrapped texture
/// outside of Skia, the only way to trigger a resolve is either to call this command or use
/// [`gpu::DirectContext::flush`].
pub fn resolve_msaa(surface: &mut Surface) {
unsafe { sb::C_SkSurfaces_ResolveMSAA(surface.native_mut()) }
}