+clear_tiles(struct app_state *state, Display *display, Drawable d,
+ int x0, int y0, int x1, int y1, Dimension w, Dimension h)
+{
+ XRectangle r = { x0*w, y0*h, (x1+1)*w, (y1+1)*h };
+
+#if X11_RENDER_DEBUG
+ 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);
+}
+
+/*
+ * 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);
+}
+
+static int