1
1
#![ allow( clippy:: let_unit_value) ] // `let () =` being used to constrain result type
2
2
3
3
use std:: ffi:: c_uint;
4
+ use std:: mem:: ManuallyDrop ;
4
5
use std:: ptr:: NonNull ;
5
6
use std:: sync:: Once ;
6
7
use std:: thread;
@@ -14,7 +15,7 @@ use objc::{
14
15
class,
15
16
declare:: ClassDecl ,
16
17
msg_send,
17
- rc:: autoreleasepool,
18
+ rc:: { autoreleasepool, StrongPtr } ,
18
19
runtime:: { Class , Object , Sel , BOOL , NO , YES } ,
19
20
sel, sel_impl,
20
21
} ;
@@ -80,7 +81,9 @@ impl super::Surface {
80
81
delegate : Option < & HalManagedMetalLayerDelegate > ,
81
82
) -> Self {
82
83
let layer = unsafe { Self :: get_metal_layer ( view, delegate) } ;
83
- // SAFETY: The layer is an initialized instance of `CAMetalLayer`.
84
+ let layer = ManuallyDrop :: new ( layer) ;
85
+ // SAFETY: The layer is an initialized instance of `CAMetalLayer`, and
86
+ // we transfer the retain count to `MetalLayer` using `ManuallyDrop`.
84
87
let layer = unsafe { metal:: MetalLayer :: from_ptr ( layer. cast ( ) ) } ;
85
88
let view: * mut Object = msg_send ! [ view. as_ptr( ) , retain] ;
86
89
let view = NonNull :: new ( view) . expect ( "retain should return the same object" ) ;
@@ -107,7 +110,7 @@ impl super::Surface {
107
110
pub ( crate ) unsafe fn get_metal_layer (
108
111
view : NonNull < Object > ,
109
112
delegate : Option < & HalManagedMetalLayerDelegate > ,
110
- ) -> * mut Object {
113
+ ) -> StrongPtr {
111
114
let is_main_thread: BOOL = msg_send ! [ class!( NSThread ) , isMainThread] ;
112
115
if is_main_thread == NO {
113
116
panic ! ( "get_metal_layer cannot be called in non-ui thread." ) ;
@@ -141,7 +144,7 @@ impl super::Surface {
141
144
// render directly into that; after all, the user passed a view
142
145
// with an explicit Metal layer to us, so this is very likely what
143
146
// they expect us to do.
144
- root_layer
147
+ unsafe { StrongPtr :: retain ( root_layer) }
145
148
} else {
146
149
// The view does not have a `CAMetalLayer` as the root layer (this
147
150
// is the default for most views).
@@ -246,7 +249,7 @@ impl super::Surface {
246
249
if let Some ( delegate) = delegate {
247
250
let ( ) = msg_send ! [ new_layer, setDelegate: delegate. 0 ] ;
248
251
}
249
- new_layer
252
+ unsafe { StrongPtr :: new ( new_layer) }
250
253
}
251
254
}
252
255
0 commit comments