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
} ;
@@ -81,7 +82,9 @@ impl super::Surface {
81
82
delegate : Option < & HalManagedMetalLayerDelegate > ,
82
83
) -> Self {
83
84
let layer = unsafe { Self :: get_metal_layer ( view, delegate) } ;
84
- // SAFETY: The layer is an initialized instance of `CAMetalLayer`.
85
+ let layer = ManuallyDrop :: new ( layer) ;
86
+ // SAFETY: The layer is an initialized instance of `CAMetalLayer`, and
87
+ // we transfer the retain count to `MetalLayer` using `ManuallyDrop`.
85
88
let layer = unsafe { metal:: MetalLayer :: from_ptr ( layer. cast ( ) ) } ;
86
89
let view: * mut Object = msg_send ! [ view. as_ptr( ) , retain] ;
87
90
let view = NonNull :: new ( view) . expect ( "retain should return the same object" ) ;
@@ -108,7 +111,7 @@ impl super::Surface {
108
111
pub ( crate ) unsafe fn get_metal_layer (
109
112
view : NonNull < Object > ,
110
113
delegate : Option < & HalManagedMetalLayerDelegate > ,
111
- ) -> * mut Object {
114
+ ) -> StrongPtr {
112
115
let is_main_thread: BOOL = msg_send ! [ class!( NSThread ) , isMainThread] ;
113
116
if is_main_thread == NO {
114
117
panic ! ( "get_metal_layer cannot be called in non-ui thread." ) ;
@@ -142,7 +145,7 @@ impl super::Surface {
142
145
// render directly into that; after all, the user passed a view
143
146
// with an explicit Metal layer to us, so this is very likely what
144
147
// they expect us to do.
145
- root_layer
148
+ unsafe { StrongPtr :: retain ( root_layer) }
146
149
} else {
147
150
// The view does not have a `CAMetalLayer` as the root layer (this
148
151
// is the default for most views).
@@ -247,7 +250,7 @@ impl super::Surface {
247
250
if let Some ( delegate) = delegate {
248
251
let ( ) = msg_send ! [ new_layer, setDelegate: delegate. 0 ] ;
249
252
}
250
- new_layer
253
+ unsafe { StrongPtr :: new ( new_layer) }
251
254
}
252
255
}
253
256
0 commit comments