apply #19772
This commit is contained in:
parent
238ccec5ee
commit
1fb689bad3
1 changed files with 74 additions and 66 deletions
|
@ -3,25 +3,25 @@ use etagere::BucketedAtlasAllocator;
|
|||
use parking_lot::Mutex;
|
||||
use windows::Win32::Graphics::{
|
||||
Direct3D11::{
|
||||
D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_WRITE,
|
||||
D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, ID3D11Device, ID3D11DeviceContext,
|
||||
ID3D11RenderTargetView, ID3D11ShaderResourceView, ID3D11Texture2D,
|
||||
},
|
||||
Dxgi::Common::{
|
||||
DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R16_FLOAT, DXGI_SAMPLE_DESC,
|
||||
D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_WRITE, D3D11_TEXTURE2D_DESC,
|
||||
D3D11_USAGE_DEFAULT, ID3D11Device, ID3D11DeviceContext, ID3D11ShaderResourceView,
|
||||
ID3D11Texture2D,
|
||||
},
|
||||
Dxgi::Common::{DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_SAMPLE_DESC},
|
||||
};
|
||||
|
||||
use crate::*;
|
||||
use crate::{
|
||||
AtlasKey, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, DevicePixels, PlatformAtlas,
|
||||
Size, platform::AtlasTextureList,
|
||||
};
|
||||
|
||||
pub(crate) struct DirectXAtlas(Mutex<DirectXAtlasState>);
|
||||
|
||||
struct DirectXAtlasState {
|
||||
device: ID3D11Device,
|
||||
device_context: ID3D11DeviceContext,
|
||||
monochrome_textures: Vec<DirectXAtlasTexture>,
|
||||
polychrome_textures: Vec<DirectXAtlasTexture>,
|
||||
// path_textures: Vec<DirectXAtlasTexture>,
|
||||
monochrome_textures: AtlasTextureList<DirectXAtlasTexture>,
|
||||
polychrome_textures: AtlasTextureList<DirectXAtlasTexture>,
|
||||
tiles_by_key: FxHashMap<AtlasKey, AtlasTile>,
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,8 @@ struct DirectXAtlasTexture {
|
|||
bytes_per_pixel: u32,
|
||||
allocator: BucketedAtlasAllocator,
|
||||
texture: ID3D11Texture2D,
|
||||
rtv: [Option<ID3D11RenderTargetView>; 1],
|
||||
view: [Option<ID3D11ShaderResourceView>; 1],
|
||||
live_atlas_keys: u32,
|
||||
}
|
||||
|
||||
impl DirectXAtlas {
|
||||
|
@ -41,27 +41,10 @@ impl DirectXAtlas {
|
|||
device_context,
|
||||
monochrome_textures: Default::default(),
|
||||
polychrome_textures: Default::default(),
|
||||
// path_textures: Default::default(),
|
||||
tiles_by_key: Default::default(),
|
||||
}))
|
||||
}
|
||||
|
||||
pub(crate) fn get_texture_drawing_info(
|
||||
&self,
|
||||
id: AtlasTextureId,
|
||||
) -> (Size<f32>, [Option<ID3D11RenderTargetView>; 1]) {
|
||||
let lock = self.0.lock();
|
||||
let tex = lock.texture(id);
|
||||
let size = tex.allocator.size();
|
||||
(
|
||||
Size {
|
||||
width: size.width as f32,
|
||||
height: size.height as f32,
|
||||
},
|
||||
tex.rtv.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn get_texture_view(
|
||||
&self,
|
||||
id: AtlasTextureId,
|
||||
|
@ -84,9 +67,8 @@ impl DirectXAtlas {
|
|||
let textures = match texture_kind {
|
||||
AtlasTextureKind::Monochrome => &mut lock.monochrome_textures,
|
||||
AtlasTextureKind::Polychrome => &mut lock.polychrome_textures,
|
||||
// AtlasTextureKind::Path => &mut lock.path_textures,
|
||||
};
|
||||
for texture in textures {
|
||||
for texture in textures.iter_mut() {
|
||||
texture.clear();
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +100,30 @@ impl PlatformAtlas for DirectXAtlas {
|
|||
}
|
||||
|
||||
fn remove(&self, key: &AtlasKey) {
|
||||
todo!()
|
||||
let mut lock = self.0.lock();
|
||||
|
||||
let Some(id) = lock.tiles_by_key.remove(key).map(|tile| tile.texture_id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let textures = match id.kind {
|
||||
AtlasTextureKind::Monochrome => &mut lock.monochrome_textures,
|
||||
AtlasTextureKind::Polychrome => &mut lock.polychrome_textures,
|
||||
};
|
||||
|
||||
let Some(texture_slot) = textures.textures.get_mut(id.index as usize) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(mut texture) = texture_slot.take() {
|
||||
texture.decrement_ref_count();
|
||||
if texture.is_unreferenced() {
|
||||
textures.free_list.push(texture.id.index as usize);
|
||||
lock.tiles_by_key.remove(key);
|
||||
} else {
|
||||
*texture_slot = Some(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,20 +133,23 @@ impl DirectXAtlasState {
|
|||
size: Size<DevicePixels>,
|
||||
texture_kind: AtlasTextureKind,
|
||||
) -> Option<AtlasTile> {
|
||||
let textures = match texture_kind {
|
||||
AtlasTextureKind::Monochrome => &mut self.monochrome_textures,
|
||||
AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
|
||||
// AtlasTextureKind::Path => &mut self.path_textures,
|
||||
};
|
||||
{
|
||||
let textures = match texture_kind {
|
||||
AtlasTextureKind::Monochrome => &mut self.monochrome_textures,
|
||||
AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
|
||||
};
|
||||
|
||||
textures
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.find_map(|texture| texture.allocate(size))
|
||||
.or_else(|| {
|
||||
let texture = self.push_texture(size, texture_kind);
|
||||
texture.allocate(size)
|
||||
})
|
||||
if let Some(tile) = textures
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.find_map(|texture| texture.allocate(size))
|
||||
{
|
||||
return Some(tile);
|
||||
}
|
||||
}
|
||||
|
||||
let texture = self.push_texture(size, texture_kind);
|
||||
texture.allocate(size)
|
||||
}
|
||||
|
||||
fn push_texture(
|
||||
|
@ -173,11 +181,7 @@ impl DirectXAtlasState {
|
|||
pixel_format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
bind_flag = D3D11_BIND_SHADER_RESOURCE;
|
||||
bytes_per_pixel = 4;
|
||||
} // AtlasTextureKind::Path => {
|
||||
// pixel_format = DXGI_FORMAT_R16_FLOAT;
|
||||
// bind_flag = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
|
||||
// bytes_per_pixel = 2;
|
||||
// }
|
||||
}
|
||||
}
|
||||
let texture_desc = D3D11_TEXTURE2D_DESC {
|
||||
Width: size.width.0 as u32,
|
||||
|
@ -202,21 +206,11 @@ impl DirectXAtlasState {
|
|||
}
|
||||
let texture = texture.unwrap();
|
||||
|
||||
let textures = match kind {
|
||||
let texture_list = match kind {
|
||||
AtlasTextureKind::Monochrome => &mut self.monochrome_textures,
|
||||
AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
|
||||
// AtlasTextureKind::Path => &mut self.path_textures,
|
||||
};
|
||||
let rtv = match kind {
|
||||
// AtlasTextureKind::Path => unsafe {
|
||||
// let mut view: Option<ID3D11RenderTargetView> = None;
|
||||
// self.device
|
||||
// .CreateRenderTargetView(&texture, None, Some(&mut view))
|
||||
// .unwrap();
|
||||
// [view]
|
||||
// },
|
||||
_ => [None],
|
||||
};
|
||||
let index = texture_list.free_list.pop();
|
||||
let view = unsafe {
|
||||
let mut view = None;
|
||||
self.device
|
||||
|
@ -226,17 +220,22 @@ impl DirectXAtlasState {
|
|||
};
|
||||
let atlas_texture = DirectXAtlasTexture {
|
||||
id: AtlasTextureId {
|
||||
index: textures.len() as u32,
|
||||
index: index.unwrap_or(texture_list.textures.len()) as u32,
|
||||
kind,
|
||||
},
|
||||
bytes_per_pixel,
|
||||
allocator: etagere::BucketedAtlasAllocator::new(size.into()),
|
||||
texture,
|
||||
rtv,
|
||||
view,
|
||||
live_atlas_keys: 0,
|
||||
};
|
||||
textures.push(atlas_texture);
|
||||
textures.last_mut().unwrap()
|
||||
if let Some(ix) = index {
|
||||
texture_list.textures[ix] = Some(atlas_texture);
|
||||
texture_list.textures.get_mut(ix).unwrap().as_mut().unwrap()
|
||||
} else {
|
||||
texture_list.textures.push(Some(atlas_texture));
|
||||
texture_list.textures.last_mut().unwrap().as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn texture(&self, id: AtlasTextureId) -> &DirectXAtlasTexture {
|
||||
|
@ -245,7 +244,7 @@ impl DirectXAtlasState {
|
|||
crate::AtlasTextureKind::Polychrome => &self.polychrome_textures,
|
||||
// crate::AtlasTextureKind::Path => &self.path_textures,
|
||||
};
|
||||
&textures[id.index as usize]
|
||||
textures[id.index as usize].as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,6 +264,7 @@ impl DirectXAtlasTexture {
|
|||
},
|
||||
padding: 0,
|
||||
};
|
||||
self.live_atlas_keys += 1;
|
||||
Some(tile)
|
||||
}
|
||||
|
||||
|
@ -292,4 +292,12 @@ impl DirectXAtlasTexture {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn decrement_ref_count(&mut self) {
|
||||
self.live_atlas_keys -= 1;
|
||||
}
|
||||
|
||||
fn is_unreferenced(&mut self) -> bool {
|
||||
self.live_atlas_keys == 0
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue