]> git.mdlowis.com Git - projs/tide.git/commitdiff
reworked redraw code to batch glyphs more efficiently and to only redraw on cycles...
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 17 Dec 2018 15:01:55 +0000 (10:01 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 17 Dec 2018 15:01:55 +0000 (10:01 -0500)
src/lib/x11.c

index f9cc3b0d8516beedd8ca55179ad50b3a62cdf8e2..c646320baf82b41459a83e16322bf3fb623f647d 100644 (file)
@@ -234,6 +234,8 @@ static bool draw_csr(View* view, size_t fheight, int x, int y, bool csrdrawn) {
 }
 
 static void draw_view(View* view, XftFont* font, size_t nrows, drawcsr* csr, int bg, int fg, int sel) {
+    int nspecs = 0;
+    XftGlyphSpec* specs = NULL;
     size_t fheight = font->height;
     bool csr_drawn = false;
     /* draw the view to the window */
@@ -243,7 +245,6 @@ static void draw_view(View* view, XftFont* font, size_t nrows, drawcsr* csr, int
     for (size_t i = 0; i < nrows; i++) {
         Row* row = view_getrow(view, i + view->index);
         size_t x = (csr->x + 2), y = (csr->y + 2 + (i * fheight));
-        XftGlyphSpec specs[row->len];
         for (size_t i = 0; i < row->len; i++) {
             int rune = row->cols[i].rune;
             if (rune == '\r' || rune == '\n' ||  rune == '\t')
@@ -252,14 +253,16 @@ static void draw_view(View* view, XftFont* font, size_t nrows, drawcsr* csr, int
                 draw_rect(sel, x, y, row->cols[i].width, fheight);
             if (row->cols[i].off == view->buffer.selection.end)
                 csr_drawn = draw_csr(view, fheight, x, y, csr_drawn);
-            specs[i].glyph = XftCharIndex(X.display, font, rune);
-            specs[i].x = x;
-            specs[i].y = y + font->ascent;
+            specs = realloc(specs, sizeof(XftGlyphSpec) * ++nspecs);
+            specs[nspecs-1].glyph = XftCharIndex(X.display, font, rune);
+            specs[nspecs-1].x = x;
+            specs[nspecs-1].y = y + font->ascent;
             x += row->cols[i].width;
         }
-        x11_draw_glyphs(&X, Palette[fg], font, specs, row->len);
     }
+    x11_draw_glyphs(&X, Palette[fg], font, specs, nspecs);
     csr->y += (nrows * fheight) + 3;
+    free(specs);
 }
 
 static void draw_hrule(drawcsr* csr) {
@@ -427,7 +430,7 @@ static void xupdate(Job* job) {
     (void)job;
     int nevents;
     /* process events from the queue */
-    XEventsQueued(X.display, QueuedAfterFlush);
+    int dirty = XEventsQueued(X.display, QueuedAfterFlush);
     XGetMotionEvents(X.display, X.self, CurrentTime, CurrentTime, &nevents);
     for (XEvent e; XPending(X.display);) {
         XNextEvent(X.display, &e);
@@ -435,20 +438,23 @@ static void xupdate(Job* job) {
             (X.eventfns[e.type])(&X, &e);
         for (int status; waitpid(-1, &status, WNOHANG) > 0;);
     }
-    /* determine the size of the regions */
-    size_t maxtagrows = ((X.height/4) / X.tagfont->height);
-    size_t tagrows = view_limitrows(win_view(TAGS), maxtagrows);
-    size_t tagregsz = (tagrows * X.tagfont->height) + 7;
-    size_t editrows = (X.height - tagregsz) / X.font->height ;
-    /* draw the regions to the window */
-    drawcsr csr = { .w = X.width, .h = X.height };
-    csr.x += ScrollWidth + 1;
-    draw_statbox();
-    draw_view(&Regions[TAGS], X.tagfont, tagrows, &csr, TagsBg, TagsFg, TagsSel);
-    draw_hrule(&csr);
-    draw_view(&Regions[EDIT], X.font, editrows, &csr, EditBg, EditFg, EditSel);
-    draw_scroll(&csr);
-    XCopyArea(X.display, X.pixmap, X.self, X.gc, 0, 0, X.width, X.height, 0, 0);
+    /* only redraw if we processed some events */
+    if (dirty || nevents) {
+        /* determine the size of the regions */
+        size_t maxtagrows = ((X.height/4) / X.tagfont->height);
+        size_t tagrows = view_limitrows(win_view(TAGS), maxtagrows);
+        size_t tagregsz = (tagrows * X.tagfont->height) + 7;
+        size_t editrows = (X.height - tagregsz) / X.font->height ;
+        /* draw the regions to the window */
+        drawcsr csr = { .w = X.width, .h = X.height };
+        csr.x += ScrollWidth + 1;
+        draw_statbox();
+        draw_view(&Regions[TAGS], X.tagfont, tagrows, &csr, TagsBg, TagsFg, TagsSel);
+        draw_hrule(&csr);
+        draw_view(&Regions[EDIT], X.font, editrows, &csr, EditBg, EditFg, EditSel);
+        draw_scroll(&csr);
+        XCopyArea(X.display, X.pixmap, X.self, X.gc, 0, 0, X.width, X.height, 0, 0);
+    }
     XFlush(X.display);
 }
 
@@ -497,13 +503,13 @@ void win_init(KeyBinding* bindings) {
     X.eventfns[ClientMessage] = xclientmsg;
     X.eventfns[ConfigureNotify] = xresize;
 
-    /* initialize
-selection atoms */
+    /* initialize selection atoms */
     for (unsigned int i = 0; i < (sizeof(Selections) / sizeof(Selections[0])); i++)
         Selections[i].atom = XInternAtom(X.display, Selections[i].name, 0);
     SelTarget = XInternAtom(X.display, "UTF8_STRING", 0);
     if (SelTarget == None)
         SelTarget = XInternAtom(X.display, "STRING", 0);
+
     /* Populate the  tags region */
     View* view = win_view(TAGS);
     view_putstr(view, TagString);