summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2009-12-24 15:28:51 -0500
committerSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2009-12-24 15:28:51 -0500
commita6eea7b4d6dd3e4385919b4a50a58688f9a6b52b (patch)
tree066ebbc77d4f6d01aa5e07f137fbcff212ff2128
parenta33070eb0e61eff275c60051161d8310ec2e1851 (diff)
downloadscreen-a6eea7b4d6dd3e4385919b4a50a58688f9a6b52b.tar.gz
Re-optimize screen updates.
In only the top line and the bottom line had to be updated, we were updating the entire region in between as well! This clearly is bad. So instead of doing that, just update the lines that need changing. Thanks to Chris Jones for reporting the bug.
-rw-r--r--src/canvas.c3
-rw-r--r--src/layer.c80
-rw-r--r--src/layer.h14
-rw-r--r--src/window.c1
4 files changed, 71 insertions, 27 deletions
diff --git a/src/canvas.c b/src/canvas.c
index a6c15ab..4cc4fe2 100644
--- a/src/canvas.c
+++ b/src/canvas.c
@@ -81,6 +81,7 @@ struct canvas *pcv;
cv->c_slnext = pcv->c_slnext;
if (cv->c_slnext)
cv->c_slnext->c_slprev = cv;
+ LayerCleanupMemory(&pcv->c_blank);
free(pcv);
}
@@ -102,6 +103,7 @@ struct canvas *cv;
{
while (cv->c_slperp)
FreeCanvas(cv->c_slperp);
+ LayerCleanupMemory(&cv->c_blank);
free(cv);
return;
}
@@ -133,6 +135,7 @@ struct canvas *cv;
free(vp);
}
evdeq(&cv->c_captev);
+ LayerCleanupMemory(&cv->c_blank);
free(cv);
}
diff --git a/src/layer.c b/src/layer.c
index 067d2ef..c71c731 100644
--- a/src/layer.c
+++ b/src/layer.c
@@ -1172,6 +1172,7 @@ ExitOverlayPage()
ocv->c_lnext = cv;
}
oldlay->l_cvlist = 0;
+ LayerCleanupMemory(oldlay);
free((char *)oldlay);
LayRestore();
LaySetCursor();
@@ -1206,6 +1207,7 @@ int pause;
{
struct canvas *cv;
struct display *olddisplay = display;
+ int line;
pause = !!pause;
@@ -1215,16 +1217,13 @@ int pause;
if ((layer->l_pause.d = pause))
{
/* Start pausing */
- layer->l_pause.top = layer->l_pause.bottom =
- layer->l_pause.left = layer->l_pause.right = -1;
+ layer->l_pause.top = layer->l_pause.bottom = -1;
return;
}
/* Unpause. So refresh the regions in the displays! */
if (layer->l_pause.top == -1 &&
- layer->l_pause.bottom == -1 &&
- layer->l_pause.left == -1 &&
- layer->l_pause.right == -1)
+ layer->l_pause.bottom == -1)
return;
for (cv = layer->l_cvlist; cv; cv = cv->c_lnext)
@@ -1235,18 +1234,24 @@ int pause;
for (vp = cv->c_vplist; vp; vp = vp->v_next)
{
- int xs = layer->l_pause.left + vp->v_xoff;
- int xe = layer->l_pause.right + vp->v_xoff;
- int ys = layer->l_pause.top + vp->v_yoff;
- int ye = layer->l_pause.bottom + vp->v_yoff;
-
- if (xs < vp->v_xs) xs = vp->v_xs;
- if (xe > vp->v_xe) xe = vp->v_xe;
- if (ys < vp->v_ys) ys = vp->v_ys;
- if (ye > vp->v_ye) ye = vp->v_ye;
-
- if (xs <= xe && ys <= ye)
- RefreshArea(xs, ys, xe, ye, 0);
+ for (line = layer->l_pause.top; line <= layer->l_pause.bottom; line++)
+ {
+ int xs, xe;
+
+ if (line + vp->v_yoff >= vp->v_ys && line + vp->v_yoff <= vp->v_ye &&
+ ((xs = layer->l_pause.left[line]) >= 0) &&
+ ((xe = layer->l_pause.right[line]) >= 0))
+ {
+ xs += vp->v_xoff;
+ xe += vp->v_xoff;
+
+ if (xs < vp->v_xs) xs = vp->v_xs;
+ if (xe > vp->v_xe) xe = vp->v_xe;
+
+ if (xs <= xe)
+ RefreshLine(line + vp->v_yoff, xs, xe, 0);
+ }
+ }
}
if (cv == D_forecv)
@@ -1263,6 +1268,8 @@ int pause;
}
}
+ for (line = layer->l_pause.top; line <= layer->l_pause.bottom; line++)
+ layer->l_pause.left[line] = layer->l_pause.right[line] = -1;
olddisplay = display;
}
@@ -1274,7 +1281,6 @@ int ys, ye;
{
if (!layer->l_pause.d)
return;
-
if (ye >= layer->l_height)
ye = layer->l_height - 1;
if (xe >= layer->l_width)
@@ -1283,10 +1289,38 @@ int ys, ye;
if (layer->l_pause.top == -1 || layer->l_pause.top > ys)
layer->l_pause.top = ys;
if (layer->l_pause.bottom < ye)
- layer->l_pause.bottom = ye;
- if (layer->l_pause.left == -1 || layer->l_pause.left > xs)
- layer->l_pause.left = xs;
- if (layer->l_pause.right < xe)
- layer->l_pause.right = xe;
+ {
+ layer->l_pause.bottom = ye;
+ if (layer->l_pause.lines <= ye)
+ {
+ int o = layer->l_pause.lines;
+ layer->l_pause.lines = ye + 32;
+ layer->l_pause.left = realloc(layer->l_pause.left, sizeof(int) * layer->l_pause.lines);
+ layer->l_pause.right = realloc(layer->l_pause.right, sizeof(int) * layer->l_pause.lines);
+ while (o < layer->l_pause.lines)
+ {
+ layer->l_pause.left[o] = layer->l_pause.right[o] = -1;
+ o++;
+ }
+ }
+ }
+
+ while (ys <= ye)
+ {
+ if (layer->l_pause.left[ys] == -1 || layer->l_pause.left[ys] > xs)
+ layer->l_pause.left[ys] = xs;
+ if (layer->l_pause.right[ys] < xe)
+ layer->l_pause.right[ys] = xe;
+ ys++;
+ }
}
+void
+LayerCleanupMemory(layer)
+struct layer *layer;
+{
+ if (layer->l_pause.left)
+ free(layer->l_pause.left);
+ if (layer->l_pause.right)
+ free(layer->l_pause.right);
+}
diff --git a/src/layer.h b/src/layer.h
index 5db4997..7d5da0b 100644
--- a/src/layer.h
+++ b/src/layer.h
@@ -77,10 +77,9 @@ struct layer
int d : 1; /* Is the output for the layer blocked? */
/* After unpausing, what region should we refresh? */
- int top;
- int bottom;
- int left;
- int right;
+ int *left, *right;
+ int top, bottom;
+ int lines;
} l_pause;
};
@@ -152,3 +151,10 @@ void LayPause __P((struct layer *layer, int pause));
*/
void LayPauseUpdateRegion __P((struct layer *layer, int xs, int xe, int ys, int ye));
+/**
+ * Free any internal memory for the layer.
+ *
+ * @param layer The layer.
+ */
+void LayerCleanupMemory __P((struct layer *layer));
+
diff --git a/src/window.c b/src/window.c
index bb232c2..aaad8ad 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1022,6 +1022,7 @@ struct win *wp;
wp->w_layer.l_cvlist = 0;
if (flayer == &wp->w_layer)
flayer = 0;
+ LayerCleanupMemory(&wp->w_layer);
#ifdef MULTIUSER
FreeWindowAcl(wp);