mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 21:31:44 +03:00
Enable Blade on MacOS via "macos-blade" feature (#7669)
Depends on https://github.com/zed-industries/font-kit/pull/2 and https://github.com/kvark/blade/pull/77 This change enables Blade to be also used on MacOS. It will also make it easier to use it on Windows. What works: most of the things. Zed loads as fast and appears equally responsive to the current renderer. <img width="306" alt="Screenshot 2024-02-11 at 12 09 15 AM" src="https://github.com/zed-industries/zed/assets/107301/66d82f45-5ea2-4e2b-86c6-5b3ed333c827"> Things missing: - [x] video streaming. ~~Requires a bit of plumbing on both Blade and Zed sides, but all fairly straightforward.~~ - verified with a local setup - [x] resize. ~~Not sure where exactly to hook up the reaction on the window size change. Once we know where, the fix is one line.~~ - [ ] fine-tune CA Layer - this isn't a blocker for merging the PR, but it would be a blocker if we wanted to switch to the new path by default - [ ] rebase on latest, get the dependency merged (need review/merge of https://github.com/zed-industries/font-kit/pull/2!) Update: I implemented resize support as well as "surface" rendering on the Blade path (which will be useful on Linux/Windows later on). I haven't tested the latter though - not sure how to get something streaming. Would appreciate some help! I don't think this should be a blocker to this PR, anyway. The only little piece that's missing for the Blade on MacOS path to be full-featured is fine-tuning the CALayer configuration. Zed does a lot of careful logic in configuring the layer, such as switching the "present with transaction" on/off intermittently, which Blade path doesn't have yet. Release Notes: - N/A --------- Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
1c361ac579
commit
9ad1862f2f
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -91,8 +91,8 @@ jobs:
|
|||||||
- name: Build collab
|
- name: Build collab
|
||||||
run: cargo build -p collab
|
run: cargo build -p collab
|
||||||
|
|
||||||
- name: Build other binaries
|
- name: Build other binaries and features
|
||||||
run: cargo build --workspace --bins --all-features
|
run: cargo build --workspace --bins --all-features; cargo check -p gpui --features "macos-blade"
|
||||||
|
|
||||||
# todo!(linux): Actually run the tests
|
# todo!(linux): Actually run the tests
|
||||||
linux_tests:
|
linux_tests:
|
||||||
|
42
Cargo.lock
generated
42
Cargo.lock
generated
@ -1396,7 +1396,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "blade-graphics"
|
name = "blade-graphics"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/kvark/blade?rev=c4f951a88b345724cb952e920ad30e39851f7760#c4f951a88b345724cb952e920ad30e39851f7760"
|
source = "git+https://github.com/kvark/blade?rev=e9d93a4d41f3946a03ffb76136290d6ccf7f2b80#e9d93a4d41f3946a03ffb76136290d6ccf7f2b80"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ash",
|
"ash",
|
||||||
"ash-window",
|
"ash-window",
|
||||||
@ -1413,7 +1413,7 @@ dependencies = [
|
|||||||
"khronos-egl",
|
"khronos-egl",
|
||||||
"libloading 0.8.0",
|
"libloading 0.8.0",
|
||||||
"log",
|
"log",
|
||||||
"metal 0.25.0",
|
"metal",
|
||||||
"mint",
|
"mint",
|
||||||
"naga",
|
"naga",
|
||||||
"objc",
|
"objc",
|
||||||
@ -1426,7 +1426,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "blade-macros"
|
name = "blade-macros"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/kvark/blade?rev=c4f951a88b345724cb952e920ad30e39851f7760#c4f951a88b345724cb952e920ad30e39851f7760"
|
source = "git+https://github.com/kvark/blade?rev=e9d93a4d41f3946a03ffb76136290d6ccf7f2b80#e9d93a4d41f3946a03ffb76136290d6ccf7f2b80"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2359,13 +2359,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-text"
|
name = "core-text"
|
||||||
version = "19.2.0"
|
version = "20.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25"
|
checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-graphics 0.22.3",
|
"core-graphics 0.23.1",
|
||||||
"foreign-types 0.3.2",
|
"foreign-types 0.5.0",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3511,12 +3511,12 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "font-kit"
|
name = "font-kit"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "git+https://github.com/zed-industries/font-kit?rev=d97147f#d97147ff11a9024b9707d9c9c7e3a0bdaba048ac"
|
source = "git+https://github.com/zed-industries/font-kit?rev=5a5c4d4#5a5c4d4ca395c74eb0abde38508e170ce0fd761a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-graphics 0.22.3",
|
"core-graphics 0.23.1",
|
||||||
"core-text",
|
"core-text",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"dwrote",
|
"dwrote",
|
||||||
@ -4085,7 +4085,7 @@ dependencies = [
|
|||||||
"cocoa",
|
"cocoa",
|
||||||
"collections",
|
"collections",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-graphics 0.22.3",
|
"core-graphics 0.23.1",
|
||||||
"core-text",
|
"core-text",
|
||||||
"cosmic-text",
|
"cosmic-text",
|
||||||
"ctor",
|
"ctor",
|
||||||
@ -4095,7 +4095,7 @@ dependencies = [
|
|||||||
"etagere",
|
"etagere",
|
||||||
"flume",
|
"flume",
|
||||||
"font-kit",
|
"font-kit",
|
||||||
"foreign-types 0.3.2",
|
"foreign-types 0.5.0",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
"gpui_macros",
|
"gpui_macros",
|
||||||
"image",
|
"image",
|
||||||
@ -4104,7 +4104,7 @@ dependencies = [
|
|||||||
"linkme",
|
"linkme",
|
||||||
"log",
|
"log",
|
||||||
"media",
|
"media",
|
||||||
"metal 0.21.0",
|
"metal",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"objc",
|
"objc",
|
||||||
"open",
|
"open",
|
||||||
@ -5350,8 +5350,8 @@ dependencies = [
|
|||||||
"block",
|
"block",
|
||||||
"bytes 1.5.0",
|
"bytes 1.5.0",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"foreign-types 0.3.2",
|
"foreign-types 0.5.0",
|
||||||
"metal 0.21.0",
|
"metal",
|
||||||
"objc",
|
"objc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -5423,20 +5423,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "metal"
|
|
||||||
version = "0.21.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4598d719460ade24c7d91f335daf055bf2a7eec030728ce751814c50cdd6a26c"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
"block",
|
|
||||||
"cocoa-foundation",
|
|
||||||
"foreign-types 0.3.2",
|
|
||||||
"log",
|
|
||||||
"objc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
|
@ -181,6 +181,9 @@ anyhow = "1.0.57"
|
|||||||
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
||||||
async-tar = "0.4.2"
|
async-tar = "0.4.2"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
|
blade-graphics = { git = "https://github.com/kvark/blade", rev = "e9d93a4d41f3946a03ffb76136290d6ccf7f2b80" }
|
||||||
|
blade-macros = { git = "https://github.com/kvark/blade", rev = "e9d93a4d41f3946a03ffb76136290d6ccf7f2b80" }
|
||||||
|
blade-rwh = { package = "raw-window-handle", version = "0.5" }
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
ctor = "0.2.6"
|
ctor = "0.2.6"
|
||||||
derive_more = "0.99.17"
|
derive_more = "0.99.17"
|
||||||
|
@ -16,6 +16,7 @@ test-support = [
|
|||||||
"util/test-support",
|
"util/test-support",
|
||||||
]
|
]
|
||||||
runtime_shaders = []
|
runtime_shaders = []
|
||||||
|
macos-blade = ["blade-graphics", "blade-macros", "blade-rwh", "bytemuck"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "src/gpui.rs"
|
path = "src/gpui.rs"
|
||||||
@ -26,6 +27,10 @@ anyhow.workspace = true
|
|||||||
async-task = "4.7"
|
async-task = "4.7"
|
||||||
backtrace = { version = "0.3", optional = true }
|
backtrace = { version = "0.3", optional = true }
|
||||||
bitflags = "2.4.0"
|
bitflags = "2.4.0"
|
||||||
|
blade-graphics = { workspace = true, optional = true }
|
||||||
|
blade-macros = { workspace = true, optional = true }
|
||||||
|
blade-rwh = { workspace = true, optional = true }
|
||||||
|
bytemuck = { version = "1", optional = true }
|
||||||
collections.workspace = true
|
collections.workspace = true
|
||||||
ctor.workspace = true
|
ctor.workspace = true
|
||||||
derive_more.workspace = true
|
derive_more.workspace = true
|
||||||
@ -33,7 +38,7 @@ dhat = { version = "0.3", optional = true }
|
|||||||
env_logger = { version = "0.9", optional = true }
|
env_logger = { version = "0.9", optional = true }
|
||||||
etagere = "0.2"
|
etagere = "0.2"
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "d97147f" }
|
font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "5a5c4d4" }
|
||||||
gpui_macros.workspace = true
|
gpui_macros.workspace = true
|
||||||
image = "0.23"
|
image = "0.23"
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
@ -48,7 +53,6 @@ pathfinder_geometry = "0.5"
|
|||||||
postage.workspace = true
|
postage.workspace = true
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
raw-window-handle = "0.6"
|
raw-window-handle = "0.6"
|
||||||
blade-rwh = { package = "raw-window-handle", version = "0.5" }
|
|
||||||
refineable.workspace = true
|
refineable.workspace = true
|
||||||
resvg = "0.14"
|
resvg = "0.14"
|
||||||
schemars.workspace = true
|
schemars.workspace = true
|
||||||
@ -86,12 +90,12 @@ cbindgen = "0.26.0"
|
|||||||
block = "0.1"
|
block = "0.1"
|
||||||
cocoa = "0.25"
|
cocoa = "0.25"
|
||||||
core-foundation = { version = "0.9.3", features = ["with-uuid"] }
|
core-foundation = { version = "0.9.3", features = ["with-uuid"] }
|
||||||
core-graphics = "0.22.3"
|
core-graphics = "0.23"
|
||||||
core-text = "19.2"
|
core-text = "20.1"
|
||||||
foreign-types = "0.3"
|
foreign-types = "0.5"
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
media.workspace = true
|
media.workspace = true
|
||||||
metal = "0.21.0"
|
metal = "0.25"
|
||||||
objc = "0.2"
|
objc = "0.2"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
@ -105,8 +109,9 @@ wayland-protocols = { version = "0.31.2", features = ["client"] }
|
|||||||
wayland-backend = { version = "0.3.3", features = ["client_system"] }
|
wayland-backend = { version = "0.3.3", features = ["client_system"] }
|
||||||
as-raw-xcb-connection = "1"
|
as-raw-xcb-connection = "1"
|
||||||
#TODO: use these on all platforms
|
#TODO: use these on all platforms
|
||||||
blade-graphics = { git = "https://github.com/kvark/blade", rev = "c4f951a88b345724cb952e920ad30e39851f7760" }
|
blade-graphics.workspace = true
|
||||||
blade-macros = { git = "https://github.com/kvark/blade", rev = "c4f951a88b345724cb952e920ad30e39851f7760" }
|
blade-macros.workspace = true
|
||||||
|
blade-rwh.workspace = true
|
||||||
bytemuck = "1"
|
bytemuck = "1"
|
||||||
cosmic-text = "0.10.0"
|
cosmic-text = "0.10.0"
|
||||||
xkbcommon = { version = "0.7", features = ["x11"] }
|
xkbcommon = { version = "0.7", features = ["x11"] }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(not(target_os = "macos"), allow(unused))]
|
#![cfg_attr(any(not(target_os = "macos"), feature = "macos-blade"), allow(unused))]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
@ -7,15 +7,18 @@ use std::{
|
|||||||
|
|
||||||
use cbindgen::Config;
|
use cbindgen::Config;
|
||||||
|
|
||||||
|
//TODO: consider generating shader code for WGSL
|
||||||
|
//TODO: deprecate "runtime-shaders" and "macos-blade"
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
generate_dispatch_bindings();
|
generate_dispatch_bindings();
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(all(target_os = "macos", not(feature = "macos-blade")))]
|
||||||
let header_path = generate_shader_bindings();
|
let header_path = generate_shader_bindings();
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(all(target_os = "macos", not(feature = "macos-blade")))]
|
||||||
#[cfg(feature = "runtime_shaders")]
|
#[cfg(feature = "runtime_shaders")]
|
||||||
emit_stitched_shaders(&header_path);
|
emit_stitched_shaders(&header_path);
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(all(target_os = "macos", not(feature = "macos-blade")))]
|
||||||
#[cfg(not(feature = "runtime_shaders"))]
|
#[cfg(not(feature = "runtime_shaders"))]
|
||||||
compile_metal_shaders(&header_path);
|
compile_metal_shaders(&header_path);
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,9 @@
|
|||||||
//! and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog).
|
//! and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog).
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)] // Not useful, GPUI makes heavy use of callbacks
|
||||||
#![allow(clippy::collapsible_else_if)]
|
#![allow(clippy::collapsible_else_if)] // False positives in platform specific code
|
||||||
|
#![allow(unused_mut)] // False positives in platform specific code
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod action;
|
mod action;
|
||||||
|
@ -3,10 +3,16 @@
|
|||||||
|
|
||||||
mod app_menu;
|
mod app_menu;
|
||||||
mod keystroke;
|
mod keystroke;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod linux;
|
mod linux;
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
mod mac;
|
mod mac;
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "linux", feature = "macos-blade"))]
|
||||||
|
mod blade;
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
|
8
crates/gpui/src/platform/blade.rs
Normal file
8
crates/gpui/src/platform/blade.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
mod blade_atlas;
|
||||||
|
mod blade_belt;
|
||||||
|
mod blade_renderer;
|
||||||
|
|
||||||
|
pub(crate) use blade_atlas::*;
|
||||||
|
pub(crate) use blade_renderer::*;
|
||||||
|
|
||||||
|
use blade_belt::*;
|
@ -1,14 +1,18 @@
|
|||||||
// Doing `if let` gives you nice scoping with passes/encoders
|
// Doing `if let` gives you nice scoping with passes/encoders
|
||||||
#![allow(irrefutable_let_patterns)]
|
#![allow(irrefutable_let_patterns)]
|
||||||
|
|
||||||
use super::{BladeBelt, BladeBeltDescriptor};
|
use super::{BladeAtlas, BladeBelt, BladeBeltDescriptor, PATH_TEXTURE_FORMAT};
|
||||||
use crate::{
|
use crate::{
|
||||||
AtlasTextureKind, AtlasTile, BladeAtlas, Bounds, ContentMask, Hsla, MonochromeSprite, Path,
|
AtlasTextureKind, AtlasTile, Bounds, ContentMask, Hsla, MonochromeSprite, Path, PathId,
|
||||||
PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow,
|
PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size,
|
||||||
Underline, PATH_TEXTURE_FORMAT,
|
Underline,
|
||||||
};
|
};
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use media::core_video::CVMetalTextureCache;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use std::ffi::c_void;
|
||||||
|
|
||||||
use blade_graphics as gpu;
|
use blade_graphics as gpu;
|
||||||
use std::{mem, sync::Arc};
|
use std::{mem, sync::Arc};
|
||||||
@ -16,6 +20,61 @@ use std::{mem, sync::Arc};
|
|||||||
const SURFACE_FRAME_COUNT: u32 = 3;
|
const SURFACE_FRAME_COUNT: u32 = 3;
|
||||||
const MAX_FRAME_TIME_MS: u32 = 1000;
|
const MAX_FRAME_TIME_MS: u32 = 1000;
|
||||||
|
|
||||||
|
pub type Context = ();
|
||||||
|
pub type Renderer = BladeRenderer;
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub unsafe fn new_renderer(
|
||||||
|
_context: self::Context,
|
||||||
|
native_window: *mut c_void,
|
||||||
|
native_view: *mut c_void,
|
||||||
|
bounds: crate::Size<f32>,
|
||||||
|
) -> Renderer {
|
||||||
|
struct RawWindow {
|
||||||
|
window: *mut c_void,
|
||||||
|
view: *mut c_void,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl blade_rwh::HasRawWindowHandle for RawWindow {
|
||||||
|
fn raw_window_handle(&self) -> blade_rwh::RawWindowHandle {
|
||||||
|
let mut wh = blade_rwh::AppKitWindowHandle::empty();
|
||||||
|
wh.ns_window = self.window;
|
||||||
|
wh.ns_view = self.view;
|
||||||
|
wh.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl blade_rwh::HasRawDisplayHandle for RawWindow {
|
||||||
|
fn raw_display_handle(&self) -> blade_rwh::RawDisplayHandle {
|
||||||
|
let dh = blade_rwh::AppKitDisplayHandle::empty();
|
||||||
|
dh.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gpu = Arc::new(
|
||||||
|
gpu::Context::init_windowed(
|
||||||
|
&RawWindow {
|
||||||
|
window: native_window as *mut _,
|
||||||
|
view: native_view as *mut _,
|
||||||
|
},
|
||||||
|
gpu::ContextDesc {
|
||||||
|
validation: cfg!(debug_assertions),
|
||||||
|
capture: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
BladeRenderer::new(
|
||||||
|
gpu,
|
||||||
|
gpu::Extent {
|
||||||
|
width: bounds.width as u32,
|
||||||
|
height: bounds.height as u32,
|
||||||
|
depth: 1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
struct GlobalParams {
|
struct GlobalParams {
|
||||||
@ -23,6 +82,31 @@ struct GlobalParams {
|
|||||||
pad: [u32; 2],
|
pad: [u32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Note: we can't use `Bounds` directly here because
|
||||||
|
// it doesn't implement Pod + Zeroable
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
|
struct PodBounds {
|
||||||
|
origin: [f32; 2],
|
||||||
|
size: [f32; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Bounds<ScaledPixels>> for PodBounds {
|
||||||
|
fn from(bounds: Bounds<ScaledPixels>) -> Self {
|
||||||
|
Self {
|
||||||
|
origin: [bounds.origin.x.0, bounds.origin.y.0],
|
||||||
|
size: [bounds.size.width.0, bounds.size.height.0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
|
struct SurfaceParams {
|
||||||
|
bounds: PodBounds,
|
||||||
|
content_mask: PodBounds,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(blade_macros::ShaderData)]
|
#[derive(blade_macros::ShaderData)]
|
||||||
struct ShaderQuadsData {
|
struct ShaderQuadsData {
|
||||||
globals: GlobalParams,
|
globals: GlobalParams,
|
||||||
@ -71,6 +155,15 @@ struct ShaderPolySpritesData {
|
|||||||
b_poly_sprites: gpu::BufferPiece,
|
b_poly_sprites: gpu::BufferPiece,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(blade_macros::ShaderData)]
|
||||||
|
struct ShaderSurfacesData {
|
||||||
|
globals: GlobalParams,
|
||||||
|
surface_locals: SurfaceParams,
|
||||||
|
t_y: gpu::TextureView,
|
||||||
|
t_cb_cr: gpu::TextureView,
|
||||||
|
s_surface: gpu::Sampler,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct PathSprite {
|
struct PathSprite {
|
||||||
@ -87,6 +180,7 @@ struct BladePipelines {
|
|||||||
underlines: gpu::RenderPipeline,
|
underlines: gpu::RenderPipeline,
|
||||||
mono_sprites: gpu::RenderPipeline,
|
mono_sprites: gpu::RenderPipeline,
|
||||||
poly_sprites: gpu::RenderPipeline,
|
poly_sprites: gpu::RenderPipeline,
|
||||||
|
surfaces: gpu::RenderPipeline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BladePipelines {
|
impl BladePipelines {
|
||||||
@ -96,6 +190,8 @@ impl BladePipelines {
|
|||||||
let shader = gpu.create_shader(gpu::ShaderDesc {
|
let shader = gpu.create_shader(gpu::ShaderDesc {
|
||||||
source: include_str!("shaders.wgsl"),
|
source: include_str!("shaders.wgsl"),
|
||||||
});
|
});
|
||||||
|
shader.check_struct_size::<GlobalParams>();
|
||||||
|
shader.check_struct_size::<SurfaceParams>();
|
||||||
shader.check_struct_size::<Quad>();
|
shader.check_struct_size::<Quad>();
|
||||||
shader.check_struct_size::<Shadow>();
|
shader.check_struct_size::<Shadow>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -220,6 +316,22 @@ impl BladePipelines {
|
|||||||
write_mask: gpu::ColorWrites::default(),
|
write_mask: gpu::ColorWrites::default(),
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
|
surfaces: gpu.create_render_pipeline(gpu::RenderPipelineDesc {
|
||||||
|
name: "surfaces",
|
||||||
|
data_layouts: &[&ShaderSurfacesData::layout()],
|
||||||
|
vertex: shader.at("vs_surface"),
|
||||||
|
primitive: gpu::PrimitiveState {
|
||||||
|
topology: gpu::PrimitiveTopology::TriangleStrip,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
depth_stencil: None,
|
||||||
|
fragment: shader.at("fs_surface"),
|
||||||
|
color_targets: &[gpu::ColorTargetState {
|
||||||
|
format: surface_format,
|
||||||
|
blend: Some(gpu::BlendState::ALPHA_BLENDING),
|
||||||
|
write_mask: gpu::ColorWrites::default(),
|
||||||
|
}],
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,6 +346,8 @@ pub struct BladeRenderer {
|
|||||||
path_tiles: HashMap<PathId, AtlasTile>,
|
path_tiles: HashMap<PathId, AtlasTile>,
|
||||||
atlas: Arc<BladeAtlas>,
|
atlas: Arc<BladeAtlas>,
|
||||||
atlas_sampler: gpu::Sampler,
|
atlas_sampler: gpu::Sampler,
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
core_video_texture_cache: CVMetalTextureCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BladeRenderer {
|
impl BladeRenderer {
|
||||||
@ -268,6 +382,12 @@ impl BladeRenderer {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
let core_video_texture_cache = unsafe {
|
||||||
|
use foreign_types::ForeignType as _;
|
||||||
|
CVMetalTextureCache::new(gpu.metal_device().as_ptr()).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
gpu,
|
gpu,
|
||||||
command_encoder,
|
command_encoder,
|
||||||
@ -278,6 +398,8 @@ impl BladeRenderer {
|
|||||||
path_tiles: HashMap::default(),
|
path_tiles: HashMap::default(),
|
||||||
atlas,
|
atlas,
|
||||||
atlas_sampler,
|
atlas_sampler,
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
core_video_texture_cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,27 +411,39 @@ impl BladeRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(&mut self) {
|
pub fn update_drawable_size(&mut self, size: Size<f64>) {
|
||||||
self.wait_for_gpu();
|
let gpu_size = gpu::Extent {
|
||||||
self.atlas.destroy();
|
width: size.width as u32,
|
||||||
self.instance_belt.destroy(&self.gpu);
|
height: size.height as u32,
|
||||||
self.gpu.destroy_command_encoder(&mut self.command_encoder);
|
depth: 1,
|
||||||
}
|
};
|
||||||
|
|
||||||
pub fn resize(&mut self, size: gpu::Extent) {
|
if gpu_size != self.viewport_size() {
|
||||||
self.wait_for_gpu();
|
self.wait_for_gpu();
|
||||||
self.gpu.resize(Self::make_surface_config(size));
|
self.gpu.resize(Self::make_surface_config(gpu_size));
|
||||||
self.viewport_size = size;
|
self.viewport_size = gpu_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn viewport_size(&self) -> gpu::Extent {
|
pub fn viewport_size(&self) -> gpu::Extent {
|
||||||
self.viewport_size
|
self.viewport_size
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn atlas(&self) -> &Arc<BladeAtlas> {
|
pub fn sprite_atlas(&self) -> &Arc<BladeAtlas> {
|
||||||
&self.atlas
|
&self.atlas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub fn layer(&self) -> metal::MetalLayer {
|
||||||
|
self.gpu.metal_layer().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub fn layer_ptr(&self) -> *mut metal::CAMetalLayer {
|
||||||
|
use metal::foreign_types::ForeignType as _;
|
||||||
|
self.gpu.metal_layer().unwrap().as_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
fn rasterize_paths(&mut self, paths: &[Path<ScaledPixels>]) {
|
fn rasterize_paths(&mut self, paths: &[Path<ScaledPixels>]) {
|
||||||
self.path_tiles.clear();
|
self.path_tiles.clear();
|
||||||
let mut vertices_by_texture_id = HashMap::default();
|
let mut vertices_by_texture_id = HashMap::default();
|
||||||
@ -362,6 +496,13 @@ impl BladeRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn destroy(&mut self) {
|
||||||
|
self.wait_for_gpu();
|
||||||
|
self.atlas.destroy();
|
||||||
|
self.instance_belt.destroy(&self.gpu);
|
||||||
|
self.gpu.destroy_command_encoder(&mut self.command_encoder);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw(&mut self, scene: &Scene) {
|
pub fn draw(&mut self, scene: &Scene) {
|
||||||
let frame = self.gpu.acquire_frame();
|
let frame = self.gpu.acquire_frame();
|
||||||
self.command_encoder.start();
|
self.command_encoder.start();
|
||||||
@ -495,8 +636,78 @@ impl BladeRenderer {
|
|||||||
);
|
);
|
||||||
encoder.draw(0, 4, 0, sprites.len() as u32);
|
encoder.draw(0, 4, 0, sprites.len() as u32);
|
||||||
}
|
}
|
||||||
PrimitiveBatch::Surfaces { .. } => {
|
PrimitiveBatch::Surfaces(surfaces) => {
|
||||||
unimplemented!()
|
let mut _encoder = pass.with(&self.pipelines.surfaces);
|
||||||
|
|
||||||
|
for surface in surfaces {
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
{
|
||||||
|
let _ = surface;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
{
|
||||||
|
let (t_y, t_cb_cr) = {
|
||||||
|
use core_foundation::base::TCFType as _;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
surface.image_buffer.pixel_format_type(),
|
||||||
|
media::core_video::kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
|
||||||
|
);
|
||||||
|
|
||||||
|
let y_texture = unsafe {
|
||||||
|
self.core_video_texture_cache
|
||||||
|
.create_texture_from_image(
|
||||||
|
surface.image_buffer.as_concrete_TypeRef(),
|
||||||
|
ptr::null(),
|
||||||
|
metal::MTLPixelFormat::R8Unorm,
|
||||||
|
surface.image_buffer.plane_width(0),
|
||||||
|
surface.image_buffer.plane_height(0),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
let cb_cr_texture = unsafe {
|
||||||
|
self.core_video_texture_cache
|
||||||
|
.create_texture_from_image(
|
||||||
|
surface.image_buffer.as_concrete_TypeRef(),
|
||||||
|
ptr::null(),
|
||||||
|
metal::MTLPixelFormat::RG8Unorm,
|
||||||
|
surface.image_buffer.plane_width(1),
|
||||||
|
surface.image_buffer.plane_height(1),
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
(
|
||||||
|
gpu::TextureView::from_metal_texture(
|
||||||
|
y_texture.as_texture_ref(),
|
||||||
|
),
|
||||||
|
gpu::TextureView::from_metal_texture(
|
||||||
|
cb_cr_texture.as_texture_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
_encoder.bind(
|
||||||
|
0,
|
||||||
|
&ShaderSurfacesData {
|
||||||
|
globals,
|
||||||
|
surface_locals: SurfaceParams {
|
||||||
|
bounds: surface.bounds.into(),
|
||||||
|
content_mask: surface.content_mask.bounds.into(),
|
||||||
|
},
|
||||||
|
t_y,
|
||||||
|
t_cb_cr,
|
||||||
|
s_surface: self.atlas_sampler,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
_encoder.draw(0, 4, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
struct Globals {
|
struct GlobalParams {
|
||||||
viewport_size: vec2<f32>,
|
viewport_size: vec2<f32>,
|
||||||
pad: vec2<u32>,
|
pad: vec2<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
var<uniform> globals: Globals;
|
var<uniform> globals: GlobalParams;
|
||||||
var t_sprite: texture_2d<f32>;
|
var t_sprite: texture_2d<f32>;
|
||||||
var s_sprite: sampler;
|
var s_sprite: sampler;
|
||||||
|
|
||||||
@ -563,7 +563,56 @@ fn fs_poly_sprite(input: PolySpriteVarying) -> @location(0) vec4<f32> {
|
|||||||
color = vec4<f32>(vec3<f32>(grayscale), sample.a);
|
color = vec4<f32>(vec3<f32>(grayscale), sample.a);
|
||||||
}
|
}
|
||||||
color.a *= saturate(0.5 - distance);
|
color.a *= saturate(0.5 - distance);
|
||||||
return color;;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- surface sprites --- //
|
// --- surfaces --- //
|
||||||
|
|
||||||
|
struct SurfaceParams {
|
||||||
|
bounds: Bounds,
|
||||||
|
content_mask: Bounds,
|
||||||
|
}
|
||||||
|
|
||||||
|
var<uniform> surface_locals: SurfaceParams;
|
||||||
|
var t_y: texture_2d<f32>;
|
||||||
|
var t_cb_cr: texture_2d<f32>;
|
||||||
|
var s_surface: sampler;
|
||||||
|
|
||||||
|
const ycbcr_to_RGB = mat4x4<f32>(
|
||||||
|
vec4<f32>( 1.0000f, 1.0000f, 1.0000f, 0.0),
|
||||||
|
vec4<f32>( 0.0000f, -0.3441f, 1.7720f, 0.0),
|
||||||
|
vec4<f32>( 1.4020f, -0.7141f, 0.0000f, 0.0),
|
||||||
|
vec4<f32>(-0.7010f, 0.5291f, -0.8860f, 1.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
struct SurfaceVarying {
|
||||||
|
@builtin(position) position: vec4<f32>,
|
||||||
|
@location(0) texture_position: vec2<f32>,
|
||||||
|
@location(3) clip_distances: vec4<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_surface(@builtin(vertex_index) vertex_id: u32) -> SurfaceVarying {
|
||||||
|
let unit_vertex = vec2<f32>(f32(vertex_id & 1u), 0.5 * f32(vertex_id & 2u));
|
||||||
|
|
||||||
|
var out = SurfaceVarying();
|
||||||
|
out.position = to_device_position(unit_vertex, surface_locals.bounds);
|
||||||
|
out.texture_position = unit_vertex;
|
||||||
|
out.clip_distances = distance_from_clip_rect(unit_vertex, surface_locals.bounds, surface_locals.content_mask);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fs_surface(input: SurfaceVarying) -> @location(0) vec4<f32> {
|
||||||
|
// Alpha clip after using the derivatives.
|
||||||
|
if (any(input.clip_distances < vec4<f32>(0.0))) {
|
||||||
|
return vec4<f32>(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let y_cb_cr = vec4<f32>(
|
||||||
|
textureSampleLevel(t_y, s_surface, input.texture_position, 0.0).r,
|
||||||
|
textureSampleLevel(t_cb_cr, s_surface, input.texture_position, 0.0).rg,
|
||||||
|
1.0);
|
||||||
|
|
||||||
|
return ycbcr_to_RGB * y_cb_cr;
|
||||||
|
}
|
@ -1,6 +1,3 @@
|
|||||||
mod blade_atlas;
|
|
||||||
mod blade_belt;
|
|
||||||
mod blade_renderer;
|
|
||||||
mod client;
|
mod client;
|
||||||
mod client_dispatcher;
|
mod client_dispatcher;
|
||||||
mod dispatcher;
|
mod dispatcher;
|
||||||
@ -9,10 +6,7 @@ mod text_system;
|
|||||||
mod wayland;
|
mod wayland;
|
||||||
mod x11;
|
mod x11;
|
||||||
|
|
||||||
pub(crate) use blade_atlas::*;
|
|
||||||
pub(crate) use dispatcher::*;
|
pub(crate) use dispatcher::*;
|
||||||
pub(crate) use platform::*;
|
pub(crate) use platform::*;
|
||||||
pub(crate) use text_system::*;
|
pub(crate) use text_system::*;
|
||||||
pub(crate) use x11::*;
|
pub(crate) use x11::*;
|
||||||
|
|
||||||
use blade_belt::*;
|
|
||||||
|
@ -13,12 +13,12 @@ use raw_window_handle::{
|
|||||||
use wayland_client::{protocol::wl_surface, Proxy};
|
use wayland_client::{protocol::wl_surface, Proxy};
|
||||||
use wayland_protocols::xdg::shell::client::xdg_toplevel;
|
use wayland_protocols::xdg::shell::client::xdg_toplevel;
|
||||||
|
|
||||||
use crate::platform::linux::blade_renderer::BladeRenderer;
|
use crate::platform::blade::BladeRenderer;
|
||||||
use crate::platform::linux::wayland::display::WaylandDisplay;
|
use crate::platform::linux::wayland::display::WaylandDisplay;
|
||||||
use crate::platform::{PlatformAtlas, PlatformInputHandler, PlatformWindow};
|
use crate::platform::{PlatformAtlas, PlatformInputHandler, PlatformWindow};
|
||||||
use crate::scene::Scene;
|
use crate::scene::Scene;
|
||||||
use crate::{
|
use crate::{
|
||||||
px, Bounds, Modifiers, Pixels, PlatformDisplay, PlatformInput, Point, PromptLevel, Size,
|
px, size, Bounds, Modifiers, Pixels, PlatformDisplay, PlatformInput, Point, PromptLevel, Size,
|
||||||
WindowAppearance, WindowBounds, WindowOptions,
|
WindowAppearance, WindowBounds, WindowOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -150,11 +150,9 @@ impl WaylandWindowState {
|
|||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner.bounds.size.width = width;
|
inner.bounds.size.width = width;
|
||||||
inner.bounds.size.height = height;
|
inner.bounds.size.height = height;
|
||||||
inner.renderer.resize(gpu::Extent {
|
inner
|
||||||
width: width as u32,
|
.renderer
|
||||||
height: height as u32,
|
.update_drawable_size(size(width as f64, height as f64));
|
||||||
depth: 1,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
let mut callbacks = self.callbacks.lock();
|
let mut callbacks = self.callbacks.lock();
|
||||||
if let Some(ref mut fun) = callbacks.resize {
|
if let Some(ref mut fun) = callbacks.resize {
|
||||||
@ -341,7 +339,7 @@ impl PlatformWindow for WaylandWindow {
|
|||||||
|
|
||||||
fn sprite_atlas(&self) -> Arc<dyn PlatformAtlas> {
|
fn sprite_atlas(&self) -> Arc<dyn PlatformAtlas> {
|
||||||
let inner = self.0.inner.lock();
|
let inner = self.0.inner.lock();
|
||||||
inner.renderer.atlas().clone()
|
inner.renderer.sprite_atlas().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_graphics_profiler_enabled(&self, enabled: bool) {
|
fn set_graphics_profiler_enabled(&self, enabled: bool) {
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
//todo!(linux): remove
|
//todo!(linux): remove
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
platform::blade::BladeRenderer, size, Bounds, GlobalPixels, Pixels, PlatformDisplay,
|
||||||
|
PlatformInput, PlatformInputHandler, PlatformWindow, Point, Size, WindowAppearance,
|
||||||
|
WindowBounds, WindowOptions, X11Display,
|
||||||
|
};
|
||||||
|
use blade_graphics as gpu;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use raw_window_handle as rwh;
|
||||||
|
|
||||||
|
use xcb::{
|
||||||
|
x::{self, StackMode},
|
||||||
|
Xid as _,
|
||||||
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
mem,
|
mem,
|
||||||
@ -10,17 +24,6 @@ use std::{
|
|||||||
sync::{self, Arc},
|
sync::{self, Arc},
|
||||||
};
|
};
|
||||||
|
|
||||||
use blade_graphics as gpu;
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
use raw_window_handle as rwh;
|
|
||||||
use xcb::{x, Xid as _};
|
|
||||||
|
|
||||||
use crate::platform::linux::blade_renderer::BladeRenderer;
|
|
||||||
use crate::{
|
|
||||||
Bounds, GlobalPixels, Pixels, PlatformDisplay, PlatformInput, PlatformInputHandler,
|
|
||||||
PlatformWindow, Point, Size, WindowAppearance, WindowBounds, WindowOptions, X11Display,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Callbacks {
|
struct Callbacks {
|
||||||
request_frame: Option<Box<dyn FnMut()>>,
|
request_frame: Option<Box<dyn FnMut()>>,
|
||||||
@ -293,9 +296,13 @@ impl X11WindowState {
|
|||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
let old_bounds = mem::replace(&mut inner.bounds, bounds);
|
let old_bounds = mem::replace(&mut inner.bounds, bounds);
|
||||||
do_move = old_bounds.origin != bounds.origin;
|
do_move = old_bounds.origin != bounds.origin;
|
||||||
|
//todo!(linux): use normal GPUI types here, refactor out the double
|
||||||
|
// viewport check and extra casts ( )
|
||||||
let gpu_size = query_render_extent(&self.xcb_connection, self.x_window);
|
let gpu_size = query_render_extent(&self.xcb_connection, self.x_window);
|
||||||
if inner.renderer.viewport_size() != gpu_size {
|
if inner.renderer.viewport_size() != gpu_size {
|
||||||
inner.renderer.resize(gpu_size);
|
inner
|
||||||
|
.renderer
|
||||||
|
.update_drawable_size(size(gpu_size.width as f64, gpu_size.height as f64));
|
||||||
resize_args = Some((inner.content_size(), inner.scale_factor));
|
resize_args = Some((inner.content_size(), inner.scale_factor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,7 +500,7 @@ impl PlatformWindow for X11Window {
|
|||||||
|
|
||||||
fn sprite_atlas(&self) -> sync::Arc<dyn crate::PlatformAtlas> {
|
fn sprite_atlas(&self) -> sync::Arc<dyn crate::PlatformAtlas> {
|
||||||
let inner = self.0.inner.lock();
|
let inner = self.0.inner.lock();
|
||||||
inner.renderer.atlas().clone()
|
inner.renderer.sprite_atlas().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_graphics_profiler_enabled(&self, enabled: bool) {
|
fn set_graphics_profiler_enabled(&self, enabled: bool) {
|
||||||
|
@ -4,8 +4,18 @@ mod dispatcher;
|
|||||||
mod display;
|
mod display;
|
||||||
mod display_link;
|
mod display_link;
|
||||||
mod events;
|
mod events;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "macos-blade"))]
|
||||||
mod metal_atlas;
|
mod metal_atlas;
|
||||||
mod metal_renderer;
|
#[cfg(not(feature = "macos-blade"))]
|
||||||
|
pub mod metal_renderer;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "macos-blade"))]
|
||||||
|
use metal_renderer as renderer;
|
||||||
|
|
||||||
|
#[cfg(feature = "macos-blade")]
|
||||||
|
use crate::platform::blade as renderer;
|
||||||
|
|
||||||
mod open_type;
|
mod open_type;
|
||||||
mod platform;
|
mod platform;
|
||||||
mod text_system;
|
mod text_system;
|
||||||
@ -17,14 +27,13 @@ use cocoa::{
|
|||||||
base::{id, nil},
|
base::{id, nil},
|
||||||
foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger},
|
foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger},
|
||||||
};
|
};
|
||||||
use metal_renderer::*;
|
|
||||||
use objc::runtime::{BOOL, NO, YES};
|
use objc::runtime::{BOOL, NO, YES};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
pub(crate) use dispatcher::*;
|
pub(crate) use dispatcher::*;
|
||||||
pub(crate) use display::*;
|
pub(crate) use display::*;
|
||||||
pub(crate) use display_link::*;
|
pub(crate) use display_link::*;
|
||||||
pub(crate) use metal_atlas::*;
|
|
||||||
pub(crate) use platform::*;
|
pub(crate) use platform::*;
|
||||||
pub(crate) use text_system::*;
|
pub(crate) use text_system::*;
|
||||||
pub(crate) use window::*;
|
pub(crate) use window::*;
|
||||||
|
@ -111,11 +111,11 @@ mod sys {
|
|||||||
pub enum CVDisplayLink {}
|
pub enum CVDisplayLink {}
|
||||||
|
|
||||||
foreign_type! {
|
foreign_type! {
|
||||||
|
pub unsafe type DisplayLink {
|
||||||
type CType = CVDisplayLink;
|
type CType = CVDisplayLink;
|
||||||
fn drop = CVDisplayLinkRelease;
|
fn drop = CVDisplayLinkRelease;
|
||||||
fn clone = CVDisplayLinkRetain;
|
fn clone = CVDisplayLinkRetain;
|
||||||
pub struct DisplayLink;
|
}
|
||||||
pub struct DisplayLinkRef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for DisplayLink {
|
impl Debug for DisplayLink {
|
||||||
|
@ -13,7 +13,7 @@ use core_graphics::{
|
|||||||
event_source::{CGEventSource, CGEventSourceStateID},
|
event_source::{CGEventSource, CGEventSourceStateID},
|
||||||
};
|
};
|
||||||
use ctor::ctor;
|
use ctor::ctor;
|
||||||
use foreign_types::ForeignType;
|
use metal::foreign_types::ForeignType as _;
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
use std::{borrow::Cow, ffi::CStr, mem, os::raw::c_char, ptr};
|
use std::{borrow::Cow, ffi::CStr, mem, os::raw::c_char, ptr};
|
||||||
|
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
|
use super::metal_atlas::MetalAtlas;
|
||||||
use crate::{
|
use crate::{
|
||||||
platform::mac::ns_string, point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds,
|
point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels,
|
||||||
ContentMask, DevicePixels, Hsla, MetalAtlas, MonochromeSprite, Path, PathId, PathVertex,
|
Hsla, MonochromeSprite, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad,
|
||||||
PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size, Surface, Underline,
|
ScaledPixels, Scene, Shadow, Size, Surface, Underline,
|
||||||
};
|
};
|
||||||
use block::ConcreteBlock;
|
use block::ConcreteBlock;
|
||||||
use cocoa::{
|
use cocoa::{
|
||||||
base::{nil, NO, YES},
|
base::{NO, YES},
|
||||||
foundation::{NSDictionary, NSUInteger},
|
foundation::NSUInteger,
|
||||||
quartzcore::AutoresizingMask,
|
quartzcore::AutoresizingMask,
|
||||||
};
|
};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use core_foundation::base::TCFType;
|
use core_foundation::base::TCFType;
|
||||||
use foreign_types::ForeignType;
|
use foreign_types::ForeignType;
|
||||||
use media::core_video::CVMetalTextureCache;
|
use media::core_video::CVMetalTextureCache;
|
||||||
use metal::{CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange};
|
use metal::{CAMetalLayer, CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange};
|
||||||
use objc::{self, msg_send, sel, sel_impl};
|
use objc::{self, msg_send, sel, sel_impl};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -29,6 +30,18 @@ const SHADERS_SOURCE_FILE: &'static str =
|
|||||||
include_str!(concat!(env!("OUT_DIR"), "/stitched_shaders.metal"));
|
include_str!(concat!(env!("OUT_DIR"), "/stitched_shaders.metal"));
|
||||||
const INSTANCE_BUFFER_SIZE: usize = 2 * 1024 * 1024; // This is an arbitrary decision. There's probably a more optimal value (maybe even we could adjust dynamically...)
|
const INSTANCE_BUFFER_SIZE: usize = 2 * 1024 * 1024; // This is an arbitrary decision. There's probably a more optimal value (maybe even we could adjust dynamically...)
|
||||||
|
|
||||||
|
pub type Context = Arc<Mutex<Vec<metal::Buffer>>>;
|
||||||
|
pub type Renderer = MetalRenderer;
|
||||||
|
|
||||||
|
pub unsafe fn new_renderer(
|
||||||
|
context: self::Context,
|
||||||
|
_native_window: *mut c_void,
|
||||||
|
_native_view: *mut c_void,
|
||||||
|
_bounds: crate::Size<f32>,
|
||||||
|
) -> Renderer {
|
||||||
|
MetalRenderer::new(context)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct MetalRenderer {
|
pub(crate) struct MetalRenderer {
|
||||||
device: metal::Device,
|
device: metal::Device,
|
||||||
layer: metal::MetalLayer,
|
layer: metal::MetalLayer,
|
||||||
@ -196,25 +209,12 @@ impl MetalRenderer {
|
|||||||
&self.layer
|
&self.layer
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sprite_atlas(&self) -> &Arc<MetalAtlas> {
|
pub fn layer_ptr(&self) -> *mut CAMetalLayer {
|
||||||
&self.sprite_atlas
|
self.layer.as_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables or disables the Metal HUD for debugging purposes. Note that this only works
|
pub fn sprite_atlas(&self) -> &Arc<MetalAtlas> {
|
||||||
/// when the app is bundled and it has the `MetalHudEnabled` key set to true in Info.plist.
|
&self.sprite_atlas
|
||||||
pub fn set_hud_enabled(&mut self, enabled: bool) {
|
|
||||||
unsafe {
|
|
||||||
if enabled {
|
|
||||||
let hud_properties = NSDictionary::dictionaryWithObject_forKey_(
|
|
||||||
nil,
|
|
||||||
ns_string("default"),
|
|
||||||
ns_string("mode"),
|
|
||||||
);
|
|
||||||
let _: () = msg_send![&*self.layer, setDeveloperHUDProperties: hud_properties];
|
|
||||||
} else {
|
|
||||||
let _: () = msg_send![&*self.layer, setDeveloperHUDProperties: NSDictionary::dictionary(nil)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_presents_with_transaction(&mut self, presents_with_transaction: bool) {
|
pub fn set_presents_with_transaction(&mut self, presents_with_transaction: bool) {
|
||||||
@ -223,6 +223,19 @@ impl MetalRenderer {
|
|||||||
.set_presents_with_transaction(presents_with_transaction);
|
.set_presents_with_transaction(presents_with_transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_drawable_size(&mut self, size: Size<f64>) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![
|
||||||
|
self.layer(),
|
||||||
|
setDrawableSize: size
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(&mut self) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw(&mut self, scene: &Scene) {
|
pub fn draw(&mut self, scene: &Scene) {
|
||||||
let layer = self.layer.clone();
|
let layer = self.layer.clone();
|
||||||
let viewport_size = layer.drawable_size();
|
let viewport_size = layer.drawable_size();
|
||||||
|
@ -52,6 +52,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
use time::UtcOffset;
|
use time::UtcOffset;
|
||||||
|
|
||||||
|
use super::renderer;
|
||||||
|
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
const NSUTF8StringEncoding: NSUInteger = 4;
|
const NSUTF8StringEncoding: NSUInteger = 4;
|
||||||
|
|
||||||
@ -145,7 +147,7 @@ pub(crate) struct MacPlatformState {
|
|||||||
background_executor: BackgroundExecutor,
|
background_executor: BackgroundExecutor,
|
||||||
foreground_executor: ForegroundExecutor,
|
foreground_executor: ForegroundExecutor,
|
||||||
text_system: Arc<MacTextSystem>,
|
text_system: Arc<MacTextSystem>,
|
||||||
instance_buffer_pool: Arc<Mutex<Vec<metal::Buffer>>>,
|
renderer_context: renderer::Context,
|
||||||
pasteboard: id,
|
pasteboard: id,
|
||||||
text_hash_pasteboard_type: id,
|
text_hash_pasteboard_type: id,
|
||||||
metadata_pasteboard_type: id,
|
metadata_pasteboard_type: id,
|
||||||
@ -175,7 +177,7 @@ impl MacPlatform {
|
|||||||
background_executor: BackgroundExecutor::new(dispatcher.clone()),
|
background_executor: BackgroundExecutor::new(dispatcher.clone()),
|
||||||
foreground_executor: ForegroundExecutor::new(dispatcher),
|
foreground_executor: ForegroundExecutor::new(dispatcher),
|
||||||
text_system: Arc::new(MacTextSystem::new()),
|
text_system: Arc::new(MacTextSystem::new()),
|
||||||
instance_buffer_pool: Arc::default(),
|
renderer_context: renderer::Context::default(),
|
||||||
pasteboard: unsafe { NSPasteboard::generalPasteboard(nil) },
|
pasteboard: unsafe { NSPasteboard::generalPasteboard(nil) },
|
||||||
text_hash_pasteboard_type: unsafe { ns_string("zed-text-hash") },
|
text_hash_pasteboard_type: unsafe { ns_string("zed-text-hash") },
|
||||||
metadata_pasteboard_type: unsafe { ns_string("zed-metadata") },
|
metadata_pasteboard_type: unsafe { ns_string("zed-metadata") },
|
||||||
@ -494,12 +496,11 @@ impl Platform for MacPlatform {
|
|||||||
handle: AnyWindowHandle,
|
handle: AnyWindowHandle,
|
||||||
options: WindowOptions,
|
options: WindowOptions,
|
||||||
) -> Box<dyn PlatformWindow> {
|
) -> Box<dyn PlatformWindow> {
|
||||||
let instance_buffer_pool = self.0.lock().instance_buffer_pool.clone();
|
|
||||||
Box::new(MacWindow::open(
|
Box::new(MacWindow::open(
|
||||||
handle,
|
handle,
|
||||||
options,
|
options,
|
||||||
self.foreground_executor(),
|
self.foreground_executor(),
|
||||||
instance_buffer_pool,
|
self.0.lock().renderer_context.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::{global_bounds_from_ns_rect, ns_string, MacDisplay, MetalRenderer, NSRange};
|
use super::{global_bounds_from_ns_rect, ns_string, renderer, MacDisplay, NSRange};
|
||||||
use crate::{
|
use crate::{
|
||||||
global_bounds_to_ns_rect, platform::PlatformInputHandler, point, px, size, AnyWindowHandle,
|
global_bounds_to_ns_rect, platform::PlatformInputHandler, point, px, size, AnyWindowHandle,
|
||||||
Bounds, DisplayLink, ExternalPaths, FileDropEvent, ForegroundExecutor, GlobalPixels,
|
Bounds, DisplayLink, ExternalPaths, FileDropEvent, ForegroundExecutor, GlobalPixels,
|
||||||
@ -23,7 +23,6 @@ use cocoa::{
|
|||||||
};
|
};
|
||||||
use core_graphics::display::{CGDirectDisplayID, CGRect};
|
use core_graphics::display::{CGDirectDisplayID, CGRect};
|
||||||
use ctor::ctor;
|
use ctor::ctor;
|
||||||
use foreign_types::ForeignTypeRef;
|
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
use objc::{
|
use objc::{
|
||||||
class,
|
class,
|
||||||
@ -322,7 +321,7 @@ struct MacWindowState {
|
|||||||
native_window: id,
|
native_window: id,
|
||||||
native_view: NonNull<Object>,
|
native_view: NonNull<Object>,
|
||||||
display_link: Option<DisplayLink>,
|
display_link: Option<DisplayLink>,
|
||||||
renderer: MetalRenderer,
|
renderer: renderer::Renderer,
|
||||||
kind: WindowKind,
|
kind: WindowKind,
|
||||||
request_frame_callback: Option<Box<dyn FnMut()>>,
|
request_frame_callback: Option<Box<dyn FnMut()>>,
|
||||||
event_callback: Option<Box<dyn FnMut(PlatformInput) -> bool>>,
|
event_callback: Option<Box<dyn FnMut(PlatformInput) -> bool>>,
|
||||||
@ -450,6 +449,13 @@ impl MacWindowState {
|
|||||||
get_scale_factor(self.native_window)
|
get_scale_factor(self.native_window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_drawable_size(&mut self, drawable_size: NSSize) {
|
||||||
|
self.renderer.update_drawable_size(Size {
|
||||||
|
width: drawable_size.width,
|
||||||
|
height: drawable_size.height,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn titlebar_height(&self) -> Pixels {
|
fn titlebar_height(&self) -> Pixels {
|
||||||
unsafe {
|
unsafe {
|
||||||
let frame = NSWindow::frame(self.native_window);
|
let frame = NSWindow::frame(self.native_window);
|
||||||
@ -478,7 +484,7 @@ impl MacWindow {
|
|||||||
handle: AnyWindowHandle,
|
handle: AnyWindowHandle,
|
||||||
options: WindowOptions,
|
options: WindowOptions,
|
||||||
executor: ForegroundExecutor,
|
executor: ForegroundExecutor,
|
||||||
instance_buffer_pool: Arc<Mutex<Vec<metal::Buffer>>>,
|
renderer_context: renderer::Context,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let pool = NSAutoreleasePool::new(nil);
|
let pool = NSAutoreleasePool::new(nil);
|
||||||
@ -541,13 +547,32 @@ impl MacWindow {
|
|||||||
let native_view = NSView::init(native_view);
|
let native_view = NSView::init(native_view);
|
||||||
assert!(!native_view.is_null());
|
assert!(!native_view.is_null());
|
||||||
|
|
||||||
|
let window_size = {
|
||||||
|
let bounds = match options.bounds {
|
||||||
|
WindowBounds::Fullscreen | WindowBounds::Maximized => {
|
||||||
|
native_window.screen().visibleFrame()
|
||||||
|
}
|
||||||
|
WindowBounds::Fixed(bounds) => global_bounds_to_ns_rect(bounds),
|
||||||
|
};
|
||||||
|
let scale = get_scale_factor(native_window);
|
||||||
|
size(
|
||||||
|
bounds.size.width as f32 * scale,
|
||||||
|
bounds.size.height as f32 * scale,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let window = Self(Arc::new(Mutex::new(MacWindowState {
|
let window = Self(Arc::new(Mutex::new(MacWindowState {
|
||||||
handle,
|
handle,
|
||||||
executor,
|
executor,
|
||||||
native_window,
|
native_window,
|
||||||
native_view: NonNull::new_unchecked(native_view),
|
native_view: NonNull::new_unchecked(native_view),
|
||||||
display_link: None,
|
display_link: None,
|
||||||
renderer: MetalRenderer::new(instance_buffer_pool),
|
renderer: renderer::new_renderer(
|
||||||
|
renderer_context,
|
||||||
|
native_window as *mut _,
|
||||||
|
native_view as *mut _,
|
||||||
|
window_size,
|
||||||
|
),
|
||||||
kind: options.kind,
|
kind: options.kind,
|
||||||
request_frame_callback: None,
|
request_frame_callback: None,
|
||||||
event_callback: None,
|
event_callback: None,
|
||||||
@ -704,6 +729,7 @@ impl MacWindow {
|
|||||||
impl Drop for MacWindow {
|
impl Drop for MacWindow {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut this = self.0.lock();
|
let mut this = self.0.lock();
|
||||||
|
this.renderer.destroy();
|
||||||
let window = this.native_window;
|
let window = this.native_window;
|
||||||
this.display_link.take();
|
this.display_link.take();
|
||||||
this.executor
|
this.executor
|
||||||
@ -1031,7 +1057,22 @@ impl PlatformWindow for MacWindow {
|
|||||||
/// Enables or disables the Metal HUD for debugging purposes. Note that this only works
|
/// Enables or disables the Metal HUD for debugging purposes. Note that this only works
|
||||||
/// when the app is bundled and it has the `MetalHudEnabled` key set to true in Info.plist.
|
/// when the app is bundled and it has the `MetalHudEnabled` key set to true in Info.plist.
|
||||||
fn set_graphics_profiler_enabled(&self, enabled: bool) {
|
fn set_graphics_profiler_enabled(&self, enabled: bool) {
|
||||||
self.0.lock().renderer.set_hud_enabled(enabled);
|
let this_lock = self.0.lock();
|
||||||
|
let layer = this_lock.renderer.layer();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
if enabled {
|
||||||
|
let hud_properties = NSDictionary::dictionaryWithObject_forKey_(
|
||||||
|
nil,
|
||||||
|
ns_string("default"),
|
||||||
|
ns_string("mode"),
|
||||||
|
);
|
||||||
|
let _: () = msg_send![layer, setDeveloperHUDProperties: hud_properties];
|
||||||
|
} else {
|
||||||
|
let _: () =
|
||||||
|
msg_send![layer, setDeveloperHUDProperties: NSDictionary::dictionary(nil)];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1487,31 +1528,28 @@ extern "C" fn close_window(this: &Object, _: Sel) {
|
|||||||
extern "C" fn make_backing_layer(this: &Object, _: Sel) -> id {
|
extern "C" fn make_backing_layer(this: &Object, _: Sel) -> id {
|
||||||
let window_state = unsafe { get_window_state(this) };
|
let window_state = unsafe { get_window_state(this) };
|
||||||
let window_state = window_state.as_ref().lock();
|
let window_state = window_state.as_ref().lock();
|
||||||
window_state.renderer.layer().as_ptr() as id
|
window_state.renderer.layer_ptr() as id
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel) {
|
extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel) {
|
||||||
let window_state = unsafe { get_window_state(this) };
|
let window_state = unsafe { get_window_state(this) };
|
||||||
let mut lock = window_state.as_ref().lock();
|
let mut lock = window_state.as_ref().lock();
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let scale_factor = lock.scale_factor() as f64;
|
let scale_factor = lock.scale_factor() as f64;
|
||||||
let size = lock.content_size();
|
let size = lock.content_size();
|
||||||
let drawable_size: NSSize = NSSize {
|
let drawable_size: NSSize = NSSize {
|
||||||
width: f64::from(size.width) * scale_factor,
|
width: f64::from(size.width) * scale_factor,
|
||||||
height: f64::from(size.height) * scale_factor,
|
height: f64::from(size.height) * scale_factor,
|
||||||
};
|
};
|
||||||
|
unsafe {
|
||||||
let _: () = msg_send![
|
let _: () = msg_send![
|
||||||
lock.renderer.layer(),
|
lock.renderer.layer(),
|
||||||
setContentsScale: scale_factor
|
setContentsScale: scale_factor
|
||||||
];
|
];
|
||||||
let _: () = msg_send![
|
|
||||||
lock.renderer.layer(),
|
|
||||||
setDrawableSize: drawable_size
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.update_drawable_size(drawable_size);
|
||||||
|
|
||||||
if let Some(mut callback) = lock.resize_callback.take() {
|
if let Some(mut callback) = lock.resize_callback.take() {
|
||||||
let content_size = lock.content_size();
|
let content_size = lock.content_size();
|
||||||
let scale_factor = lock.scale_factor();
|
let scale_factor = lock.scale_factor();
|
||||||
@ -1523,7 +1561,7 @@ extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel) {
|
|||||||
|
|
||||||
extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) {
|
extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) {
|
||||||
let window_state = unsafe { get_window_state(this) };
|
let window_state = unsafe { get_window_state(this) };
|
||||||
let lock = window_state.as_ref().lock();
|
let mut lock = window_state.as_ref().lock();
|
||||||
|
|
||||||
if lock.content_size() == size.into() {
|
if lock.content_size() == size.into() {
|
||||||
return;
|
return;
|
||||||
@ -1539,12 +1577,7 @@ extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) {
|
|||||||
height: size.height * scale_factor,
|
height: size.height * scale_factor,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
lock.update_drawable_size(drawable_size);
|
||||||
let _: () = msg_send![
|
|
||||||
lock.renderer.layer(),
|
|
||||||
setDrawableSize: drawable_size
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(lock);
|
drop(lock);
|
||||||
let mut lock = window_state.lock();
|
let mut lock = window_state.lock();
|
||||||
@ -1561,6 +1594,7 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
|
|||||||
let window_state = unsafe { get_window_state(this) };
|
let window_state = unsafe { get_window_state(this) };
|
||||||
let mut lock = window_state.lock();
|
let mut lock = window_state.lock();
|
||||||
if let Some(mut callback) = lock.request_frame_callback.take() {
|
if let Some(mut callback) = lock.request_frame_callback.take() {
|
||||||
|
#[cfg(not(feature = "macos-blade"))]
|
||||||
lock.renderer.set_presents_with_transaction(true);
|
lock.renderer.set_presents_with_transaction(true);
|
||||||
lock.stop_display_link();
|
lock.stop_display_link();
|
||||||
drop(lock);
|
drop(lock);
|
||||||
@ -1568,6 +1602,7 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
|
|||||||
|
|
||||||
let mut lock = window_state.lock();
|
let mut lock = window_state.lock();
|
||||||
lock.request_frame_callback = Some(callback);
|
lock.request_frame_callback = Some(callback);
|
||||||
|
#[cfg(not(feature = "macos-blade"))]
|
||||||
lock.renderer.set_presents_with_transaction(false);
|
lock.renderer.set_presents_with_transaction(false);
|
||||||
lock.start_display_link();
|
lock.start_display_link();
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ bytes = "1.2"
|
|||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
core-foundation = "0.9.3"
|
core-foundation = "0.9.3"
|
||||||
foreign-types = "0.3"
|
foreign-types = "0.5"
|
||||||
metal = "0.21.0"
|
metal = "0.25"
|
||||||
objc = "0.2"
|
objc = "0.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
@ -135,24 +135,24 @@ echo "Bundled ${app_path}"
|
|||||||
|
|
||||||
if [ "$local_arch" = false ]; then
|
if [ "$local_arch" = false ]; then
|
||||||
echo "Uploading dSYMs"
|
echo "Uploading dSYMs"
|
||||||
dsymutil --flat target/aarch64-apple-darwin/release/Zed
|
dsymutil --flat target/aarch64-apple-darwin/${target_dir}/Zed
|
||||||
dsymutil --flat target/x86_64-apple-darwin/release/Zed
|
dsymutil --flat target/x86_64-apple-darwin/${target_dir}/Zed
|
||||||
version="$(cargo metadata --no-deps --manifest-path crates/zed/Cargo.toml --offline --format-version=1 | jq -r '.packages | map(select(.name == "zed"))[0].version')"
|
version="$(cargo metadata --no-deps --manifest-path crates/zed/Cargo.toml --offline --format-version=1 | jq -r '.packages | map(select(.name == "zed"))[0].version')"
|
||||||
if [ "$channel" == "nightly" ]; then
|
if [ "$channel" == "nightly" ]; then
|
||||||
version="$version-$(git rev-parse --short HEAD)"
|
version="$version-$(git rev-parse --short HEAD)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Removing existing gzipped dSYMs"
|
echo "Removing existing gzipped dSYMs"
|
||||||
rm -f target/aarch64-apple-darwin/release/Zed.dwarf.gz
|
rm -f target/aarch64-apple-darwin/${target_dir}/Zed.dwarf.gz
|
||||||
rm -f target/x86_64-apple-darwin/release/Zed.dwarf.gz
|
rm -f target/x86_64-apple-darwin/${target_dir}/Zed.dwarf.gz
|
||||||
|
|
||||||
echo "Gzipping dSYMs"
|
echo "Gzipping dSYMs"
|
||||||
gzip target/aarch64-apple-darwin/release/Zed.dwarf
|
gzip target/aarch64-apple-darwin/${target_dir}/Zed.dwarf
|
||||||
gzip target/x86_64-apple-darwin/release/Zed.dwarf
|
gzip target/x86_64-apple-darwin/${target_dir}/Zed.dwarf
|
||||||
|
|
||||||
echo "Uploading dSYMs"
|
echo "Uploading dSYMs"
|
||||||
uploadDsym target/aarch64-apple-darwin/release/Zed.dwarf.gz "$channel/Zed-$version-aarch64-apple-darwin.dwarf.gz"
|
uploadDsym target/aarch64-apple-darwin/${target_dir}/Zed.dwarf.gz "$channel/Zed-$version-aarch64-apple-darwin.dwarf.gz"
|
||||||
uploadDsym target/x86_64-apple-darwin/release/Zed.dwarf.gz "$channel/Zed-$version-x86_64-apple-darwin.dwarf.gz"
|
uploadDsym target/x86_64-apple-darwin/${target_dir}/Zed.dwarf.gz "$channel/Zed-$version-x86_64-apple-darwin.dwarf.gz"
|
||||||
|
|
||||||
echo "Creating fat binaries"
|
echo "Creating fat binaries"
|
||||||
lipo \
|
lipo \
|
||||||
|
Loading…
Reference in New Issue
Block a user