From 5ff2158b23d10d886a412815455a4a3436b8d0f6 Mon Sep 17 00:00:00 2001 From: Fedor Logachev Date: Sun, 30 Jul 2023 15:26:13 -0600 Subject: [PATCH] graphics: Implement TextureId::from_raw_id --- src/graphics.rs | 20 +++++++++++++++-- src/graphics/gl.rs | 50 +++++++++++++++++++++++++++---------------- src/graphics/metal.rs | 3 +++ 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/graphics.rs b/src/graphics.rs index 7127b1ac..afae871e 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -368,8 +368,24 @@ impl Default for TextureParams { #[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)] pub struct ShaderId(usize); +// Inner hence we can't have private data in enum fields #[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)] -pub struct TextureId(usize); +pub(crate) enum TextureIdInner { + Managed(usize), + Raw(RawId), +} + +#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)] +pub struct TextureId(TextureIdInner); + +impl TextureId { + /// Wrap raw platform texture into a TextureId acceptable for miniquad + /// Without allocating any miniquad memory and without letting miniquad + /// manage the texture. + pub fn from_raw_id(raw_id: RawId) -> TextureId { + TextureId(TextureIdInner::Raw(raw_id)) + } +} /// Pixel arithmetic description for blending operations. /// Will be used in an equation: @@ -953,7 +969,7 @@ pub struct ShaderSource<'a> { pub metal_shader: Option<&'a str>, } -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Hash, Eq)] pub enum RawId { OpenGl(crate::native::gl::GLuint), #[cfg(target_vendor = "apple")] diff --git a/src/graphics/gl.rs b/src/graphics/gl.rs index cf6e2faa..33669c1e 100644 --- a/src/graphics/gl.rs +++ b/src/graphics/gl.rs @@ -383,12 +383,24 @@ pub(crate) struct RenderPassInternal { depth_texture: Option, } +struct Textures(Vec); +impl Textures { + fn get(&self, texture: TextureId) -> Texture { + match texture.0 { + TextureIdInner::Raw(RawId::OpenGl(texture)) => Texture { + raw: texture, + params: Default::default(), + }, + TextureIdInner::Managed(texture) => self.0[texture], + } + } +} pub struct GlContext { shaders: Vec, pipelines: Vec, passes: Vec, buffers: Vec, - textures: Vec, + textures: Textures, default_framebuffer: GLuint, pub(crate) cache: GlCache, @@ -413,7 +425,7 @@ impl GlContext { pipelines: vec![], passes: vec![], buffers: vec![], - textures: vec![], + textures: Textures(vec![]), features: Features { instancing: !crate::native::gl::is_gl2(), ..Default::default() @@ -698,19 +710,19 @@ impl RenderingBackend for GlContext { params: TextureParams, ) -> TextureId { let texture = Texture::new(self, access, bytes, params); - self.textures.push(texture); - TextureId(self.textures.len() - 1) + self.textures.0.push(texture); + TextureId(TextureIdInner::Managed(self.textures.0.len() - 1)) } fn delete_texture(&mut self, texture: TextureId) { - let t = self.textures[texture.0]; + let t = self.textures.get(texture); t.delete(); } fn texture_set_filter(&mut self, texture: TextureId, filter: FilterMode) { - let t = self.textures[texture.0]; + let t = self.textures.get(texture); t.set_filter(self, filter); } fn texture_set_wrap(&mut self, texture: TextureId, wrap: TextureWrap) { - let t = self.textures[texture.0]; + let t = self.textures.get(texture); t.set_wrap(self, wrap); } fn texture_resize( @@ -720,11 +732,11 @@ impl RenderingBackend for GlContext { height: u32, bytes: Option<&[u8]>, ) { - let mut t = self.textures[texture.0]; + let mut t = self.textures.get(texture); t.resize(self, width, height, bytes); } fn texture_read_pixels(&mut self, texture: TextureId, bytes: &mut [u8]) { - let t = self.textures[texture.0]; + let t = self.textures.get(texture); t.read_pixels(bytes); } fn texture_update_part( @@ -736,15 +748,15 @@ impl RenderingBackend for GlContext { height: i32, bytes: &[u8], ) { - let t = self.textures[texture.0]; + let t = self.textures.get(texture); t.update_texture_part(self, x_offset, y_offset, width, height, bytes); } fn texture_params(&self, texture: TextureId) -> TextureParams { - let texture = self.textures[texture.0]; + let texture = self.textures.get(texture); texture.params } unsafe fn texture_raw_id(&self, texture: TextureId) -> RawId { - let texture = self.textures[texture.0]; + let texture = self.textures.get(texture); RawId::OpenGl(texture.raw) } @@ -762,7 +774,7 @@ impl RenderingBackend for GlContext { GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - self.textures[color_img.0].raw, + self.textures.get(color_img).raw, 0, ); if let Some(depth_img) = depth_img { @@ -770,7 +782,7 @@ impl RenderingBackend for GlContext { GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, - self.textures[depth_img.0].raw, + self.textures.get(depth_img).raw, 0, ); } @@ -794,9 +806,9 @@ impl RenderingBackend for GlContext { unsafe { glDeleteFramebuffers(1, &mut render_pass.gl_fb as *mut _) } - self.textures[render_pass.texture.0].delete(); + self.textures.get(render_pass.texture).delete(); if let Some(depth_texture) = render_pass.depth_texture { - self.textures[depth_texture.0].delete(); + self.textures.get(depth_texture).delete(); } } @@ -1082,7 +1094,7 @@ impl RenderingBackend for GlContext { if let Some(gl_loc) = shader_image.gl_loc { unsafe { self.cache - .bind_texture(n, self.textures[bindings_image.0].raw); + .bind_texture(n, self.textures.get(*bindings_image).raw); glUniform1i(gl_loc, n as i32); } } @@ -1251,8 +1263,8 @@ impl RenderingBackend for GlContext { let pass = &self.passes[pass.0]; ( pass.gl_fb, - self.textures[pass.texture.0].params.width as i32, - self.textures[pass.texture.0].params.height as i32, + self.textures.get(pass.texture).params.width as i32, + self.textures.get(pass.texture).params.height as i32, ) } }; diff --git a/src/graphics/metal.rs b/src/graphics/metal.rs index b2d55a2f..fe9dd31a 100644 --- a/src/graphics/metal.rs +++ b/src/graphics/metal.rs @@ -654,6 +654,9 @@ impl RenderingBackend for MetalContext { } texture } + fn new_texture_from_raw_id(&mut self, raw_id: RawId) -> TextureId { + unimplemented!() + } fn texture_update_part( &mut self,