gpui/metal: Clamp max texture width/height to 16kB (#10314)
Fixed #10149 A user had Zed crash due to invalid font size in settings. It turned out the width/height of glyphs does not pass validation in Metal texture initialization with a large enough font size. All modern Macs have a max texture width/height of 16kB (barring Apple A8, used by iPhone 6 back in 2014, which uses 8kB). This commit clamps texture size at 16kB. Note that while it fixes Zed crash, using a font size that hits the limit is still pretty unusable - the users will still have a pretty unusable editor, but at least it won't crash for them. Release Notes: - Fixed crashes with huge `buffer_font_size` values.
This commit is contained in:
parent
935e0d547e
commit
4fb9f41e69
2 changed files with 36 additions and 2 deletions
|
@ -528,6 +528,35 @@ where
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Returns a new `Size` with the minimum width and height from `self` and `other`.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `other` - A reference to another `Size` to compare with `self`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use zed::Size;
|
||||||
|
/// let size1 = Size { width: 30, height: 40 };
|
||||||
|
/// let size2 = Size { width: 50, height: 20 };
|
||||||
|
/// let min_size = size1.min(&size2);
|
||||||
|
/// assert_eq!(min_size, Size { width: 30, height: 20 });
|
||||||
|
/// ```
|
||||||
|
pub fn min(&self, other: &Self) -> Self {
|
||||||
|
Size {
|
||||||
|
width: if self.width >= other.width {
|
||||||
|
other.width.clone()
|
||||||
|
} else {
|
||||||
|
self.width.clone()
|
||||||
|
},
|
||||||
|
height: if self.height >= other.height {
|
||||||
|
other.height.clone()
|
||||||
|
} else {
|
||||||
|
self.height.clone()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Sub for Size<T>
|
impl<T> Sub for Size<T>
|
||||||
|
|
|
@ -83,6 +83,7 @@ impl MetalAtlasState {
|
||||||
AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
|
AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
|
||||||
AtlasTextureKind::Path => &mut self.path_textures,
|
AtlasTextureKind::Path => &mut self.path_textures,
|
||||||
};
|
};
|
||||||
|
|
||||||
textures
|
textures
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.rev()
|
.rev()
|
||||||
|
@ -102,8 +103,12 @@ impl MetalAtlasState {
|
||||||
width: DevicePixels(1024),
|
width: DevicePixels(1024),
|
||||||
height: DevicePixels(1024),
|
height: DevicePixels(1024),
|
||||||
};
|
};
|
||||||
|
// Max texture size on all modern Apple GPUs. Anything bigger than that crashes in validateWithDevice.
|
||||||
let size = min_size.max(&DEFAULT_ATLAS_SIZE);
|
const MAX_ATLAS_SIZE: Size<DevicePixels> = Size {
|
||||||
|
width: DevicePixels(16384),
|
||||||
|
height: DevicePixels(16384),
|
||||||
|
};
|
||||||
|
let size = min_size.min(&MAX_ATLAS_SIZE).max(&DEFAULT_ATLAS_SIZE);
|
||||||
let texture_descriptor = metal::TextureDescriptor::new();
|
let texture_descriptor = metal::TextureDescriptor::new();
|
||||||
texture_descriptor.set_width(size.width.into());
|
texture_descriptor.set_width(size.width.into());
|
||||||
texture_descriptor.set_height(size.height.into());
|
texture_descriptor.set_height(size.height.into());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue