Skip to main content

ferroui_base/platform/
i_platform_gpu.rs

1use super::IOptionalFeatureProvider;
2use crate::reactive::IDisposable;
3use std::rc::Rc;
4
5/// Entry point to a platform GPU API (Metal, OpenGL, Vulkan, ...).
6///
7/// The object is shared by threads, as in the reference, where the platform
8/// registers one object that the UI thread finds among its services and the
9/// thread that renders asks for its context. It is therefore held in an
10/// `Arc` and is `Send + Sync`: the platform creates it on its thread, the
11/// compositor hands a handle to the server side, and either side may clone,
12/// call and drop its handle without the other. An implementation holds only
13/// what two threads may share; what belongs to one thread (a display or a
14/// context that is an `Rc`) it keeps bound to that thread.
15///
16/// A context it creates is an object of the thread that asked for it.
17pub trait IPlatformGraphics: Send + Sync {
18    /// Whether the backend renders through one context shared by all
19    /// surfaces.
20    fn uses_shared_context(&self) -> bool;
21
22    /// Creates a new graphics context.
23    fn create_context(&self) -> Rc<dyn IPlatformGraphicsContext>;
24
25    /// The shared graphics context; only valid when
26    /// [`uses_shared_context`](Self::uses_shared_context) is true.
27    fn get_shared_context(&self) -> Rc<dyn IPlatformGraphicsContext>;
28
29    /// Optional features of the graphics API, if the implementation provides
30    /// any.
31    fn as_feature_provider(&self) -> Option<&dyn IOptionalFeatureProvider> {
32        None
33    }
34}
35
36/// Reports whether the platform graphics are ready to be used.
37///
38/// Asked by the thread that renders, at every frame, about a state the
39/// thread of the platform changes: shared by the two as the platform
40/// graphics are (`Send + Sync`). The platform graphics announce the feature
41/// through their optional features as an `Arc<dyn IPlatformGraphicsReadyStateFeature>`
42/// (`try_get_shared` of the optional features).
43pub trait IPlatformGraphicsReadyStateFeature: Send + Sync {
44    fn is_ready(&self) -> bool;
45    fn uses_contexts(&self) -> bool;
46}
47
48const _: fn() = || {
49    // The two contracts the thread of the platform and the thread that
50    // renders hold a handle to.
51    fn assert_send_sync<T: Send + Sync>() {}
52    assert_send_sync::<std::sync::Arc<dyn IPlatformGraphics>>();
53    assert_send_sync::<std::sync::Arc<dyn IPlatformGraphicsReadyStateFeature>>();
54};
55
56/// A context of a platform GPU API.
57pub trait IPlatformGraphicsContext: IOptionalFeatureProvider {
58    /// Whether the context is lost and cannot be used anymore.
59    fn is_lost(&self) -> bool;
60
61    /// Makes the context current. Disposing the result restores the
62    /// previously current context.
63    fn ensure_current(&self) -> Rc<dyn IDisposable>;
64
65    /// Releases the context.
66    fn dispose(&self);
67
68    /// Lets the backend recover the concrete context type.
69    fn as_any(&self) -> &dyn std::any::Any;
70}
71
72/// The graphics context a GPU object belongs to was lost.
73#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
74pub struct PlatformGraphicsContextLostException;
75
76impl std::fmt::Display for PlatformGraphicsContextLostException {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        f.write_str("The platform graphics context was lost.")
79    }
80}
81
82impl std::error::Error for PlatformGraphicsContextLostException {}