From: Michael D. Lowis Date: Mon, 17 Dec 2018 15:01:55 +0000 (-0500) Subject: reworked redraw code to batch glyphs more efficiently and to only redraw on cycles... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=2b4299e3686895d25aacddd192af5deb2e852e6b;p=projs%2Ftide.git reworked redraw code to batch glyphs more efficiently and to only redraw on cycles where we received an event --- diff --git a/src/lib/x11.c b/src/lib/x11.c index f9cc3b0..c646320 100644 --- a/src/lib/x11.c +++ b/src/lib/x11.c @@ -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);