Selaa lähdekoodia

wallet: make also index and vertex buffers be auto-managed

darkfi 1 vuosi sitten
vanhempi
sitoutus
5d07cc9585

+ 25 - 8
bin/darkwallet/src/gfx/mod.rs

@@ -100,7 +100,7 @@ pub struct ManagedBuffer {
 
 impl Drop for ManagedBuffer {
     fn drop(&mut self) {
-        //self.render_api.delete_unmanaged_buffer(self.id);
+        self.render_api.delete_unmanaged_buffer(self.id);
     }
 }
 
@@ -141,7 +141,7 @@ impl RenderApi {
         let _ = self.method_req.send(method);
     }
 
-    pub fn new_vertex_buffer(&self, verts: Vec<Vertex>) -> GfxBufferId {
+    fn new_unmanaged_vertex_buffer(&self, verts: Vec<Vertex>) -> GfxBufferId {
         let gfx_buffer_id = rand::random();
 
         let method = GraphicsMethod::NewVertexBuffer((verts, gfx_buffer_id));
@@ -150,7 +150,7 @@ impl RenderApi {
         gfx_buffer_id
     }
 
-    pub fn new_index_buffer(&self, indices: Vec<u16>) -> GfxBufferId {
+    fn new_unmanaged_index_buffer(&self, indices: Vec<u16>) -> GfxBufferId {
         let gfx_buffer_id = rand::random();
 
         let method = GraphicsMethod::NewIndexBuffer((indices, gfx_buffer_id));
@@ -159,7 +159,20 @@ impl RenderApi {
         gfx_buffer_id
     }
 
-    pub fn delete_buffer(&self, buffer: GfxBufferId) {
+    pub fn new_vertex_buffer(&self, verts: Vec<Vertex>) -> ManagedBufferPtr {
+        Arc::new(ManagedBuffer {
+            id: self.new_unmanaged_vertex_buffer(verts),
+            render_api: self.clone(),
+        })
+    }
+    pub fn new_index_buffer(&self, indices: Vec<u16>) -> ManagedBufferPtr {
+        Arc::new(ManagedBuffer {
+            id: self.new_unmanaged_index_buffer(indices),
+            render_api: self.clone(),
+        })
+    }
+
+    fn delete_unmanaged_buffer(&self, buffer: GfxBufferId) {
         let method = GraphicsMethod::DeleteBuffer(buffer);
         let _ = self.method_req.send(method);
     }
@@ -172,8 +185,8 @@ impl RenderApi {
 
 #[derive(Clone, Debug)]
 pub struct GfxDrawMesh {
-    pub vertex_buffer: GfxBufferId,
-    pub index_buffer: GfxBufferId,
+    pub vertex_buffer: ManagedBufferPtr,
+    pub index_buffer: ManagedBufferPtr,
     pub texture: Option<ManagedTexturePtr>,
     pub num_elements: i32,
 }
@@ -184,9 +197,11 @@ impl GfxDrawMesh {
         textures: &HashMap<GfxTextureId, miniquad::TextureId>,
         buffers: &HashMap<GfxBufferId, miniquad::BufferId>,
     ) -> DrawMesh {
+        let buffers_keep_alive = [self.vertex_buffer.clone(), self.index_buffer.clone()];
         DrawMesh {
-            vertex_buffer: buffers[&self.vertex_buffer],
-            index_buffer: buffers[&self.index_buffer],
+            vertex_buffer: buffers[&self.vertex_buffer.id],
+            index_buffer: buffers[&self.index_buffer.id],
+            buffers_keep_alive,
             texture: self.texture.map(|t| (t.clone(), textures[&t.id])),
             num_elements: self.num_elements,
         }
@@ -241,6 +256,8 @@ impl GfxDrawCall {
 struct DrawMesh {
     vertex_buffer: miniquad::BufferId,
     index_buffer: miniquad::BufferId,
+    /// Keeps the buffers alive for the duration of this draw call
+    buffers_keep_alive: [ManagedBufferPtr; 2],
     texture: Option<(ManagedTexturePtr, miniquad::TextureId)>,
     num_elements: i32,
 }

+ 3 - 5
bin/darkwallet/src/mesh.rs

@@ -18,9 +18,7 @@
 
 use crate::{
     error::Result,
-    gfx::{
-        GfxBufferId, GfxDrawMesh, GfxTextureId, ManagedTexturePtr, Rectangle, RenderApi, Vertex,
-    },
+    gfx::{GfxDrawMesh, ManagedBufferPtr, ManagedTexturePtr, Rectangle, RenderApi, Vertex},
 };
 
 pub type Color = [f32; 4];
@@ -42,8 +40,8 @@ pub const COLOR_GREY: Color = [0.5, 0.5, 0.5, 1.];
 
 #[derive(Clone)]
 pub struct MeshInfo {
-    pub vertex_buffer: GfxBufferId,
-    pub index_buffer: GfxBufferId,
+    pub vertex_buffer: ManagedBufferPtr,
+    pub index_buffer: ManagedBufferPtr,
     pub num_elements: i32,
 }
 

+ 4 - 12
bin/darkwallet/src/ui/chatview/mod.rs

@@ -51,7 +51,6 @@ use crate::{
     pubsub::Subscription,
     scene::{MethodCallSub, Pimpl, SceneNodeWeak},
     text::{self, Glyph, GlyphPositionIter, TextShaperPtr},
-    ui::FreedData,
     util::{enumerate, is_whitespace},
     ExecutorPtr,
 };
@@ -630,7 +629,7 @@ impl ChatView {
         &self,
         msgbuf: &mut MessageBuffer,
         rect: &Rectangle,
-    ) -> (Vec<GfxDrawInstruction>, FreedData) {
+    ) -> Vec<GfxDrawInstruction> {
         let scroll = self.scroll.get();
 
         let total_height = msgbuf.calc_total_height().await;
@@ -658,15 +657,13 @@ impl ChatView {
             instrs.push(GfxDrawInstruction::Draw(mesh));
         }
 
-        let freed = std::mem::take(&mut msgbuf.freed);
-
-        (instrs, freed)
+        instrs
     }
 
     async fn redraw_cached(&self, msgbuf: &mut MessageBuffer) {
         let rect = self.rect.get();
 
-        let (mut mesh_instrs, freed) = self.get_meshes(msgbuf, &rect).await;
+        let mut mesh_instrs = self.get_meshes(msgbuf, &rect).await;
 
         let mut instrs = vec![GfxDrawInstruction::ApplyView(rect)];
         instrs.append(&mut mesh_instrs);
@@ -675,10 +672,6 @@ impl ChatView {
             vec![(self.dc_key, GfxDrawCall { instrs, dcs: vec![], z_index: self.z_index.get() })];
 
         self.render_api.replace_draw_calls(draw_calls);
-
-        for buffer_id in freed.buffers {
-            self.render_api.delete_buffer(buffer_id);
-        }
     }
 
     /// Invalidates cache and redraws everything
@@ -800,7 +793,7 @@ impl UIObject for ChatView {
         // Now we have updated all the values so it's safe to wake up here.
         self.bgload_cv.notify();
 
-        let (mut mesh_instrs, freed) = self.get_meshes(&mut msgbuf, &rect).await;
+        let mut mesh_instrs = self.get_meshes(&mut msgbuf, &rect).await;
         drop(msgbuf);
 
         let mut instrs = vec![GfxDrawInstruction::ApplyView(rect)];
@@ -812,7 +805,6 @@ impl UIObject for ChatView {
                 self.dc_key,
                 GfxDrawCall { instrs, dcs: vec![], z_index: self.z_index.get() },
             )],
-            freed_buffers: freed.buffers,
         })
     }
 

+ 10 - 15
bin/darkwallet/src/ui/chatview/page.rs

@@ -39,7 +39,6 @@ use crate::{
     pubsub::Subscription,
     scene::{SceneNodePtr, SceneNodeWeak},
     text::{self, glyph_str, Glyph, GlyphPositionIter, TextShaper, TextShaperPtr},
-    ui::FreedData,
     util::{enumerate_mut, enumerate_ref},
     ExecutorPtr,
 };
@@ -323,8 +322,9 @@ impl PrivMessage {
             text::wrap(width, self.font_size, self.window_scale, &self.unwrapped_glyphs);
     }
 
-    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
-        std::mem::replace(&mut self.mesh_cache, None)
+    fn clear_mesh(&mut self) {
+        // Auto-deletes when refs are dropped
+        self.mesh_cache = None;
     }
 
     fn select(&mut self) {
@@ -409,8 +409,9 @@ impl DateMessage {
 
     //fn adjust_width(&mut self, line_width: f32) { }
 
-    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
-        std::mem::replace(&mut self.mesh_cache, None)
+    fn clear_mesh(&mut self) {
+        // Auto-deletes when refs are dropped
+        self.mesh_cache = None;
     }
 
     fn gen_mesh(
@@ -511,7 +512,7 @@ impl Message {
         }
     }
 
-    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
+    fn clear_mesh(&mut self) {
         match self {
             Self::Priv(m) => m.clear_mesh(),
             Self::Date(m) => m.clear_mesh(),
@@ -603,7 +604,6 @@ pub struct MessageBuffer {
     /// From most recent to older
     msgs: Vec<Message>,
     date_msgs: HashMap<NaiveDate, Message>,
-    pub freed: FreedData,
     pub line_width: f32,
 
     font_size: PropertyFloat32,
@@ -651,7 +651,6 @@ impl MessageBuffer {
 
             msgs: vec![],
             date_msgs: HashMap::new(),
-            freed: Default::default(),
             line_width: 0.,
 
             font_size,
@@ -724,12 +723,10 @@ impl MessageBuffer {
         }
     }
 
-    /// Clear all meshes and caches. Returns data that needs to be freed.
+    /// Clear all meshes and caches.
     pub fn clear_meshes(&mut self) {
         for msg in &mut self.msgs {
-            if let Some(mesh) = msg.clear_mesh() {
-                self.freed.add_mesh(mesh);
-            }
+            msg.clear_mesh();
         }
     }
 
@@ -776,9 +773,7 @@ impl MessageBuffer {
 
         assert_eq!(privmsg.confirmed, false);
         privmsg.confirmed = true;
-        if let Some(mesh) = privmsg.clear_mesh() {
-            self.freed.add_mesh(mesh);
-        }
+        privmsg.clear_mesh();
 
         return true
     }

+ 1 - 31
bin/darkwallet/src/ui/editbox.rs

@@ -45,7 +45,6 @@ use crate::{
     pubsub::Subscription,
     scene::{Pimpl, SceneNodePtr, SceneNodeWeak},
     text::{self, Glyph, GlyphPositionIter, TextShaperPtr},
-    ui::FreedData,
     util::is_whitespace,
     ExecutorPtr,
 };
@@ -271,7 +270,6 @@ pub struct EditBox {
     cursor_mesh: SyncMutex<Option<GfxDrawMesh>>,
     /// DC key for the cursor. Allows updating cursor independently.
     cursor_dc_key: u64,
-    freed: SyncMutex<FreedData>,
 
     is_active: PropertyBool,
     is_focused: PropertyBool,
@@ -358,7 +356,6 @@ impl EditBox {
             text_dc_key: OsRng.gen(),
             cursor_mesh: SyncMutex::new(None),
             cursor_dc_key: OsRng.gen(),
-            freed: SyncMutex::new(Default::default()),
 
             is_active,
             is_focused,
@@ -1183,10 +1180,6 @@ impl EditBox {
         };
 
         self.render_api.replace_draw_calls(draw_update.draw_calls);
-        //debug!(target: "ui::editbox", "replace draw calls done");
-        for buffer_id in draw_update.freed_buffers {
-            self.render_api.delete_buffer(buffer_id);
-        }
     }
 
     async fn redraw_cursor(&self) {
@@ -1227,31 +1220,18 @@ impl EditBox {
     async fn draw_cached(&self) -> Option<DrawUpdate> {
         let rect = self.rect.get();
 
-        let mut freed = std::mem::take(&mut *self.freed.lock().unwrap());
-
         // Force complete redraw if the window scale changed
         let window_scale = self.window_scale.get();
         if self.old_window_scale.swap(window_scale, Ordering::Relaxed) != window_scale {
             self.regen_glyphs();
 
             let text_mesh = std::mem::replace(&mut *self.text_mesh.lock().unwrap(), None);
-            // We're finished with these so clean up.
-            if let Some(old) = text_mesh {
-                freed.buffers.push(old.vertex_buffer);
-                freed.buffers.push(old.index_buffer);
-            }
         }
 
         let text_mesh = self.regen_text_mesh(rect.clone()).await;
         let old_text_mesh =
             std::mem::replace(&mut *self.text_mesh.lock().unwrap(), Some(text_mesh.clone()));
 
-        // We're finished with these so clean up.
-        if let Some(old) = old_text_mesh {
-            freed.buffers.push(old.vertex_buffer);
-            freed.buffers.push(old.index_buffer);
-        }
-
         let cursor_instrs = self.get_cursor_instrs().await;
 
         Some(DrawUpdate {
@@ -1273,19 +1253,13 @@ impl EditBox {
                     GfxDrawCall { instrs: cursor_instrs, dcs: vec![], z_index: self.z_index.get() },
                 ),
             ],
-            freed_buffers: freed.buffers,
         })
     }
 }
 
 impl Drop for EditBox {
     fn drop(&mut self) {
-        let text_mesh = std::mem::replace(&mut *self.text_mesh.lock().unwrap(), None);
-        // We're finished with these so clean up.
-        if let Some(old) = text_mesh {
-            self.render_api.delete_buffer(old.vertex_buffer);
-            self.render_api.delete_buffer(old.index_buffer);
-        }
+        *self.text_mesh.lock().unwrap() = None;
     }
 }
 
@@ -1336,10 +1310,6 @@ impl UIObject for EditBox {
 
         async fn regen_cursor(self_: Arc<EditBox>) {
             let mesh = std::mem::take(&mut *self_.cursor_mesh.lock().unwrap());
-            let mut freed = self_.freed.lock().unwrap();
-            if let Some(mesh) = mesh {
-                freed.add_mesh(mesh);
-            }
         }
         on_modify.when_change(self.cursor_color.prop(), regen_cursor);
         on_modify.when_change(self.cursor_ascent.prop(), regen_cursor);

+ 1 - 17
bin/darkwallet/src/ui/image.rs

@@ -135,9 +135,6 @@ impl Image {
         };
         self.render_api.replace_draw_calls(draw_update.draw_calls);
         debug!(target: "ui::image", "replace draw calls done");
-        for buff in draw_update.freed_buffers {
-            self.render_api.delete_buffer(buff);
-        }
     }
 
     /// Called whenever any property changes.
@@ -160,13 +157,6 @@ impl Image {
 
         let texture = self.texture.lock().unwrap().clone().expect("Node missing texture_id!");
 
-        // We're finished with these so clean up.
-        let mut freed_buffers = vec![];
-        if let Some(old) = old_mesh {
-            freed_buffers.push(old.vertex_buffer);
-            freed_buffers.push(old.index_buffer);
-        }
-
         let mesh = GfxDrawMesh {
             vertex_buffer: mesh.vertex_buffer,
             index_buffer: mesh.index_buffer,
@@ -187,7 +177,6 @@ impl Image {
                     z_index: self.z_index.get(),
                 },
             )],
-            freed_buffers,
         })
     }
 }
@@ -227,11 +216,6 @@ impl Drop for Image {
 
         // Free buffers
         // Should this be in drop?
-        if let Some(mesh) = &*self.mesh.lock().unwrap() {
-            let vertex_buffer = mesh.vertex_buffer;
-            let index_buffer = mesh.index_buffer;
-            self.render_api.delete_buffer(vertex_buffer);
-            self.render_api.delete_buffer(index_buffer);
-        }
+        *self.mesh.lock().unwrap() = None;
     }
 }

+ 1 - 3
bin/darkwallet/src/ui/layer.rs

@@ -102,7 +102,6 @@ impl Layer {
 
         let mut draw_calls = vec![];
         let mut child_calls = vec![];
-        let mut freed_buffers = vec![];
 
         // We should return a draw call so that if the layer is made visible, we can just
         // recalculate it and update in place.
@@ -116,7 +115,6 @@ impl Layer {
 
                 draw_calls.append(&mut draw_update.draw_calls);
                 child_calls.push(draw_update.key);
-                freed_buffers.append(&mut draw_update.freed_buffers);
             }
         }
 
@@ -126,7 +124,7 @@ impl Layer {
             z_index: self.z_index(),
         };
         draw_calls.push((self.dc_key, dc));
-        Some(DrawUpdate { key: self.dc_key, draw_calls, freed_buffers })
+        Some(DrawUpdate { key: self.dc_key, draw_calls })
     }
 }
 

+ 0 - 17
bin/darkwallet/src/ui/mod.rs

@@ -96,7 +96,6 @@ pub trait UIObject: Sync {
 pub struct DrawUpdate {
     pub key: u64,
     pub draw_calls: Vec<(u64, GfxDrawCall)>,
-    pub freed_buffers: Vec<GfxBufferId>,
 }
 
 pub struct OnModify<T> {
@@ -187,19 +186,3 @@ pub fn get_children_ordered(node: &SceneNode3) -> Vec<SceneNodePtr> {
     let nodes = child_infs.into_iter().rev().map(|(node, _)| node).collect();
     nodes
 }
-
-#[derive(Default)]
-pub struct FreedData {
-    pub buffers: Vec<GfxBufferId>,
-    pub textures: Vec<GfxTextureId>,
-}
-
-impl FreedData {
-    pub fn add_mesh(&mut self, mesh: GfxDrawMesh) {
-        self.buffers.push(mesh.vertex_buffer);
-        self.buffers.push(mesh.index_buffer);
-    }
-    pub fn add_texture(&mut self, texture_id: GfxTextureId) {
-        self.textures.push(texture_id);
-    }
-}

+ 0 - 9
bin/darkwallet/src/ui/text.rs

@@ -166,11 +166,6 @@ impl Text {
         };
         self.render_api.replace_draw_calls(draw_update.draw_calls);
         debug!(target: "ui::text", "replace draw calls done");
-
-        // We're finished with these so clean up.
-        for buff in draw_update.freed_buffers {
-            self.render_api.delete_buffer(buff);
-        }
     }
 
     async fn get_draw_calls(&self, parent_rect: Rectangle) -> Option<DrawUpdate> {
@@ -213,10 +208,6 @@ impl Text {
                     z_index: self.z_index.get(),
                 },
             )],
-            freed_buffers: vec![
-                old_render_info.mesh.vertex_buffer,
-                old_render_info.mesh.index_buffer,
-            ],
         })
     }
 }

+ 0 - 9
bin/darkwallet/src/ui/vector_art/mod.rs

@@ -97,9 +97,6 @@ impl VectorArt {
             return;
         };
         self.render_api.replace_draw_calls(draw_update.draw_calls);
-        for buff in draw_update.freed_buffers {
-            self.render_api.delete_buffer(buff);
-        }
         debug!(target: "ui::vector_art", "replace draw calls done");
     }
 
@@ -121,11 +118,6 @@ impl VectorArt {
         };
 
         let old_mesh = std::mem::replace(&mut *self.buffers.lock().unwrap(), Some(mesh.clone()));
-        let mut freed_buffers = vec![];
-        if let Some(old_mesh) = old_mesh {
-            freed_buffers.push(old_mesh.vertex_buffer);
-            freed_buffers.push(old_mesh.index_buffer);
-        }
 
         Some(DrawUpdate {
             key: self.dc_key,
@@ -140,7 +132,6 @@ impl VectorArt {
                     z_index: self.z_index.get(),
                 },
             )],
-            freed_buffers,
         })
     }
 }

+ 0 - 6
bin/darkwallet/src/ui/win.rs

@@ -421,7 +421,6 @@ impl Window {
 
         let mut draw_calls = vec![];
         let mut child_calls = vec![];
-        let mut freed_buffers = vec![];
 
         for child in self.get_children() {
             let obj = get_ui_object3(&child);
@@ -432,7 +431,6 @@ impl Window {
 
             draw_calls.append(&mut draw_update.draw_calls);
             child_calls.push(draw_update.key);
-            freed_buffers.append(&mut draw_update.freed_buffers);
         }
 
         let dc = GfxDrawCall {
@@ -445,10 +443,6 @@ impl Window {
 
         self.render_api.replace_draw_calls(draw_calls);
 
-        for buff in freed_buffers {
-            self.render_api.delete_buffer(buff);
-        }
-
         debug!(target: "ui::win", "Window::draw() - replaced draw call");
     }
 }