Compare commits
3 Commits
temperatur
...
gpu-prefer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ab1475f26 | ||
|
|
aef9751e05 | ||
|
|
c68c8928c2 |
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -13699,6 +13699,7 @@ dependencies = [
|
|||||||
"release_channel",
|
"release_channel",
|
||||||
"repl",
|
"repl",
|
||||||
"rope",
|
"rope",
|
||||||
|
"schemars",
|
||||||
"search",
|
"search",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -67,5 +67,6 @@ fn notification_window_options(
|
|||||||
app_id: Some(app_id.to_owned()),
|
app_id: Some(app_id.to_owned()),
|
||||||
window_min_size: None,
|
window_min_size: None,
|
||||||
window_decorations: Some(WindowDecorations::Client),
|
window_decorations: Some(WindowDecorations::Client),
|
||||||
|
gpu: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ fn build_window_options(display_id: DisplayId, bounds: Bounds<Pixels>) -> Window
|
|||||||
app_id: None,
|
app_id: None,
|
||||||
window_min_size: None,
|
window_min_size: None,
|
||||||
window_decorations: None,
|
window_decorations: None,
|
||||||
|
gpu: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -252,6 +252,16 @@ pub enum Decorations {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A type to describe which GPU to prefer.
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]
|
||||||
|
pub enum Gpu {
|
||||||
|
/// The window is rendered using the integrated (lower-power) GPU
|
||||||
|
#[default]
|
||||||
|
Integrated,
|
||||||
|
/// The window is rendered using the discrete GPU
|
||||||
|
Discrete,
|
||||||
|
}
|
||||||
|
|
||||||
/// What window controls this platform supports
|
/// What window controls this platform supports
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]
|
||||||
pub struct WindowControls {
|
pub struct WindowControls {
|
||||||
@@ -679,6 +689,10 @@ pub struct WindowOptions {
|
|||||||
/// Whether to use client or server side decorations. Wayland only
|
/// Whether to use client or server side decorations. Wayland only
|
||||||
/// Note that this may be ignored.
|
/// Note that this may be ignored.
|
||||||
pub window_decorations: Option<WindowDecorations>,
|
pub window_decorations: Option<WindowDecorations>,
|
||||||
|
|
||||||
|
/// Whether to prefer one GPU over another. macOS only
|
||||||
|
/// Note that this may be ignored.
|
||||||
|
pub gpu: Option<Gpu>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The variables that can be configured when creating a new window
|
/// The variables that can be configured when creating a new window
|
||||||
@@ -707,6 +721,11 @@ pub(crate) struct WindowParams {
|
|||||||
|
|
||||||
#[cfg_attr(target_os = "linux", allow(dead_code))]
|
#[cfg_attr(target_os = "linux", allow(dead_code))]
|
||||||
pub window_min_size: Option<Size<Pixels>>,
|
pub window_min_size: Option<Size<Pixels>>,
|
||||||
|
|
||||||
|
/// Whether to prefer one GPU over another. macOS only
|
||||||
|
/// Note that this may be ignored.
|
||||||
|
#[cfg_attr(target_os = "linux", allow(dead_code))]
|
||||||
|
pub gpu: Option<Gpu>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the status of how a window should be opened.
|
/// Represents the status of how a window should be opened.
|
||||||
@@ -757,6 +776,7 @@ impl Default for WindowOptions {
|
|||||||
app_id: None,
|
app_id: None,
|
||||||
window_min_size: None,
|
window_min_size: None,
|
||||||
window_decorations: None,
|
window_decorations: None,
|
||||||
|
gpu: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
use super::{BladeAtlas, PATH_TEXTURE_FORMAT};
|
use super::{BladeAtlas, PATH_TEXTURE_FORMAT};
|
||||||
use crate::{
|
use crate::{
|
||||||
AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels, Hsla, MonochromeSprite, Path,
|
AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels, Gpu, Hsla, MonochromeSprite,
|
||||||
PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size,
|
Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow,
|
||||||
Underline,
|
Size, Underline,
|
||||||
};
|
};
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
@@ -32,6 +32,7 @@ pub unsafe fn new_renderer(
|
|||||||
native_view: *mut c_void,
|
native_view: *mut c_void,
|
||||||
bounds: crate::Size<f32>,
|
bounds: crate::Size<f32>,
|
||||||
transparent: bool,
|
transparent: bool,
|
||||||
|
_gpu: Option<Gpu>,
|
||||||
) -> Renderer {
|
) -> Renderer {
|
||||||
use raw_window_handle as rwh;
|
use raw_window_handle as rwh;
|
||||||
struct RawWindow {
|
struct RawWindow {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::metal_atlas::MetalAtlas;
|
use super::metal_atlas::MetalAtlas;
|
||||||
use crate::{
|
use crate::{
|
||||||
point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels,
|
point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels,
|
||||||
Hsla, MonochromeSprite, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad,
|
Gpu, Hsla, MonochromeSprite, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad,
|
||||||
ScaledPixels, Scene, Shadow, Size, Surface, Underline,
|
ScaledPixels, Scene, Shadow, Size, Surface, Underline,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
@@ -38,8 +38,9 @@ pub unsafe fn new_renderer(
|
|||||||
_native_view: *mut c_void,
|
_native_view: *mut c_void,
|
||||||
_bounds: crate::Size<f32>,
|
_bounds: crate::Size<f32>,
|
||||||
_transparent: bool,
|
_transparent: bool,
|
||||||
|
gpu: Option<Gpu>,
|
||||||
) -> Renderer {
|
) -> Renderer {
|
||||||
MetalRenderer::new(context)
|
MetalRenderer::new(context, gpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct InstanceBufferPool {
|
pub(crate) struct InstanceBufferPool {
|
||||||
@@ -108,13 +109,19 @@ pub(crate) struct MetalRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MetalRenderer {
|
impl MetalRenderer {
|
||||||
pub fn new(instance_buffer_pool: Arc<Mutex<InstanceBufferPool>>) -> Self {
|
pub fn new(instance_buffer_pool: Arc<Mutex<InstanceBufferPool>>, gpu: Option<Gpu>) -> Self {
|
||||||
// Prefer low‐power integrated GPUs on Intel Mac. On Apple
|
let device = match gpu {
|
||||||
// Silicon, there is only ever one GPU, so this is equivalent to
|
Some(Gpu::Discrete) => metal::Device::system_default(),
|
||||||
// `metal::Device::system_default()`.
|
_ => {
|
||||||
let mut devices = metal::Device::all();
|
// By default, prefer low‐power integrated GPUs on Intel Mac. On Apple
|
||||||
devices.sort_by_key(|device| (!device.is_removable(), device.is_low_power()));
|
// Silicon, there is only ever one GPU, so this is equivalent to
|
||||||
let Some(device) = devices.pop() else {
|
// `metal::Device::system_default()`.
|
||||||
|
let mut devices = metal::Device::all();
|
||||||
|
devices.sort_by_key(|device| (!device.is_removable(), device.is_low_power()));
|
||||||
|
devices.pop()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let Some(device) = device else {
|
||||||
log::error!("unable to access a compatible graphics device");
|
log::error!("unable to access a compatible graphics device");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -505,6 +505,7 @@ impl MacWindow {
|
|||||||
show,
|
show,
|
||||||
display_id,
|
display_id,
|
||||||
window_min_size,
|
window_min_size,
|
||||||
|
gpu,
|
||||||
}: WindowParams,
|
}: WindowParams,
|
||||||
executor: ForegroundExecutor,
|
executor: ForegroundExecutor,
|
||||||
renderer_context: renderer::Context,
|
renderer_context: renderer::Context,
|
||||||
@@ -603,6 +604,7 @@ impl MacWindow {
|
|||||||
native_view as *mut _,
|
native_view as *mut _,
|
||||||
bounds.size.map(|pixels| pixels.0),
|
bounds.size.map(|pixels| pixels.0),
|
||||||
false,
|
false,
|
||||||
|
gpu,
|
||||||
),
|
),
|
||||||
request_frame_callback: None,
|
request_frame_callback: None,
|
||||||
event_callback: None,
|
event_callback: None,
|
||||||
|
|||||||
@@ -645,6 +645,7 @@ impl Window {
|
|||||||
app_id,
|
app_id,
|
||||||
window_min_size,
|
window_min_size,
|
||||||
window_decorations,
|
window_decorations,
|
||||||
|
gpu,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
let bounds = window_bounds
|
let bounds = window_bounds
|
||||||
@@ -661,6 +662,7 @@ impl Window {
|
|||||||
show,
|
show,
|
||||||
display_id,
|
display_id,
|
||||||
window_min_size,
|
window_min_size,
|
||||||
|
gpu,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
let display_id = platform_window.display().map(|display| display.id());
|
let display_id = platform_window.display().map(|display| display.id());
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ serde.workspace = true
|
|||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
settings.workspace = true
|
settings.workspace = true
|
||||||
simplelog.workspace = true
|
simplelog.workspace = true
|
||||||
|
schemars.workspace = true
|
||||||
smol.workspace = true
|
smol.workspace = true
|
||||||
snippet_provider.workspace = true
|
snippet_provider.workspace = true
|
||||||
tab_switcher.workspace = true
|
tab_switcher.workspace = true
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
mod app_menus;
|
mod app_menus;
|
||||||
|
mod gpu;
|
||||||
pub mod inline_completion_registry;
|
pub mod inline_completion_registry;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub(crate) mod linux_prompts;
|
pub(crate) mod linux_prompts;
|
||||||
@@ -11,6 +12,7 @@ use breadcrumbs::Breadcrumbs;
|
|||||||
use client::ZED_URL_SCHEME;
|
use client::ZED_URL_SCHEME;
|
||||||
use collections::VecDeque;
|
use collections::VecDeque;
|
||||||
use editor::{scroll::Autoscroll, Editor, MultiBuffer};
|
use editor::{scroll::Autoscroll, Editor, MultiBuffer};
|
||||||
|
use gpu::GpuSettings;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, point, px, AppContext, AsyncAppContext, Context, FocusableView, MenuItem, PromptLevel,
|
actions, point, px, AppContext, AsyncAppContext, Context, FocusableView, MenuItem, PromptLevel,
|
||||||
ReadGlobal, TitlebarOptions, View, ViewContext, VisualContext, WindowKind, WindowOptions,
|
ReadGlobal, TitlebarOptions, View, ViewContext, VisualContext, WindowKind, WindowOptions,
|
||||||
@@ -78,6 +80,7 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
cx.on_action(|_: &ShowAll, cx| cx.unhide_other_apps());
|
cx.on_action(|_: &ShowAll, cx| cx.unhide_other_apps());
|
||||||
cx.on_action(quit);
|
cx.on_action(quit);
|
||||||
|
|
||||||
|
GpuSettings::register(cx);
|
||||||
if ReleaseChannel::global(cx) == ReleaseChannel::Dev {
|
if ReleaseChannel::global(cx) == ReleaseChannel::Dev {
|
||||||
cx.on_action(test_panic);
|
cx.on_action(test_panic);
|
||||||
}
|
}
|
||||||
@@ -115,6 +118,7 @@ pub fn build_window_options(display_uuid: Option<Uuid>, cx: &mut AppContext) ->
|
|||||||
width: px(360.0),
|
width: px(360.0),
|
||||||
height: px(240.0),
|
height: px(240.0),
|
||||||
}),
|
}),
|
||||||
|
gpu: GpuSettings::get_global(cx).gpu.map(Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
46
crates/zed/src/zed/gpu.rs
Normal file
46
crates/zed/src/zed/gpu.rs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use settings::{Settings, SettingsSources};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Default, Serialize, PartialEq, Eq, Deserialize, JsonSchema)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum Gpu {
|
||||||
|
Discrete,
|
||||||
|
#[default]
|
||||||
|
Integrated,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<gpui::Gpu> for Gpu {
|
||||||
|
fn into(self) -> gpui::Gpu {
|
||||||
|
match self {
|
||||||
|
Gpu::Discrete => gpui::Gpu::Discrete,
|
||||||
|
Gpu::Integrated => gpui::Gpu::Integrated,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Settings related to the machine's GPU and how Zed uses it.
|
||||||
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
|
||||||
|
pub struct GpuSettings {
|
||||||
|
/// Which GPU to prefer: discrete or integrated.
|
||||||
|
/// Integrated are often lower-power and thus more battery-efficient.
|
||||||
|
///
|
||||||
|
/// Default: 0.2
|
||||||
|
pub gpu: Option<Gpu>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings for GpuSettings {
|
||||||
|
const KEY: Option<&'static str> = None;
|
||||||
|
|
||||||
|
type FileContent = Option<Self>;
|
||||||
|
|
||||||
|
fn load(
|
||||||
|
sources: SettingsSources<Self::FileContent>,
|
||||||
|
_: &mut gpui::AppContext,
|
||||||
|
) -> anyhow::Result<Self> {
|
||||||
|
if let Some(Some(user_value)) = sources.user.copied() {
|
||||||
|
return Ok(user_value);
|
||||||
|
}
|
||||||
|
Ok(Self::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user