This commit is contained in:
Max Brunsfeld 2021-03-30 12:36:18 -07:00
parent f8cc3996b2
commit 011d4d8437
4 changed files with 40 additions and 27 deletions

View file

@ -1,8 +1,8 @@
use crate::geometry::vector::vec2i; use crate::geometry::vector::{vec2i, Vector2I};
use crate::geometry::vector::Vector2I;
use anyhow::anyhow;
use etagere::BucketedAtlasAllocator; use etagere::BucketedAtlasAllocator;
use foreign_types::ForeignType;
use metal::{self, Device, TextureDescriptor}; use metal::{self, Device, TextureDescriptor};
use objc::{msg_send, sel, sel_impl};
pub struct AtlasAllocator { pub struct AtlasAllocator {
device: Device, device: Device,
@ -19,12 +19,12 @@ impl AtlasAllocator {
atlasses: Vec::new(), atlasses: Vec::new(),
free_atlasses: Vec::new(), free_atlasses: Vec::new(),
}; };
let atlas = me.new_atlas(); let atlas = me.new_atlas(Vector2I::zero());
me.atlasses.push(atlas); me.atlasses.push(atlas);
me me
} }
pub fn atlas_size(&self) -> Vector2I { pub fn default_atlas_size(&self) -> Vector2I {
vec2i( vec2i(
self.texture_descriptor.width() as i32, self.texture_descriptor.width() as i32,
self.texture_descriptor.height() as i32, self.texture_descriptor.height() as i32,
@ -32,22 +32,13 @@ impl AtlasAllocator {
} }
pub fn allocate(&mut self, requested_size: Vector2I) -> anyhow::Result<(usize, Vector2I)> { pub fn allocate(&mut self, requested_size: Vector2I) -> anyhow::Result<(usize, Vector2I)> {
let atlas_size = self.atlas_size();
if requested_size.x() > atlas_size.x() || requested_size.y() > atlas_size.y() {
return Err(anyhow!(
"requested size {:?} too large for atlas {:?}",
requested_size,
atlas_size
));
}
let origin = self let origin = self
.atlasses .atlasses
.last_mut() .last_mut()
.unwrap() .unwrap()
.allocate(requested_size) .allocate(requested_size)
.unwrap_or_else(|| { .unwrap_or_else(|| {
let mut atlas = self.new_atlas(); let mut atlas = self.new_atlas(requested_size);
let origin = atlas.allocate(requested_size).unwrap(); let origin = atlas.allocate(requested_size).unwrap();
self.atlasses.push(atlas); self.atlasses.push(atlas);
origin origin
@ -67,13 +58,29 @@ impl AtlasAllocator {
self.atlasses.get(atlas_id).map(|a| a.texture.as_ref()) self.atlasses.get(atlas_id).map(|a| a.texture.as_ref())
} }
fn new_atlas(&mut self) -> Atlas { fn new_atlas(&mut self, required_size: Vector2I) -> Atlas {
self.free_atlasses.pop().unwrap_or_else(|| { if let Some(i) = self.free_atlasses.iter().rposition(|atlas| {
Atlas::new( atlas.size().x() >= required_size.x() && atlas.size().y() >= required_size.y()
self.atlas_size(), }) {
self.device.new_texture(&self.texture_descriptor), self.free_atlasses.remove(i)
) } else {
}) let size = self.default_atlas_size().max(required_size);
let texture = if size.x() as u64 > self.texture_descriptor.width()
|| size.y() as u64 > self.texture_descriptor.height()
{
let descriptor = unsafe {
let descriptor_ptr: *mut metal::MTLTextureDescriptor =
msg_send![self.texture_descriptor, copy];
metal::TextureDescriptor::from_ptr(descriptor_ptr)
};
descriptor.set_width(size.x() as u64);
descriptor.set_height(size.y() as u64);
self.device.new_texture(&descriptor)
} else {
self.device.new_texture(&self.texture_descriptor)
};
Atlas::new(size, texture)
}
} }
} }
@ -90,6 +97,11 @@ impl Atlas {
} }
} }
fn size(&self) -> Vector2I {
let size = self.allocator.size();
vec2i(size.width, size.height)
}
fn allocate(&mut self, size: Vector2I) -> Option<Vector2I> { fn allocate(&mut self, size: Vector2I) -> Option<Vector2I> {
let origin = self let origin = self
.allocator .allocator

View file

@ -66,8 +66,8 @@ impl Renderer {
); );
let path_stencil_descriptor = metal::TextureDescriptor::new(); let path_stencil_descriptor = metal::TextureDescriptor::new();
path_stencil_descriptor.set_width(1024); path_stencil_descriptor.set_width(64);
path_stencil_descriptor.set_height(768); path_stencil_descriptor.set_height(64);
path_stencil_descriptor.set_pixel_format(pixel_format); path_stencil_descriptor.set_pixel_format(pixel_format);
path_stencil_descriptor path_stencil_descriptor
.set_usage(metal::MTLTextureUsage::RenderTarget | metal::MTLTextureUsage::ShaderRead); .set_usage(metal::MTLTextureUsage::RenderTarget | metal::MTLTextureUsage::ShaderRead);
@ -250,7 +250,7 @@ impl Renderer {
shaders::GPUIPathWindingVertexInputIndex_GPUIPathWindingVertexInputIndexAtlasSize shaders::GPUIPathWindingVertexInputIndex_GPUIPathWindingVertexInputIndexAtlasSize
as u64, as u64,
mem::size_of::<shaders::vector_float2>() as u64, mem::size_of::<shaders::vector_float2>() as u64,
[self.path_stencils.atlas_size().to_float2()].as_ptr() as *const c_void, [self.path_stencils.default_atlas_size().to_float2()].as_ptr() as *const c_void,
); );
let buffer_contents = unsafe { let buffer_contents = unsafe {

View file

@ -193,7 +193,7 @@ vertex SpriteFragmentInput sprite_vertex(
}; };
} }
#define MAX_WINDINGS 8. #define MAX_WINDINGS 16.
fragment float4 sprite_fragment( fragment float4 sprite_fragment(
SpriteFragmentInput input [[stage_in]], SpriteFragmentInput input [[stage_in]],

View file

@ -175,7 +175,8 @@ impl FileFinder {
LineBox::new( LineBox::new(
settings.ui_font_family, settings.ui_font_family,
settings.ui_font_size, settings.ui_font_size,
Svg::new("icons/file-16.svg".into()).boxed(), Empty::new().boxed(),
// Svg::new("icons/file-16.svg".into()).boxed(),
) )
.boxed(), .boxed(),
) )