Skip to content

Commit 91c1904

Browse files
committed
Avoid an explicit CATransaction commit
These are expensive, and the layer should be able to figure out the timing of when to render by itself.
1 parent c72c4a8 commit 91c1904

File tree

3 files changed

+16
-10
lines changed

3 files changed

+16
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22

3+
- Improved performance when presenting on macOS.
34
- Update to `objc2` 0.6.0.
45
- Bump MSRV to Rust 1.71.
56

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ objc2-foundation = { version = "0.3.1", default-features = false, features = [
102102
"NSString",
103103
"NSThread",
104104
"NSValue",
105+
"NSNull",
105106
] }
106107
objc2-quartz-core = { version = "0.3.1", default-features = false, features = [
107108
"std",

src/backends/cg.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ use crate::backend_interface::*;
33
use crate::error::InitError;
44
use crate::{Rect, SoftBufferError};
55
use objc2::rc::Retained;
6-
use objc2::runtime::{AnyObject, Bool};
6+
use objc2::runtime::{AnyObject, Bool, ProtocolObject};
77
use objc2::{define_class, msg_send, AllocAnyThread, DefinedClass, MainThreadMarker, Message};
88
use objc2_core_foundation::{CFRetained, CGPoint};
99
use objc2_core_graphics::{
1010
CGBitmapInfo, CGColorRenderingIntent, CGColorSpace, CGDataProvider, CGImage, CGImageAlphaInfo,
1111
};
1212
use objc2_foundation::{
1313
ns_string, NSDictionary, NSKeyValueChangeKey, NSKeyValueChangeNewKey,
14-
NSKeyValueObservingOptions, NSNumber, NSObject, NSObjectNSKeyValueObserverRegistration,
14+
NSKeyValueObservingOptions, NSNull, NSNumber, NSObject, NSObjectNSKeyValueObserverRegistration,
1515
NSString, NSValue,
1616
};
17-
use objc2_quartz_core::{kCAGravityTopLeft, CALayer, CATransaction};
17+
use objc2_quartz_core::{kCAGravityTopLeft, CALayer};
1818
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle};
1919

2020
use std::ffi::c_void;
@@ -222,6 +222,17 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for CGImpl<
222222
// resized to something that doesn't fit, see #177.
223223
layer.setContentsGravity(unsafe { kCAGravityTopLeft });
224224

225+
// The CALayer has a default action associated with a change in the layer contents, causing
226+
// a quarter second fade transition to happen every time a new buffer is applied.
227+
//
228+
// We avoid this by setting the action for the "contents" key to NULL.
229+
//
230+
// TODO(madsmtm): Do we want to do the same for bounds/contentsScale for smoother resizing?
231+
layer.setActions(Some(&NSDictionary::from_slices(
232+
&[ns_string!("contents")],
233+
&[ProtocolObject::from_ref(&*unsafe { NSNull::null() })],
234+
)));
235+
225236
// Initialize color space here, to reduce work later on.
226237
let color_space = unsafe { CGColorSpace::new_device_rgb() }.unwrap();
227238

@@ -326,16 +337,9 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_,
326337
}
327338
.unwrap();
328339

329-
// The CALayer has a default action associated with a change in the layer contents, causing
330-
// a quarter second fade transition to happen every time a new buffer is applied. This can
331-
// be avoided by wrapping the operation in a transaction and disabling all actions.
332-
CATransaction::begin();
333-
CATransaction::setDisableActions(true);
334-
335340
// SAFETY: The contents is `CGImage`, which is a valid class for `contents`.
336341
unsafe { self.imp.layer.setContents(Some(image.as_ref())) };
337342

338-
CATransaction::commit();
339343
Ok(())
340344
}
341345

0 commit comments

Comments
 (0)