1
1
#![ allow( clippy:: let_unit_value) ] // `let () =` being used to constrain result type
2
2
3
- use std:: ffi:: c_uint;
4
3
use std:: ptr:: NonNull ;
5
4
use std:: sync:: Once ;
6
5
use std:: thread;
7
6
8
7
use objc2:: {
9
8
class,
10
9
declare:: ClassBuilder ,
11
- msg_send,
10
+ msg_send, msg_send_id ,
12
11
rc:: { autoreleasepool, Retained } ,
13
12
runtime:: { AnyClass , AnyObject , Bool , ProtocolObject , Sel } ,
14
13
sel, ClassType ,
15
14
} ;
16
- use objc2_foundation:: { CGFloat , CGRect , CGSize , NSObject , NSObjectProtocol } ;
15
+ use objc2_foundation:: { CGFloat , CGRect , CGSize , MainThreadMarker , NSObject , NSObjectProtocol } ;
17
16
use objc2_metal:: MTLTextureType ;
18
- use objc2_quartz_core:: { kCAGravityResize, CALayer , CAMetalDrawable , CAMetalLayer } ;
17
+ use objc2_quartz_core:: {
18
+ kCAGravityResize, CAAutoresizingMask , CALayer , CAMetalDrawable , CAMetalLayer ,
19
+ } ;
19
20
use parking_lot:: { Mutex , RwLock } ;
20
21
21
22
extern "C" fn layer_should_inherit_contents_scale_from_window (
@@ -86,20 +87,19 @@ impl super::Surface {
86
87
///
87
88
/// The `view` must be a valid instance of `NSView` or `UIView`.
88
89
pub ( crate ) unsafe fn get_metal_layer ( view : NonNull < NSObject > ) -> Retained < CAMetalLayer > {
89
- let is_main_thread: bool = msg_send ! [ class!( NSThread ) , isMainThread] ;
90
- if is_main_thread {
90
+ let Some ( _mtm) = MainThreadMarker :: new ( ) else {
91
91
panic ! ( "get_metal_layer cannot be called in non-ui thread." ) ;
92
- }
92
+ } ;
93
93
94
94
// Ensure that the view is layer-backed.
95
95
// Views are always layer-backed in UIKit.
96
96
#[ cfg( target_os = "macos" ) ]
97
97
let ( ) = msg_send ! [ view. as_ptr( ) , setWantsLayer: true ] ;
98
98
99
- let root_layer: * mut CALayer = msg_send ! [ view. as_ptr( ) , layer] ;
99
+ let root_layer: Option < Retained < CALayer > > = msg_send_id ! [ view. as_ptr( ) , layer] ;
100
100
// `-[NSView layer]` can return `NULL`, while `-[UIView layer]` should
101
101
// always be available.
102
- assert ! ( ! root_layer. is_null ( ) , "failed making the view layer-backed" ) ;
102
+ let root_layer = root_layer . expect ( "failed making the view layer-backed" ) ;
103
103
104
104
// NOTE: We explicitly do not touch properties such as
105
105
// `layerContentsPlacement`, `needsDisplayOnBoundsChange` and
@@ -109,8 +109,7 @@ impl super::Surface {
109
109
// `NSViewLayerContentsRedrawDuringViewResize`, which allows the view
110
110
// to receive `drawRect:`/`updateLayer` calls).
111
111
112
- let is_metal_layer: bool = msg_send ! [ root_layer, isKindOfClass: class!( CAMetalLayer ) ] ;
113
- if is_metal_layer {
112
+ if root_layer. isKindOfClass ( CAMetalLayer :: class ( ) ) {
114
113
// The view has a `CAMetalLayer` as the root layer, which can
115
114
// happen for example if user overwrote `-[NSView layerClass]` or
116
115
// the view is `MTKView`.
@@ -119,7 +118,7 @@ impl super::Surface {
119
118
// render directly into that; after all, the user passed a view
120
119
// with an explicit Metal layer to us, so this is very likely what
121
120
// they expect us to do.
122
- unsafe { Retained :: retain ( root_layer . cast ( ) ) . unwrap ( ) }
121
+ unsafe { Retained :: cast ( root_layer ) }
123
122
} else {
124
123
// The view does not have a `CAMetalLayer` as the root layer (this
125
124
// is the default for most views).
@@ -188,8 +187,8 @@ impl super::Surface {
188
187
// we're going to do.
189
188
190
189
// Create a new sublayer.
191
- let new_layer: * mut CAMetalLayer = msg_send ! [ class! ( CAMetalLayer ) , new] ;
192
- let ( ) = msg_send ! [ root_layer, addSublayer: new_layer] ;
190
+ let new_layer = CAMetalLayer :: new ( ) ;
191
+ root_layer. addSublayer ( & new_layer) ;
193
192
194
193
// Automatically resize the sublayer's frame to match the
195
194
// superlayer's bounds.
@@ -204,15 +203,15 @@ impl super::Surface {
204
203
// We _could_ also let `configure` set the `bounds` size, however
205
204
// that would be inconsistent with using the root layer directly
206
205
// (as we may do, see above).
207
- let width_sizable = 1 << 1 ; // kCALayerWidthSizable
208
- let height_sizable = 1 << 4 ; // kCALayerHeightSizable
209
- let mask : c_uint = width_sizable | height_sizable ;
210
- let ( ) = msg_send ! [ new_layer , setAutoresizingMask : mask ] ;
206
+ new_layer . setAutoresizingMask (
207
+ CAAutoresizingMask :: kCALayerWidthSizable
208
+ | CAAutoresizingMask :: kCALayerHeightSizable ,
209
+ ) ;
211
210
212
211
// Specify the relative size that the auto resizing mask above
213
212
// will keep (i.e. tell it to fill out its superlayer).
214
- let frame: CGRect = msg_send ! [ root_layer, bounds] ;
215
- let ( ) = msg_send ! [ new_layer, setFrame: frame] ;
213
+ let frame = root_layer. bounds ( ) ;
214
+ new_layer. setFrame ( frame) ;
216
215
217
216
// The gravity to use when the layer's `drawableSize` isn't the
218
217
// same as the bounds rectangle.
@@ -225,26 +224,25 @@ impl super::Surface {
225
224
// Unfortunately, it also makes it harder to see changes to
226
225
// `width` and `height` in `configure`. When debugging resize
227
226
// issues, swap this for `kCAGravityTopLeft` instead.
228
- let _ : ( ) = msg_send ! [ new_layer, setContentsGravity: unsafe { kCAGravityResize } ] ;
227
+ new_layer. setContentsGravity ( unsafe { kCAGravityResize } ) ;
229
228
230
229
// Set initial scale factor of the layer. This is kept in sync by
231
230
// `configure` (on UIKit), and the delegate below (on AppKit).
232
- let scale_factor: CGFloat = msg_send ! [ root_layer, contentsScale] ;
233
- let ( ) = msg_send ! [ new_layer, setContentsScale: scale_factor] ;
231
+ let scale_factor = root_layer. contentsScale ( ) ;
232
+ new_layer. setContentsScale ( scale_factor) ;
234
233
235
234
let delegate = HalManagedMetalLayerDelegate :: new ( ) ;
236
- let ( ) = msg_send ! [ new_layer, setDelegate: delegate. 0 ] ;
235
+ new_layer. setDelegate ( std :: mem :: transmute ( delegate. 0 ) ) ;
237
236
238
- unsafe { Retained :: from_raw ( new_layer) . unwrap ( ) }
237
+ new_layer
239
238
}
240
239
}
241
240
242
241
pub ( super ) fn dimensions ( & self ) -> wgt:: Extent3d {
243
- let ( size, scale) : ( CGSize , CGFloat ) = unsafe {
244
- let render_layer_borrow = self . render_layer . lock ( ) ;
245
- let render_layer = render_layer_borrow. as_ref ( ) ;
246
- let bounds: CGRect = msg_send ! [ render_layer, bounds] ;
247
- let contents_scale: CGFloat = msg_send ! [ render_layer, contentsScale] ;
242
+ let ( size, scale) : ( CGSize , CGFloat ) = {
243
+ let render_layer = self . render_layer . lock ( ) ;
244
+ let bounds = render_layer. bounds ( ) ;
245
+ let contents_scale = render_layer. contentsScale ( ) ;
248
246
( bounds. size , contents_scale)
249
247
} ;
250
248
0 commit comments