diff --git a/Cargo.lock b/Cargo.lock index aa030b9575..7b4fbdaaa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -763,8 +763,8 @@ dependencies = [ "foreign-types", "futures", "gpui", - "io_surface", "log", + "media", "objc", "parking_lot 0.11.2", "postage", @@ -2232,9 +2232,9 @@ dependencies = [ "futures", "gpui_macros", "image", - "io_surface", "lazy_static", "log", + "media", "metal", "num_cpus", "objc", @@ -2601,15 +2601,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "io_surface" -version = "0.1.0" -dependencies = [ - "block", - "core-foundation", - "objc", -] - [[package]] name = "iovec" version = "0.1.4" @@ -3039,6 +3030,15 @@ dependencies = [ "digest 0.10.3", ] +[[package]] +name = "media" +version = "0.1.0" +dependencies = [ + "block", + "core-foundation", + "objc", +] + [[package]] name = "memchr" version = "2.5.0" diff --git a/crates/capture/Cargo.toml b/crates/capture/Cargo.toml index 8c6e901bbd..f52fde195e 100644 --- a/crates/capture/Cargo.toml +++ b/crates/capture/Cargo.toml @@ -10,7 +10,7 @@ identifier = "dev.zed.Capture" [dependencies] gpui = { path = "../gpui" } -io_surface = { path = "../io_surface" } +media = { path = "../media" } block = "0.1" cocoa = "0.24" diff --git a/crates/capture/src/main.rs b/crates/capture/src/main.rs index e83135fc64..ed9f56cd18 100644 --- a/crates/capture/src/main.rs +++ b/crates/capture/src/main.rs @@ -16,8 +16,8 @@ use gpui::{ platform::current::Surface, Menu, MenuItem, ViewContext, }; -use io_surface::IOSurface; use log::LevelFilter; +use media::core_video::{self, CVImageBuffer}; use objc::{ class, declare::ClassDecl, @@ -55,7 +55,7 @@ fn main() { } struct ScreenCaptureView { - surface: Option, + image_buffer: Option, } impl gpui::Entity for ScreenCaptureView { @@ -64,8 +64,9 @@ impl gpui::Entity for ScreenCaptureView { impl ScreenCaptureView { pub fn new(cx: &mut ViewContext) -> Self { - let (surface_tx, mut surface_rx) = postage::watch::channel::>(); - let surface_tx = Arc::new(Mutex::new(surface_tx)); + let (image_buffer_tx, mut image_buffer_rx) = + postage::watch::channel::>(); + let image_buffer_tx = Arc::new(Mutex::new(image_buffer_tx)); unsafe { let block = ConcreteBlock::new(move |content: id, error: id| { @@ -93,7 +94,7 @@ impl ScreenCaptureView { let output: id = msg_send![capture_output_class, alloc]; let output: id = msg_send![output, init]; - let surface_tx = surface_tx.clone(); + let surface_tx = image_buffer_tx.clone(); let callback = Box::new(move |buffer: CMSampleBufferRef| { let buffer = CMSampleBuffer::wrap_under_get_rule(buffer); @@ -112,8 +113,7 @@ impl ScreenCaptureView { } let image_buffer = buffer.image_buffer(); - let io_surface = image_buffer.io_surface(); - *surface_tx.lock().borrow_mut() = Some(io_surface); + *surface_tx.lock().borrow_mut() = Some(image_buffer); }) as Box; let callback = Box::into_raw(Box::new(callback)); (*output).set_ivar("callback", callback as *mut c_void); @@ -169,10 +169,10 @@ impl ScreenCaptureView { } cx.spawn_weak(|this, mut cx| async move { - while let Some(surface) = surface_rx.next().await { + while let Some(image_buffer) = image_buffer_rx.next().await { if let Some(this) = this.upgrade(&cx) { this.update(&mut cx, |this, cx| { - this.surface = surface; + this.image_buffer = image_buffer; println!("NEW SURFACE!"); cx.notify(); }) @@ -183,7 +183,7 @@ impl ScreenCaptureView { }) .detach(); - Self { surface: None } + Self { image_buffer: None } } } @@ -193,12 +193,12 @@ impl gpui::View for ScreenCaptureView { } fn render(&mut self, _: &mut gpui::RenderContext) -> gpui::ElementBox { - let surface = self.surface.clone(); + let image_buffer = self.image_buffer.clone(); Canvas::new(move |bounds, _, cx| { - if let Some(native_surface) = surface.clone() { + if let Some(image_buffer) = image_buffer.clone() { cx.scene.push_surface(Surface { bounds, - native_surface, + image_buffer, }); } }) @@ -291,48 +291,3 @@ mod core_media { fn CMSampleBufferGetImageBuffer(buffer: CMSampleBufferRef) -> CVImageBufferRef; } } - -mod core_video { - #![allow(non_snake_case)] - - use core_foundation::{ - base::{CFTypeID, TCFType}, - declare_TCFType, impl_CFTypeDescription, impl_TCFType, - }; - use io_surface::{IOSurface, IOSurfaceRef}; - use std::ffi::c_void; - - #[repr(C)] - pub struct __CVImageBuffer(c_void); - // The ref type must be a pointer to the underlying struct. - pub type CVImageBufferRef = *const __CVImageBuffer; - - declare_TCFType!(CVImageBuffer, CVImageBufferRef); - impl_TCFType!(CVImageBuffer, CVImageBufferRef, CVImageBufferGetTypeID); - impl_CFTypeDescription!(CVImageBuffer); - - impl CVImageBuffer { - pub fn io_surface(&self) -> IOSurface { - unsafe { - IOSurface::wrap_under_get_rule(CVPixelBufferGetIOSurface( - self.as_concrete_TypeRef(), - )) - } - } - - pub fn width(&self) -> usize { - unsafe { CVPixelBufferGetWidth(self.as_concrete_TypeRef()) } - } - - pub fn height(&self) -> usize { - unsafe { CVPixelBufferGetHeight(self.as_concrete_TypeRef()) } - } - } - - extern "C" { - fn CVImageBufferGetTypeID() -> CFTypeID; - fn CVPixelBufferGetIOSurface(buffer: CVImageBufferRef) -> IOSurfaceRef; - fn CVPixelBufferGetWidth(buffer: CVImageBufferRef) -> usize; - fn CVPixelBufferGetHeight(buffer: CVImageBufferRef) -> usize; - } -} diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 6539c292fc..51bc416e19 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -60,7 +60,7 @@ png = "0.16" simplelog = "0.9" [target.'cfg(target_os = "macos")'.dependencies] -io_surface = { path = "../io_surface" } +media = { path = "../media" } anyhow = "1" block = "0.1" cocoa = "0.24" diff --git a/crates/gpui/src/platform/mac/renderer.rs b/crates/gpui/src/platform/mac/renderer.rs index 41883a2f73..6c1d3cef21 100644 --- a/crates/gpui/src/platform/mac/renderer.rs +++ b/crates/gpui/src/platform/mac/renderer.rs @@ -39,7 +39,7 @@ struct PathSprite { pub struct Surface { pub bounds: RectF, - pub native_surface: io_surface::IOSurface, + pub image_buffer: media::core_video::CVImageBuffer, } impl Renderer { @@ -790,7 +790,6 @@ impl Renderer { let target_size = surface.bounds.size() * scale_factor; // let corner_radius = surface.corner_radius * scale_factor; // let border_width = surface.border.width * scale_factor; - // let (alloc_id, atlas_bounds) = self.image_cache.render(&surface.native_surface); } // command_encoder.set_render_pipeline_state(&self.image_pipeline_state); diff --git a/crates/io_surface/src/io_surface.rs b/crates/io_surface/src/io_surface.rs deleted file mode 100644 index 13b1fd5ce1..0000000000 --- a/crates/io_surface/src/io_surface.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![allow(non_snake_case)] - -use core_foundation::{ - base::{CFTypeID, TCFType}, - declare_TCFType, impl_CFTypeDescription, impl_TCFType, -}; -use std::ffi::c_void; - -#[repr(C)] -pub struct __IOSurface(c_void); -// The ref type must be a pointer to the underlying struct. -pub type IOSurfaceRef = *const __IOSurface; - -declare_TCFType!(IOSurface, IOSurfaceRef); -impl_TCFType!(IOSurface, IOSurfaceRef, IOSurfaceGetTypeID); -impl_CFTypeDescription!(IOSurface); - -#[link(name = "IOSurface", kind = "framework")] -extern "C" { - fn IOSurfaceGetTypeID() -> CFTypeID; -} diff --git a/crates/io_surface/Cargo.toml b/crates/media/Cargo.toml similarity index 74% rename from crates/io_surface/Cargo.toml rename to crates/media/Cargo.toml index 2d9324b6d8..ff472fe352 100644 --- a/crates/io_surface/Cargo.toml +++ b/crates/media/Cargo.toml @@ -1,10 +1,10 @@ [package] -name = "io_surface" +name = "media" version = "0.1.0" edition = "2021" [lib] -path = "src/io_surface.rs" +path = "src/media.rs" doctest = false [dependencies] diff --git a/crates/media/src/media.rs b/crates/media/src/media.rs new file mode 100644 index 0000000000..435c03e936 --- /dev/null +++ b/crates/media/src/media.rs @@ -0,0 +1,66 @@ +#![allow(non_snake_case)] + +use core_foundation::{ + base::{CFTypeID, TCFType}, + declare_TCFType, impl_CFTypeDescription, impl_TCFType, +}; +use std::ffi::c_void; + +pub mod io_surface { + use super::*; + + #[repr(C)] + pub struct __IOSurface(c_void); + // The ref type must be a pointer to the underlying struct. + pub type IOSurfaceRef = *const __IOSurface; + + declare_TCFType!(IOSurface, IOSurfaceRef); + impl_TCFType!(IOSurface, IOSurfaceRef, IOSurfaceGetTypeID); + impl_CFTypeDescription!(IOSurface); + + #[link(name = "IOSurface", kind = "framework")] + extern "C" { + fn IOSurfaceGetTypeID() -> CFTypeID; + } +} + +pub mod core_video { + #![allow(non_snake_case)] + + use super::*; + use io_surface::{IOSurface, IOSurfaceRef}; + + #[repr(C)] + pub struct __CVImageBuffer(c_void); + // The ref type must be a pointer to the underlying struct. + pub type CVImageBufferRef = *const __CVImageBuffer; + + declare_TCFType!(CVImageBuffer, CVImageBufferRef); + impl_TCFType!(CVImageBuffer, CVImageBufferRef, CVImageBufferGetTypeID); + impl_CFTypeDescription!(CVImageBuffer); + + impl CVImageBuffer { + pub fn io_surface(&self) -> IOSurface { + unsafe { + IOSurface::wrap_under_get_rule(CVPixelBufferGetIOSurface( + self.as_concrete_TypeRef(), + )) + } + } + + pub fn width(&self) -> usize { + unsafe { CVPixelBufferGetWidth(self.as_concrete_TypeRef()) } + } + + pub fn height(&self) -> usize { + unsafe { CVPixelBufferGetHeight(self.as_concrete_TypeRef()) } + } + } + + extern "C" { + fn CVImageBufferGetTypeID() -> CFTypeID; + fn CVPixelBufferGetIOSurface(buffer: CVImageBufferRef) -> IOSurfaceRef; + fn CVPixelBufferGetWidth(buffer: CVImageBufferRef) -> usize; + fn CVPixelBufferGetHeight(buffer: CVImageBufferRef) -> usize; + } +}