Skip to content

Fix deprecations in objc2-core-foundation v0.3.1 #264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ jobs:
- name: Pin deps that break MSRV
if: matrix.rust_version == '1.71.0'
run: |
cargo update -p half --precise 2.4.1
cargo update -p bumpalo --precise 3.14.0

- name: Build crate
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,19 @@ features = [
]

[target.'cfg(target_vendor = "apple")'.dependencies]
objc2-core-graphics = { version = "0.3.0", default-features = false, features = [
objc2-core-graphics = { version = "0.3.1", default-features = false, features = [
"std",
"objc2",
"CGColorSpace",
"CGDataProvider",
"CGImage",
] }
objc2 = "0.6.0"
objc2-core-foundation = { version = "0.3.0", default-features = false, features = [
objc2-core-foundation = { version = "0.3.1", default-features = false, features = [
"std",
"CFCGTypes",
] }
objc2-foundation = { version = "0.3.0", default-features = false, features = [
objc2-foundation = { version = "0.3.1", default-features = false, features = [
"std",
"objc2-core-foundation",
"NSDictionary",
Expand All @@ -103,7 +103,7 @@ objc2-foundation = { version = "0.3.0", default-features = false, features = [
"NSThread",
"NSValue",
] }
objc2-quartz-core = { version = "0.3.0", default-features = false, features = [
objc2-quartz-core = { version = "0.3.1", default-features = false, features = [
"std",
"objc2-core-foundation",
"CALayer",
Expand Down
45 changes: 20 additions & 25 deletions src/backends/cg.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Softbuffer implementation using CoreGraphics.
use crate::backend_interface::*;
use crate::error::InitError;
use crate::{Rect, SoftBufferError};
Expand All @@ -6,8 +7,7 @@ use objc2::runtime::{AnyObject, Bool};
use objc2::{define_class, msg_send, AllocAnyThread, DefinedClass, MainThreadMarker, Message};
use objc2_core_foundation::{CFRetained, CGPoint};
use objc2_core_graphics::{
CGBitmapInfo, CGColorRenderingIntent, CGColorSpace, CGColorSpaceCreateDeviceRGB,
CGDataProviderCreateWithData, CGImageAlphaInfo, CGImageCreate,
CGBitmapInfo, CGColorRenderingIntent, CGColorSpace, CGDataProvider, CGImage, CGImageAlphaInfo,
};
use objc2_foundation::{
ns_string, NSDictionary, NSKeyValueChangeKey, NSKeyValueChangeNewKey,
Expand All @@ -27,7 +27,7 @@ use std::ptr::{self, slice_from_raw_parts_mut, NonNull};
define_class!(
#[unsafe(super(NSObject))]
#[name = "SoftbufferObserver"]
#[ivars = Retained<CALayer>]
#[ivars = SendCALayer]
struct Observer;

/// NSKeyValueObserving
Expand All @@ -45,13 +45,9 @@ define_class!(
}
);

// SAFETY: The `CALayer` that the observer contains is thread safe.
unsafe impl Send for Observer {}
unsafe impl Sync for Observer {}

impl Observer {
fn new(layer: &CALayer) -> Retained<Self> {
let this = Self::alloc().set_ivars(layer.retain());
let this = Self::alloc().set_ivars(SendCALayer(layer.retain()));
unsafe { msg_send![super(this), init] }
}

Expand All @@ -64,11 +60,9 @@ impl Observer {

let change =
change.expect("requested a change dictionary in `addObserver`, but none was provided");
let new = unsafe {
change
.objectForKey(NSKeyValueChangeNewKey)
.expect("requested change dictionary did not contain `NSKeyValueChangeNewKey`")
};
let new = change
.objectForKey(unsafe { NSKeyValueChangeNewKey })
.expect("requested change dictionary did not contain `NSKeyValueChangeNewKey`");

// NOTE: Setting these values usually causes a quarter second animation to occur, which is
// undesirable.
Expand Down Expand Up @@ -106,7 +100,7 @@ pub struct CGImpl<D, W> {
/// Can also be retrieved from `layer.superlayer()`.
root_layer: SendCALayer,
observer: Retained<Observer>,
color_space: SendCGColorSpace,
color_space: CFRetained<CGColorSpace>,
/// The width of the underlying buffer.
width: usize,
/// The height of the underlying buffer.
Expand Down Expand Up @@ -229,7 +223,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for CGImpl<
layer.setContentsGravity(unsafe { kCAGravityTopLeft });

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

// Grab initial width and height from the layer (whose properties have just been initialized
// by the observer using `NSKeyValueObservingOptionInitial`).
Expand All @@ -242,7 +236,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for CGImpl<
layer: SendCALayer(layer),
root_layer: SendCALayer(root_layer),
observer,
color_space: SendCGColorSpace(color_space),
color_space,
width,
height,
_display: PhantomData,
Expand Down Expand Up @@ -310,18 +304,18 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_,
// SAFETY: The data pointer and length are valid.
// The info pointer can safely be NULL, we don't use it in the `release` callback.
unsafe {
CGDataProviderCreateWithData(ptr::null_mut(), data_ptr, len, Some(release)).unwrap()
CGDataProvider::with_data(ptr::null_mut(), data_ptr, len, Some(release)).unwrap()
}
};

let image = unsafe {
CGImageCreate(
CGImage::new(
self.imp.width,
self.imp.height,
8,
32,
self.imp.width * 4,
Some(&self.imp.color_space.0),
Some(&self.imp.color_space),
// TODO: This looks incorrect!
CGBitmapInfo::ByteOrder32Little | CGBitmapInfo(CGImageAlphaInfo::NoneSkipFirst.0),
Some(&data_provider),
Expand Down Expand Up @@ -350,16 +344,17 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_,
}
}

struct SendCGColorSpace(CFRetained<CGColorSpace>);
// SAFETY: `CGColorSpace` is immutable, and can freely be shared between threads.
unsafe impl Send for SendCGColorSpace {}
unsafe impl Sync for SendCGColorSpace {}

struct SendCALayer(Retained<CALayer>);
// CALayer is thread safe, like most things in Core Animation, see:

// SAFETY: CALayer is dubiously thread safe, like most things in Core Animation.
// But since we make sure to do our changes within a CATransaction, it is
// _probably_ fine for us to use CALayer from different threads.
//
// See also:
// https://developer.apple.com/documentation/quartzcore/catransaction/1448267-lock?language=objc
// https://stackoverflow.com/questions/76250226/how-to-render-content-of-calayer-on-a-background-thread
unsafe impl Send for SendCALayer {}
// SAFETY: Same as above.
unsafe impl Sync for SendCALayer {}

impl Deref for SendCALayer {
Expand Down