33#![ cfg_attr( docsrs, feature( doc_auto_cfg, doc_cfg_hide) , doc( cfg_hide( doc) ) ) ]
44#![ deny( unsafe_op_in_unsafe_fn) ]
55
6+ use core:: ffi:: c_void;
7+ use core:: hash;
8+ use core:: panic:: { RefUnwindSafe , UnwindSafe } ;
69use objc2:: rc:: Retained ;
710use objc2_quartz_core:: CAMetalLayer ;
8- use std:: ffi:: c_void;
911
1012#[ cfg( any( target_os = "macos" , doc) ) ]
1113pub mod appkit;
@@ -14,11 +16,43 @@ pub mod appkit;
1416pub mod uikit;
1517
1618/// A wrapper around [`CAMetalLayer`].
19+ #[ doc( alias = "CAMetalLayer" ) ]
20+ #[ derive( Debug , Clone ) ]
1721pub struct Layer {
1822 layer : Retained < CAMetalLayer > ,
1923 pre_existing : bool ,
2024}
2125
26+ impl PartialEq for Layer {
27+ #[ inline]
28+ fn eq ( & self , other : & Self ) -> bool {
29+ self . layer . eq ( & other. layer )
30+ }
31+ }
32+
33+ impl Eq for Layer { }
34+
35+ impl hash:: Hash for Layer {
36+ #[ inline]
37+ fn hash < H : hash:: Hasher > ( & self , state : & mut H ) {
38+ self . layer . hash ( state) ;
39+ }
40+ }
41+
42+ // SAFETY: `CAMetalLayer` is thread safe, like most things in Core Animation, see:
43+ // https://developer.apple.com/documentation/quartzcore/catransaction/1448267-lock?language=objc
44+ // https://stackoverflow.com/questions/76250226/how-to-render-content-of-calayer-on-a-background-thread
45+ //
46+ // TODO(madsmtm): Move this to `objc2-quartz-core`.
47+ unsafe impl Send for Layer { }
48+ unsafe impl Sync for Layer { }
49+
50+ // Layer methods may panic, but that won't leave the layer in an invalid state.
51+ //
52+ // TODO(madsmtm): Move this to `objc2-quartz-core`.
53+ impl UnwindSafe for Layer { }
54+ impl RefUnwindSafe for Layer { }
55+
2256impl Layer {
2357 /// Get a pointer to the underlying [`CAMetalLayer`]. The pointer is valid
2458 /// for at least as long as the [`Layer`] is valid, but can be extended by
0 commit comments