Skip to content

Commit ba3b823

Browse files
committed
use CALayer for macOS backend
1 parent 7521606 commit ba3b823

File tree

2 files changed

+25
-29
lines changed

2 files changed

+25
-29
lines changed

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ x11-dl = "2.19.1"
2626
winapi = "0.3.9"
2727

2828
[target.'cfg(target_os = "macos")'.dependencies]
29+
cocoa = "0.24.0"
2930
core-graphics = "0.22.3"
31+
foreign-types = "0.3.0"
3032
objc = "0.2.7"
3133

3234
[target.'cfg(target_arch = "wasm32")'.dependencies]
@@ -49,4 +51,4 @@ features = ["jpeg"]
4951
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
5052
# Turn rayon back on everywhere else; creating the separate entry resets the features to default.
5153
image = "0.23.14"
52-
rayon = "1.5.1"
54+
rayon = "1.5.1"

src/cg.rs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,30 @@
11
use crate::{GraphicsContextImpl, SoftBufferError};
22
use raw_window_handle::{HasRawWindowHandle, AppKitHandle};
3-
use objc::runtime::Object;
43
use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault};
54
use core_graphics::color_space::CGColorSpace;
6-
use core_graphics::context::CGContext;
75
use core_graphics::data_provider::CGDataProvider;
8-
use core_graphics::geometry::{CGPoint, CGSize, CGRect};
6+
use core_graphics::geometry::CGSize;
97
use core_graphics::image::CGImage;
10-
use core_graphics::sys;
8+
9+
use cocoa::base::id;
10+
use cocoa::quartzcore::CALayer;
11+
use foreign_types::ForeignType;
1112

1213
pub struct CGImpl {
13-
view: *mut Object,
14+
layer: CALayer,
1415
}
1516

1617
impl CGImpl {
1718
pub unsafe fn new<W: HasRawWindowHandle>(handle: AppKitHandle) -> Result<Self, SoftBufferError<W>> {
18-
let window = handle.ns_window as *mut Object;
19-
let view = handle.ns_view as *mut Object;
20-
let cls = class!(NSGraphicsContext);
21-
let graphics_context: *mut Object = msg_send![cls, graphicsContextWithWindow:window];
22-
if graphics_context.is_null() {
23-
return Err(SoftBufferError::PlatformError(Some("Graphics context is null".into()), None));
24-
}
25-
let _: () = msg_send![cls, setCurrentContext:graphics_context];
26-
Ok(
27-
Self {
28-
view,
29-
}
30-
)
19+
let view = handle.ns_view as id;
20+
let layer = CALayer::new();
21+
let _: () = msg_send![view, setLayer:layer.clone()];
22+
Ok(Self{layer})
3123
}
3224
}
3325

3426
impl GraphicsContextImpl for CGImpl {
3527
unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) {
36-
let cls = class!(NSGraphicsContext);
37-
let graphics_context: *mut Object = msg_send![cls, currentContext];
38-
let context_ptr: *mut sys::CGContext = msg_send![graphics_context, CGContext];
39-
let context = CGContext::from_existing_context_ptr(context_ptr);
4028
let color_space = CGColorSpace::create_device_rgb();
4129
let slice = std::slice::from_raw_parts(
4230
buffer.as_ptr() as *const u8,
@@ -54,11 +42,17 @@ impl GraphicsContextImpl for CGImpl {
5442
false,
5543
kCGRenderingIntentDefault,
5644
);
57-
let frame: CGRect = msg_send![self.view, frame];
58-
// In Core Graphics, (0, 0) is bottom left, not top left
59-
let origin = CGPoint { x: 0f64, y: frame.size.height };
60-
let size = CGSize { width: width as f64, height: -(height as f64) };
61-
let rect = CGRect { origin, size };
62-
context.draw_image(rect, &image);
45+
46+
let size = CGSize::new(width as f64, height as f64);
47+
let rep: id = msg_send![class!(NSCGImageRep), alloc];
48+
let rep: id = msg_send![rep, initWithCGImage:image.as_ptr() size:size];
49+
50+
let nsimage: id = msg_send![class!(NSImage), alloc];
51+
let nsimage: id = msg_send![nsimage, initWithSize:size];
52+
let _: () = msg_send![nsimage, addRepresentation:rep];
53+
let _: () = msg_send![rep, release];
54+
55+
self.layer.set_contents(nsimage);
56+
let _: () = msg_send![nsimage, release];
6357
}
6458
}

0 commit comments

Comments
 (0)