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 {}