diff options
author | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2009-12-24 15:28:51 -0500 |
---|---|---|
committer | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2009-12-24 15:28:51 -0500 |
commit | a6eea7b4d6dd3e4385919b4a50a58688f9a6b52b (patch) | |
tree | 066ebbc77d4f6d01aa5e07f137fbcff212ff2128 | |
parent | a33070eb0e61eff275c60051161d8310ec2e1851 (diff) | |
download | screen-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.c | 3 | ||||
-rw-r--r-- | src/layer.c | 80 | ||||
-rw-r--r-- | src/layer.h | 14 | ||||
-rw-r--r-- | src/window.c | 1 |
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); |