Ver código fonte

wallet: chatview upscale text depending on window_scale

darkfi 1 ano atrás
pai
commit
b340ebf197

+ 32 - 4
bin/darkwallet/src/app/schema.rs

@@ -80,6 +80,8 @@ const FONTSIZE: f32 = 40.;
 const FONTSIZE: f32 = 20.;
 
 pub(super) async fn make_test(app: &App, window: SceneNodePtr) {
+    let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
+
     let mut cc = Compiler::new();
 
     // Create a layer called view
@@ -257,7 +259,15 @@ pub(super) async fn make_test(app: &App, window: SceneNodePtr) {
     node.set_property_u32(Role::App, "z_index", 1).unwrap();
 
     let node = node
-        .setup(|me| Text::new(me, app.render_api.clone(), app.text_shaper.clone(), app.ex.clone()))
+        .setup(|me| {
+            Text::new(
+                me,
+                window_scale.clone(),
+                app.render_api.clone(),
+                app.text_shaper.clone(),
+                app.ex.clone(),
+            )
+        })
         .await;
     layer_node.link(node);
 
@@ -420,6 +430,7 @@ pub(super) async fn make_test(app: &App, window: SceneNodePtr) {
             ChatView::new(
                 me,
                 chat_tree,
+                window_scale,
                 app.render_api.clone(),
                 app.text_shaper.clone(),
                 app.ex.clone(),
@@ -430,7 +441,7 @@ pub(super) async fn make_test(app: &App, window: SceneNodePtr) {
 }
 
 pub(super) async fn make(app: &App, window: SceneNodePtr) {
-    let screen_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
+    let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
 
     let mut cc = Compiler::new();
 
@@ -517,7 +528,15 @@ pub(super) async fn make(app: &App, window: SceneNodePtr) {
     node.set_property_u32(Role::App, "z_index", 1).unwrap();
 
     let node = node
-        .setup(|me| Text::new(me, app.render_api.clone(), app.text_shaper.clone(), app.ex.clone()))
+        .setup(|me| {
+            Text::new(
+                me,
+                window_scale.clone(),
+                app.render_api.clone(),
+                app.text_shaper.clone(),
+                app.ex.clone(),
+            )
+        })
         .await;
     layer_node.link(node);
 
@@ -602,6 +621,7 @@ pub(super) async fn make(app: &App, window: SceneNodePtr) {
             ChatView::new(
                 me,
                 chat_tree,
+                window_scale.clone(),
                 app.render_api.clone(),
                 app.text_shaper.clone(),
                 app.ex.clone(),
@@ -668,7 +688,15 @@ pub(super) async fn make(app: &App, window: SceneNodePtr) {
     node.set_property_u32(Role::App, "z_index", 2).unwrap();
 
     let node = node
-        .setup(|me| Text::new(me, app.render_api.clone(), app.text_shaper.clone(), app.ex.clone()))
+        .setup(|me| {
+            Text::new(
+                me,
+                window_scale.clone(),
+                app.render_api.clone(),
+                app.text_shaper.clone(),
+                app.ex.clone(),
+            )
+        })
         .await;
     layer_node.link(node);
 

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

@@ -182,6 +182,7 @@ impl ChatView {
     pub async fn new(
         node: SceneNodeWeak,
         tree: sled::Tree,
+        window_scale: PropertyFloat32,
         render_api: RenderApiPtr,
         text_shaper: TextShaperPtr,
         ex: ExecutorPtr,
@@ -284,6 +285,7 @@ impl ChatView {
                     nick_colors.clone(),
                     hi_bg_color.clone(),
                     debug.clone(),
+                    window_scale,
                     render_api,
                     text_shaper,
                 )),
@@ -691,7 +693,9 @@ impl UIObject for ChatView {
         let rect = self.rect.get();
 
         let mut msgbuf = self.msgbuf.lock().await;
+        msgbuf.adjust_window_scale().await;
         msgbuf.adjust_width(rect.w);
+        msgbuf.clear_meshes();
 
         let mut scroll = self.scroll.get();
         if let Some(scroll) = self.adjust_scroll(&mut msgbuf, scroll, rect.h).await {

+ 166 - 52
bin/darkwallet/src/ui/chatview/page.rs

@@ -52,8 +52,9 @@ fn is_whitespace(s: &str) -> bool {
 }
 
 #[derive(Clone)]
-pub(super) struct PrivMessage {
+pub struct PrivMessage {
     font_size: f32,
+    window_scale: f32,
 
     timestamp: Timestamp,
     id: MessageId,
@@ -70,8 +71,9 @@ pub(super) struct PrivMessage {
 }
 
 impl PrivMessage {
-    pub(super) async fn new(
+    pub async fn new(
         font_size: f32,
+        window_scale: f32,
 
         timestamp: Timestamp,
         id: MessageId,
@@ -83,11 +85,8 @@ impl PrivMessage {
         text_shaper: &TextShaper,
         render_api: &RenderApi,
     ) -> Message {
-        let dt = Local.timestamp_millis_opt(timestamp as i64).unwrap();
-        let timestr = dt.format("%H:%M").to_string();
-
-        let linetext = format!("{} {} {}", timestr, nick, text);
-        let unwrapped_glyphs = text_shaper.shape(linetext, font_size).await;
+        let linetext = Self::gen_line_text(timestamp, &nick, &text);
+        let unwrapped_glyphs = text_shaper.shape(linetext, font_size * window_scale).await;
 
         let mut atlas = text::Atlas::new(render_api);
         atlas.push(&unwrapped_glyphs);
@@ -95,6 +94,7 @@ impl PrivMessage {
 
         let mut self_ = Self {
             font_size,
+            window_scale,
             timestamp,
             id,
             nick,
@@ -109,6 +109,13 @@ impl PrivMessage {
         Message::Priv(self_)
     }
 
+    fn gen_line_text(timestamp: Timestamp, nick: &str, text: &str) -> String {
+        let dt = Local.timestamp_millis_opt(timestamp as i64).unwrap();
+        let timestr = dt.format("%H:%M").to_string();
+
+        format!("{} {} {}", timestr, nick, text)
+    }
+
     fn height(&self, line_height: f32) -> f32 {
         self.wrapped_lines.len() as f32 * line_height
     }
@@ -204,8 +211,14 @@ impl PrivMessage {
             section = 0;
         }
 
-        let glyph_pos_iter = GlyphPositionIter::new(self.font_size, line, baseline);
-        for (mut glyph_rect, glyph) in glyph_pos_iter.zip(line.iter()) {
+        let glyph_pos_iter = GlyphPositionIter::new(
+            self.font_size * self.window_scale,
+            line,
+            baseline * self.window_scale,
+        );
+        for (glyph_rect, glyph) in glyph_pos_iter.zip(line.iter()) {
+            let mut glyph_rect = glyph_rect / self.window_scale;
+
             let uv_rect = self.atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
             glyph_rect.y -= off_y;
 
@@ -227,13 +240,36 @@ impl PrivMessage {
         }
     }
 
-    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
-        std::mem::replace(&mut self.mesh_cache, None)
+    /// clear_mesh() must be called after this.
+    async fn adjust_window_scale(
+        &mut self,
+        window_scale: f32,
+        text_shaper: &TextShaper,
+        render_api: &RenderApi,
+    ) -> GfxTextureId {
+        self.window_scale = window_scale;
+
+        let linetext = Self::gen_line_text(self.timestamp, &self.nick, &self.text);
+        self.unwrapped_glyphs = text_shaper.shape(linetext, self.font_size * window_scale).await;
+
+        let texture_id = self.atlas.texture_id;
+
+        let mut atlas = text::Atlas::new(render_api);
+        atlas.push(&self.unwrapped_glyphs);
+        self.atlas = atlas.make();
+
+        texture_id
     }
 
+    /// clear_mesh() must be called after this.
     fn adjust_width(&mut self, line_width: f32) {
         // Invalidate wrapped_glyphs and recalc
-        self.wrapped_lines = text::wrap(line_width, self.font_size, &self.unwrapped_glyphs);
+        self.wrapped_lines =
+            text::wrap(line_width * self.window_scale, self.font_size, &self.unwrapped_glyphs);
+    }
+
+    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
+        std::mem::replace(&mut self.mesh_cache, None)
     }
 
     fn select(&mut self) {
@@ -250,8 +286,10 @@ impl std::fmt::Debug for PrivMessage {
 }
 
 #[derive(Clone)]
-pub(super) struct DateMessage {
+pub struct DateMessage {
     font_size: f32,
+    window_scale: f32,
+
     timestamp: Timestamp,
     glyphs: Vec<Glyph>,
 
@@ -260,35 +298,66 @@ pub(super) struct DateMessage {
 }
 
 impl DateMessage {
-    pub(super) async fn new(
+    pub async fn new(
         font_size: f32,
+        window_scale: f32,
+
         timestamp: Timestamp,
 
         text_shaper: &TextShaper,
         render_api: &RenderApi,
     ) -> Message {
+        let datestr = Self::datestr(timestamp);
+        let timestamp = Self::timest_to_midnight(timestamp);
+
+        let glyphs = text_shaper.shape(datestr, font_size).await;
+
+        let mut atlas = text::Atlas::new(render_api);
+        atlas.push(&glyphs);
+        let atlas = atlas.make();
+
+        Message::Date(Self { font_size, window_scale, timestamp, glyphs, atlas, mesh_cache: None })
+    }
+
+    fn datestr(timestamp: Timestamp) -> String {
         let dt = Local.timestamp_millis_opt(timestamp as i64).unwrap();
         let datestr = dt.format("%a %-d %b %Y").to_string();
+        datestr
+    }
 
+    fn timest_to_midnight(timestamp: Timestamp) -> Timestamp {
+        let dt = Local.timestamp_millis_opt(timestamp as i64).unwrap();
         let dt2 = dt.date_naive().and_hms_opt(0, 0, 0).unwrap();
         assert_eq!(dt.date_naive(), dt2.date());
         let timestamp = Local.from_local_datetime(&dt2).unwrap().timestamp_millis() as u64;
+        timestamp
+    }
 
-        let glyphs = text_shaper.shape(datestr, font_size).await;
+    /// clear_mesh() must be called after this.
+    async fn adjust_window_scale(
+        &mut self,
+        window_scale: f32,
+        text_shaper: &TextShaper,
+        render_api: &RenderApi,
+    ) -> GfxTextureId {
+        self.window_scale = window_scale;
+
+        let datestr = Self::datestr(self.timestamp);
+        self.glyphs = text_shaper.shape(datestr, self.font_size * window_scale).await;
+
+        let texture_id = self.atlas.texture_id;
 
         let mut atlas = text::Atlas::new(render_api);
-        atlas.push(&glyphs);
-        let atlas = atlas.make();
+        atlas.push(&self.glyphs);
+        self.atlas = atlas.make();
 
-        Message::Date(Self { font_size, timestamp, glyphs, atlas, mesh_cache: None })
+        texture_id
     }
 
-    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
-        None
-    }
+    //fn adjust_width(&mut self, line_width: f32) { }
 
-    fn adjust_width(&mut self, line_width: f32) {
-        // Do nothing
+    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
+        std::mem::replace(&mut self.mesh_cache, None)
     }
 
     fn gen_mesh(
@@ -357,10 +426,15 @@ impl Message {
         }
     }
 
-    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
+    async fn adjust_window_scale(
+        &mut self,
+        window_scale: f32,
+        text_shaper: &TextShaper,
+        render_api: &RenderApi,
+    ) -> GfxTextureId {
         match self {
-            Self::Priv(m) => m.clear_mesh(),
-            Self::Date(m) => m.clear_mesh(),
+            Self::Priv(m) => m.adjust_window_scale(window_scale, text_shaper, render_api).await,
+            Self::Date(m) => m.adjust_window_scale(window_scale, text_shaper, render_api).await,
         }
     }
 
@@ -371,6 +445,13 @@ impl Message {
         }
     }
 
+    fn clear_mesh(&mut self) -> Option<GfxDrawMesh> {
+        match self {
+            Self::Priv(m) => m.clear_mesh(),
+            Self::Date(m) => m.clear_mesh(),
+        }
+    }
+
     fn gen_mesh(
         &mut self,
         clip: &Rectangle,
@@ -433,9 +514,9 @@ fn select_nick_color(nick: &str, nick_colors: &[Color]) -> Color {
 }
 
 #[derive(Default)]
-pub(super) struct FreedData {
-    pub(super) buffers: Vec<GfxBufferId>,
-    pub(super) textures: Vec<GfxTextureId>,
+pub struct FreedData {
+    pub buffers: Vec<GfxBufferId>,
+    pub textures: Vec<GfxTextureId>,
 }
 
 impl FreedData {
@@ -452,8 +533,8 @@ pub struct MessageBuffer {
     /// From most recent to older
     msgs: Vec<Message>,
     date_msgs: HashMap<NaiveDate, Message>,
-    pub(super) freed: FreedData,
-    pub(super) line_width: f32,
+    pub freed: FreedData,
+    pub line_width: f32,
 
     font_size: PropertyFloat32,
     line_height: PropertyFloat32,
@@ -464,12 +545,17 @@ pub struct MessageBuffer {
     hi_bg_color: PropertyColor,
     debug: PropertyBool,
 
+    window_scale: PropertyFloat32,
+    /// Used to detect if the window scale was changed when drawing.
+    /// If it does then we must reload the glyphs too.
+    old_window_scale: f32,
+
     render_api: RenderApiPtr,
     text_shaper: TextShaperPtr,
 }
 
 impl MessageBuffer {
-    pub(super) fn new(
+    pub fn new(
         font_size: PropertyFloat32,
         line_height: PropertyFloat32,
         baseline: PropertyFloat32,
@@ -478,9 +564,11 @@ impl MessageBuffer {
         nick_colors: PropertyPtr,
         hi_bg_color: PropertyColor,
         debug: PropertyBool,
+        window_scale: PropertyFloat32,
         render_api: RenderApiPtr,
         text_shaper: TextShaperPtr,
     ) -> Self {
+        let old_window_scale = window_scale.get();
         Self {
             msgs: vec![],
             date_msgs: HashMap::new(),
@@ -496,14 +584,30 @@ impl MessageBuffer {
             hi_bg_color,
             debug,
 
+            window_scale,
+            old_window_scale,
+
             render_api,
             text_shaper,
         }
     }
 
+    pub async fn adjust_window_scale(&mut self) {
+        let window_scale = self.window_scale.get();
+        if self.old_window_scale == window_scale {
+            return
+        }
+
+        for msg in &mut self.msgs {
+            let old_texture_id =
+                msg.adjust_window_scale(window_scale, &self.text_shaper, &self.render_api).await;
+            self.freed.add_texture(old_texture_id);
+        }
+    }
+
     /// For scrolling we want to be able to adjust and measure without
     /// explicitly rendering since it may be off screen.
-    pub(super) fn adjust_width(&mut self, line_width: f32) {
+    pub fn adjust_width(&mut self, line_width: f32) {
         if (line_width - self.line_width).abs() < f32::EPSILON {
             return;
         }
@@ -512,12 +616,10 @@ impl MessageBuffer {
         for msg in &mut self.msgs {
             msg.adjust_width(line_width);
         }
-
-        self.clear_meshes();
     }
 
     /// Clear all meshes and caches. Returns data that needs to be freed.
-    fn clear_meshes(&mut self) {
+    pub fn clear_meshes(&mut self) {
         for msg in &mut self.msgs {
             if let Some(mesh) = msg.clear_mesh() {
                 self.freed.add_mesh(mesh);
@@ -525,7 +627,7 @@ impl MessageBuffer {
         }
     }
 
-    pub(super) async fn calc_total_height(&mut self) -> f32 {
+    pub async fn calc_total_height(&mut self) -> f32 {
         let line_height = self.line_height.get();
         let mut height = 0.;
 
@@ -539,7 +641,7 @@ impl MessageBuffer {
         height
     }
 
-    pub(super) async fn insert_privmsg(
+    pub async fn insert_privmsg(
         &mut self,
         timest: Timestamp,
         message_id: MessageId,
@@ -548,9 +650,11 @@ impl MessageBuffer {
     ) {
         //debug!(target: "ui::chatview", "MessageBuffer::insert_privmsg()");
         let font_size = self.font_size.get();
+        let window_scale = self.window_scale.get();
 
         let msg = PrivMessage::new(
             font_size,
+            window_scale,
             timest,
             message_id,
             nick,
@@ -595,7 +699,7 @@ impl MessageBuffer {
         self.msgs.insert(idx, msg);
     }
 
-    pub(super) async fn push_privmsg(
+    pub async fn push_privmsg(
         &mut self,
         timest: Timestamp,
         message_id: MessageId,
@@ -603,9 +707,11 @@ impl MessageBuffer {
         text: String,
     ) -> f32 {
         let font_size = self.font_size.get();
+        let window_scale = self.window_scale.get();
 
         let msg = PrivMessage::new(
             font_size,
+            window_scale,
             timest,
             message_id,
             nick,
@@ -628,11 +734,7 @@ impl MessageBuffer {
     }
 
     /// Generate caches and return meshes
-    pub(super) async fn gen_meshes(
-        &mut self,
-        rect: &Rectangle,
-        scroll: f32,
-    ) -> Vec<(f32, GfxDrawMesh)> {
+    pub async fn gen_meshes(&mut self, rect: &Rectangle, scroll: f32) -> Vec<(f32, GfxDrawMesh)> {
         let line_height = self.line_height.get();
         let baseline = self.baseline.get();
         let debug_render = self.debug.get();
@@ -685,6 +787,7 @@ impl MessageBuffer {
     /// Gets around borrow checker with unsafe
     fn msgs_with_date(&mut self) -> impl Stream<Item = &mut Message> {
         let font_size = self.font_size.get();
+        let window_scale = self.window_scale.get();
         AsyncIter::from(async_gen! {
             let mut last_date = None;
 
@@ -697,7 +800,7 @@ impl MessageBuffer {
 
                 if let Some(newer_date) = last_date {
                     if newer_date != older_date {
-                        let datemsg = self.get_date_msg(newer_date, font_size).await;
+                        let datemsg = self.get_date_msg(newer_date, font_size, window_scale).await;
                         let datemsg = unsafe { &mut *(datemsg as *mut Message) };
                         //debug!(target: "ui::chatview", "Adding date: {idx} {datemsg:?}");
                         yield datemsg;
@@ -710,32 +813,43 @@ impl MessageBuffer {
             }
 
             if let Some(date) = last_date {
-                let datemsg = self.get_date_msg(date, font_size).await;
+                let datemsg = self.get_date_msg(date, font_size, window_scale).await;
                 let datemsg = unsafe { &mut *(datemsg as *mut Message) };
                 yield datemsg;
             }
         })
     }
 
-    async fn get_date_msg(&mut self, date: NaiveDate, font_size: f32) -> &mut Message {
+    async fn get_date_msg(
+        &mut self,
+        date: NaiveDate,
+        font_size: f32,
+        window_scale: f32,
+    ) -> &mut Message {
         let dt = date.and_hms_opt(0, 0, 0).unwrap();
         let timest = Local.from_local_datetime(&dt).unwrap().timestamp_millis() as u64;
 
         if !self.date_msgs.contains_key(&date) {
-            let datemsg =
-                DateMessage::new(font_size, timest, &self.text_shaper, &self.render_api).await;
+            let datemsg = DateMessage::new(
+                font_size,
+                window_scale,
+                timest,
+                &self.text_shaper,
+                &self.render_api,
+            )
+            .await;
             self.date_msgs.insert(date, datemsg);
         }
 
         self.date_msgs.get_mut(&date).unwrap()
     }
 
-    pub(super) fn oldest_timestamp(&self) -> Option<Timestamp> {
+    pub fn oldest_timestamp(&self) -> Option<Timestamp> {
         let last_msg = &self.msgs.last()?;
         Some(last_msg.timestamp())
     }
 
-    pub(super) fn latest_timestamp(&self) -> Option<Timestamp> {
+    pub fn latest_timestamp(&self) -> Option<Timestamp> {
         let first_msg = &self.msgs.first()?;
         Some(first_msg.timestamp())
     }
@@ -754,7 +868,7 @@ impl MessageBuffer {
         colors
     }
 
-    pub(super) async fn select_line(&mut self, y: f32) {
+    pub async fn select_line(&mut self, y: f32) {
         let line_height = self.line_height.get();
 
         let msgs = self.msgs_with_date();

+ 37 - 26
bin/darkwallet/src/ui/text.rs

@@ -62,12 +62,14 @@ pub struct Text {
     baseline: PropertyFloat32,
     debug: PropertyBool,
 
+    window_scale: PropertyFloat32,
     parent_rect: SyncMutex<Option<Rectangle>>,
 }
 
 impl Text {
     pub async fn new(
         node: SceneNodeWeak,
+        window_scale: PropertyFloat32,
         render_api: RenderApiPtr,
         text_shaper: TextShaperPtr,
         ex: ExecutorPtr,
@@ -94,6 +96,7 @@ impl Text {
             text_color.get(),
             baseline.get(),
             debug.get(),
+            window_scale.get(),
         )
         .await;
 
@@ -123,6 +126,7 @@ impl Text {
                 baseline,
                 debug,
 
+                window_scale,
                 parent_rect: SyncMutex::new(None),
             }
         });
@@ -138,14 +142,18 @@ impl Text {
         text_color: Color,
         baseline: f32,
         debug: bool,
+        window_scale: f32,
     ) -> TextRenderInfo {
         debug!(target: "ui::text", "Rendering label '{}'", text);
-        let glyphs = text_shaper.shape(text, font_size).await;
+        let glyphs = text_shaper.shape(text, font_size * window_scale).await;
         let atlas = text::make_texture_atlas(render_api, &glyphs);
 
         let mut mesh = MeshBuilder::new();
-        let glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
-        for (glyph_rect, glyph) in glyph_pos_iter.zip(glyphs.iter()) {
+        let glyph_pos_iter =
+            GlyphPositionIter::new(font_size * window_scale, &glyphs, baseline * window_scale);
+        for (mut glyph_rect, glyph) in glyph_pos_iter.zip(glyphs.iter()) {
+            let glyph_rect = glyph_rect / window_scale;
+
             let uv_rect = atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
 
             if debug {
@@ -165,21 +173,6 @@ impl Text {
     }
 
     async fn redraw(self: Arc<Self>) {
-        let old = self.render_info.lock().unwrap().clone();
-
-        let render_info = Self::regen_mesh(
-            &self.render_api,
-            &self.text_shaper,
-            self.text.get(),
-            self.font_size.get(),
-            self.text_color.get(),
-            self.baseline.get(),
-            self.debug.get(),
-        )
-        .await;
-
-        *self.render_info.lock().unwrap() = render_info;
-
         let Some(parent_rect) = self.parent_rect.lock().unwrap().clone() else { return };
 
         let Some(draw_update) = self.get_draw_calls(parent_rect).await else {
@@ -190,11 +183,12 @@ impl Text {
         debug!(target: "ui::text", "replace draw calls done");
 
         // We're finished with these so clean up.
-        assert!(draw_update.freed_textures.is_empty());
-        assert!(draw_update.freed_buffers.is_empty());
-        self.render_api.delete_buffer(old.mesh.vertex_buffer);
-        self.render_api.delete_buffer(old.mesh.index_buffer);
-        self.render_api.delete_texture(old.texture_id);
+        for texture in draw_update.freed_textures {
+            self.render_api.delete_texture(texture);
+        }
+        for buff in draw_update.freed_buffers {
+            self.render_api.delete_buffer(buff);
+        }
     }
 
     async fn get_draw_calls(&self, parent_rect: Rectangle) -> Option<DrawUpdate> {
@@ -202,7 +196,21 @@ impl Text {
         self.rect.eval(&parent_rect).ok()?;
         let rect = self.rect.get();
 
-        let render_info = self.render_info.lock().unwrap().clone();
+        let old_render_info = self.render_info.lock().unwrap().clone();
+
+        let render_info = Self::regen_mesh(
+            &self.render_api,
+            &self.text_shaper,
+            self.text.get(),
+            self.font_size.get(),
+            self.text_color.get(),
+            self.baseline.get(),
+            self.debug.get(),
+            self.window_scale.get(),
+        )
+        .await;
+
+        *self.render_info.lock().unwrap() = render_info.clone();
 
         let mesh = GfxDrawMesh {
             vertex_buffer: render_info.mesh.vertex_buffer,
@@ -224,8 +232,11 @@ impl Text {
                     z_index: self.z_index.get(),
                 },
             )],
-            freed_textures: vec![],
-            freed_buffers: vec![],
+            freed_textures: vec![old_render_info.texture_id],
+            freed_buffers: vec![
+                old_render_info.mesh.vertex_buffer,
+                old_render_info.mesh.index_buffer,
+            ],
         })
     }
 }