]> git.draconx.ca Git - rrace.git/commitdiff
motif: Don't query widget width every timer update.
authorNick Bowler <nbowler@draconx.ca>
Thu, 26 Jan 2023 02:18:13 +0000 (21:18 -0500)
committerNick Bowler <nbowler@draconx.ca>
Thu, 26 Jan 2023 02:18:21 +0000 (21:18 -0500)
Turns out that just getting the widget width from Xt represents
the vast majority of the time spent on the timer update.  It is
very simple to query the width only when it changes, instead,
and save that result for later rendering.

src/xcounter.c
src/xcounter.h

index e8e5d17baa2ad76c532e0436dd6c8dc78990f320..47fdf5b4d8819bb942ebd4f36f3dfdff77e7314d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Helpers for implementing a rapid-update counter display in Motif.
- * Copyright © 2022 Nick Bowler
+ * Copyright © 2022-2023 Nick Bowler
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,6 +48,10 @@ struct xcounter {
        Pixmap pixmap;
 
        uint_least32_t render_mask;
+
+       /* Cached width of the widget */
+       uint_least16_t render_width;
+
        unsigned char seq[23], num_strings;
 
        /*
@@ -80,7 +84,7 @@ xc_alloc(Widget w, XmRenderTable rt, XmString *strings, int nstr)
        xc->widget = w;
 
        for (i = 0; i < nstr; i++) {
-               unsigned w, h;
+               unsigned h;
 
                if ((h = XmStringHeight(rt, strings[i])) > height)
                        height = h + 2*MARGIN;
@@ -209,13 +213,10 @@ static void xc_redraw(struct xcounter *xc, uint_fast32_t mask)
        Drawable d = XtWindow(xc->widget);
 
        unsigned out_x = MARGIN, src_x, w;
-       Dimension max_w, h;
+       Dimension max_w;
        int i;
 
-       XtVaGetValues(xc->widget, XmNwidth, &max_w,
-                                 (char *)NULL);
-       max_w = MAX(MARGIN, max_w) - MARGIN;
-
+       max_w = MAX(MARGIN, xc->render_width) - MARGIN;
        xc_foreach_seq(xc, i, out_x, src_x, w, mask) {
                if (out_x + w > max_w) {
                        w = max_w - out_x;
@@ -339,7 +340,13 @@ void xcounter_expose(struct xcounter *xc, XExposeEvent *e)
 
 void xcounter_resize_cb(Widget w, void *data, void *cb_data)
 {
-       xc_queue_render(data, XC_RESIZING);
+       struct xcounter *xc = data;
+       Dimension width;
+
+       XtVaGetValues(xc->widget, XmNwidth, &width, (char *)NULL);
+       xc->render_width = width;
+
+       xc_queue_render(xc, XC_RESIZING);
 }
 
 void xcounter_expose_cb(Widget w, void *data, void *cb_data)
index e08b8a8a6333fb9b1bc9d9302abfb6182328c0b1..112d485781adab0835a45f4fce4690f1035eab88 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Helpers for implementing a rapid-update counter display in Motif.
- * Copyright © 2022 Nick Bowler
+ * Copyright © 2022-2023 Nick Bowler
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -94,7 +94,8 @@ void xcounter_resize_cb(Widget w, void *data, void *cb_data);
 void xcounter_expose_cb(Widget w, void *data, void *cb_data);
 
 /*
- * Clear the margins of the counter after resizing the widget.
+ * Call after the widget is resized to update the internal dimensions,
+ * and clear the margins.
  *
  * Since the pre-rendered text never changes, this is all that is needed:
  * existing portions of the window do not need to be redrawn (except when