Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased

- Improved performance when presenting on macOS.
- Update to `objc2` 0.6.0.
- Bump MSRV to Rust 1.71.
- Make `Context` cloneable.
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ objc2-foundation = { version = "0.3.1", default-features = false, features = [
"NSString",
"NSThread",
"NSValue",
"NSNull",
] }
objc2-quartz-core = { version = "0.3.1", default-features = false, features = [
"std",
Expand Down
24 changes: 14 additions & 10 deletions src/backends/cg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ use crate::backend_interface::*;
use crate::error::InitError;
use crate::{Rect, SoftBufferError};
use objc2::rc::Retained;
use objc2::runtime::{AnyObject, Bool};
use objc2::runtime::{AnyObject, Bool, ProtocolObject};
use objc2::{define_class, msg_send, AllocAnyThread, DefinedClass, MainThreadMarker, Message};
use objc2_core_foundation::{CFRetained, CGPoint};
use objc2_core_graphics::{
CGBitmapInfo, CGColorRenderingIntent, CGColorSpace, CGDataProvider, CGImage, CGImageAlphaInfo,
};
use objc2_foundation::{
ns_string, NSDictionary, NSKeyValueChangeKey, NSKeyValueChangeNewKey,
NSKeyValueObservingOptions, NSNumber, NSObject, NSObjectNSKeyValueObserverRegistration,
NSKeyValueObservingOptions, NSNull, NSNumber, NSObject, NSObjectNSKeyValueObserverRegistration,
NSString, NSValue,
};
Comment on lines 12 to 16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never liked these big mass imports. Any chance we could instead do:

use objc2_foundation as found;

...then do:

found::NSNull

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'd rather avoid that, when reading the implementation, it doesn't actually matter much which framework a specific thing is from - and besides, everything is already prefixed ("NS", "CG" etc.).

I'd rather do:

use objc2_core_foundation::*;
use objc2_core_graphics::*;
use objc2_foundation::*;
use objc2_quartz_core::*;

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I guess objc2_* could have taken the same approach as cidre, e.g. cidre::ns::Null, which is admittedly much more "Rusty", though I decided not to, since it makes it harder to figure out what a specific type corresponds to underneath).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes the code later on harder to read for humans. My vote's still on having a module prefix. I take the same approach in new Win32 code that I write.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, I do something similar in the Windows part of the code.

If you think it's out of scope for this PR, I can file one later.

use objc2_quartz_core::{kCAGravityTopLeft, CALayer, CATransaction};
use objc2_quartz_core::{kCAGravityTopLeft, CALayer};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle};

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

// The CALayer has a default action associated with a change in the layer contents, causing
// a quarter second fade transition to happen every time a new buffer is applied.
//
// We avoid this by setting the action for the "contents" key to NULL.
//
// TODO(madsmtm): Do we want to do the same for bounds/contentsScale for smoother resizing?
layer.setActions(Some(&NSDictionary::from_slices(
&[ns_string!("contents")],
&[ProtocolObject::from_ref(&*unsafe { NSNull::null() })],
)));

// Initialize color space here, to reduce work later on.
let color_space = unsafe { CGColorSpace::new_device_rgb() }.unwrap();

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

// The CALayer has a default action associated with a change in the layer contents, causing
// a quarter second fade transition to happen every time a new buffer is applied. This can
// be avoided by wrapping the operation in a transaction and disabling all actions.
CATransaction::begin();
CATransaction::setDisableActions(true);

// SAFETY: The contents is `CGImage`, which is a valid class for `contents`.
unsafe { self.imp.layer.setContents(Some(image.as_ref())) };

CATransaction::commit();
Ok(())
}

Expand Down
Loading