From: Nick Bowler Date: Wed, 7 Dec 2022 06:37:25 +0000 (-0500) Subject: motif: simplify border_clear implementation. X-Git-Url: http://git.draconx.ca/gitweb/rrace.git/commitdiff_plain/1ad1b0dcce2ad67f1aaa559c7a76cf0a6cbab03b motif: simplify border_clear implementation. This was cute, but since we no longer draw empty tiles in response to expose events there are only two situations where the optimized border clear is actually used: - when the game is won, or - when the window is resized. In both cases the entire border needs to be cleared, meaning all this code to reduce the number of drawing calls is optimizing for a case that literally never happens. --- diff --git a/src/x11.c b/src/x11.c index f827965..b098d0e 100644 --- a/src/x11.c +++ b/src/x11.c @@ -140,72 +140,36 @@ static void draw_tile(struct app_state *state, Display *display, Drawable d, XFillRectangle(display, d, state->tile_gc, tx+2, ty+2, tw-4, th-4); } -/* - * Clear a contiguous rectangle of tiles from top-left (x0, y0) to - * bottom-right (x1, y1). - */ -static void -clear_tiles(struct app_state *state, Display *display, Drawable d, - int x0, int y0, int x1, int y1, Dimension w, Dimension h) +static void clear_rect(struct app_state *state, Display *display, Drawable d, + int x, int y, int w, int h) { - XRectangle r = { x0*w, y0*h, (x1+1)*w, (y1+1)*h }; - #if X11_RENDER_DEBUG + XRectangle r = { x, y, w, h }; + XSetForeground(display, state->tile_gc, 0xff0000); XFillRectangles(display, d, state->tile_gc, &r, 1); XFlush(display); usleep(70000); #endif - XClearArea(display, d, r.x, r.y, r.width, r.height, 0); + XClearArea(display, d, x, y, w, h, 0); } /* * Efficiently clear all the border tiles in the game area. The mask indicates * which tiles need clearing, but for the border clear it is safe to wipe an * entire row or column of the border using a single XClearArea. - * - * The idea is to pick whichever row or column has the most tiles to clear, - * clear them, and then repeat until none are left (repeats at most 4 times). */ static void clear_border(struct app_state *state, Display *display, Drawable d, Dimension w, Dimension h, uint_fast32_t mask) { - uint_fast32_t best_mask = 0; - int best_count = -1; - int i, best = -1; - if (!(mask &= ~GOAL_MASK & 0x1ffffff)) return; - for (i = 0; i < 4; i++) { - uint_fast32_t this_mask, tmp; - int this_count = 0; - - if (i & 2) - this_mask = board_column(4*(i & 1)); - else - this_mask = board_row(4*(i & 1)); - - /* Count set bits */ - for (tmp = mask & this_mask; tmp; this_count++) - tmp &= tmp - 1; - - if (this_count > best_count) { - best_count = this_count; - best_mask = this_mask; - best = i; - } - } - - switch (best) { - case 0: clear_tiles(state, display, d, 0, 0, 4, 0, w, h); break; - case 1: clear_tiles(state, display, d, 0, 4, 4, 4, w, h); break; - case 2: clear_tiles(state, display, d, 0, 0, 0, 4, w, h); break; - case 3: clear_tiles(state, display, d, 4, 0, 4, 4, w, h); break; - } - - clear_border(state, display, d, w, h, mask & ~best_mask); + clear_rect(state, display, d, 0, 0, 5*w, h); + clear_rect(state, display, d, 0, 4*h, 5*w, h); + clear_rect(state, display, d, 0, 0, w, 5*h); + clear_rect(state, display, d, 4*w, 0, w, 5*h); } static int