Skip to main content

ferroui_base/platform/surfaces/
i_framebuffer_platform_surface.rs

1use super::{IPlatformRenderSurface, IPlatformRenderSurfaceRenderTarget};
2use crate::platform::{ILockedFramebuffer, RenderTargetSceneInfo};
3use std::rc::Rc;
4
5/// A surface that is rendered to through a locked framebuffer.
6pub trait IFramebufferPlatformSurface: IPlatformRenderSurface {
7    /// Creates the framebuffer render target of the surface.
8    fn create_framebuffer_render_target(&self) -> Rc<dyn IFramebufferRenderTarget>;
9}
10
11/// Properties of a locked framebuffer.
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
13pub struct FramebufferLockProperties {
14    /// Whether the framebuffer still holds the contents of the previous
15    /// frame.
16    pub previous_frame_is_retained: bool,
17}
18
19/// The render target of a framebuffer surface.
20pub trait IFramebufferRenderTarget: IPlatformRenderSurfaceRenderTarget {
21    /// Provides a framebuffer descriptor for drawing.
22    ///
23    /// The contents of the framebuffer are presented when it is disposed.
24    fn lock(&self, scene_info: &RenderTargetSceneInfo) -> (Rc<dyn ILockedFramebuffer>, FramebufferLockProperties);
25
26    /// Whether the target keeps the frame contents between locks.
27    fn retains_frame_contents(&self) -> bool {
28        false
29    }
30
31    /// Releases the render target.
32    fn dispose(&self);
33}
34
35type LockFramebuffer = dyn Fn(&RenderTargetSceneInfo) -> (Rc<dyn ILockedFramebuffer>, FramebufferLockProperties);
36
37/// A framebuffer render target backed by a function.
38pub struct FuncFramebufferRenderTarget {
39    lock_framebuffer: Box<LockFramebuffer>,
40    retains_frame_contents: bool,
41}
42
43impl FuncFramebufferRenderTarget {
44    /// Creates a target from a function that locks the framebuffer.
45    pub fn new(lock_framebuffer: impl Fn() -> Rc<dyn ILockedFramebuffer> + 'static) -> Self {
46        Self {
47            lock_framebuffer: Box::new(move |_| (lock_framebuffer(), FramebufferLockProperties::default())),
48            retains_frame_contents: false,
49        }
50    }
51
52    /// Creates a target from a function that receives the scene info and
53    /// reports the lock properties.
54    pub fn with_scene_info(
55        lock_framebuffer: impl Fn(&RenderTargetSceneInfo) -> (Rc<dyn ILockedFramebuffer>, FramebufferLockProperties)
56            + 'static,
57        retains_frame_contents: bool,
58    ) -> Self {
59        Self { lock_framebuffer: Box::new(lock_framebuffer), retains_frame_contents }
60    }
61}
62
63impl IPlatformRenderSurfaceRenderTarget for FuncFramebufferRenderTarget {}
64
65impl IFramebufferRenderTarget for FuncFramebufferRenderTarget {
66    fn lock(&self, scene_info: &RenderTargetSceneInfo) -> (Rc<dyn ILockedFramebuffer>, FramebufferLockProperties) {
67        (self.lock_framebuffer)(scene_info)
68    }
69
70    fn retains_frame_contents(&self) -> bool {
71        self.retains_frame_contents
72    }
73
74    fn dispose(&self) {}
75}