Subject:
two patches for Nano-X blitting
From:
Kaben Nanlohy ####@####.####
Date:
6 Sep 2000 18:50:21 -0000
Message-Id: <Pine.NEB.4.21.0009061050190.27415-100000@kaben.frye.com>
Hi;
I've been having a difficult time with source and destination clipping
while blitting. I was failing various asserts in linear4_blit() from
fblin4.c, namely:
assert (dstx >= 0 && dstx < dstpsd->xres);
assert (dsty >= 0 && dsty < dstpsd->yres);
assert (w > 0);
assert (h > 0);
I only hit the asserts when destination needed clipping, either with
GrCopyArea() or using the pair GsPrepareDrawing(), GdBlit().
Also had difficulty drawing to a given onscreen window, then to a pixmap
of smaller dimensions, then drawing to the window again. The window was
clipped to the dimensions of the pixmap until I drew to a different
window, restoring the clipping cache.
Here are two patches, the first to GdBlit() in
microwin/src/engine/devdraw.c to address the first problem of destination
clipping, and the second to GsPrepareDrawing() in
microwin/src/nanox/srvutil.c to address the confused clipping cache
problem.
The first patch fixes its bug, or so I hope; the second patch is an
interim hack -- it kills the clipping cache after clipping a pixmap, so as
to force it to be refilled correctly. It looks as though someone planned
to have separate caches for pixmaps and windows? This would speed-up
double-buffering in animation and other such stuff.
I'm using microwindows-0.88patch1.
Here are my config options... new patches follow. -- Kaben Nanlohy
ARCH = LINUX-NATIVE
OPTIMIZE = N
DEBUG = Y
VERBOSE = Y
MICROWIN = N
NANOX = Y
SHAREDLIBS = N
NWIDGET = N
OBJFRAMEWORK = N
SCREEN_PIXTYPE = MWPF_PALETTE
LINK_APP_INTO_SERVER = Y
HAVE_FILEIO = N
HAVE_BMP_SUPPORT = N
HAVE_JPEG_SUPPORT = N
HAVE_T1LIB_SUPPORT = N
HAVE_FREETYPE_SUPPORT = N
HAVE_SHAREDMEM_SUPPORT = N
HAVE_HZK_SUPPORT = N
HAVE_GB2312_SUPPORT = N
ERASEMOVE = Y
UPDATEREGIONS = Y
HAVEMSFONTS = N
GRAYPALETTE = N
X11 = Y
SCREEN_E15 = N
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
SCREEN_DEPTH = 4
--- devdraw.c 2000/09/01 21:24:03 1.5
+++ devdraw.c 2000/09/02 00:11:39 1.6
@@ -1146,8 +1146,29 @@
GdBlit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD width, MWCOORD height,
PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long rop)
{
+
+/*
+ * Added by Kaben Nanlohy to fix GdBlit() clipping.
+ * This fix is taken from Morten's GdArea() clip-code.
+ */
+int rx1, rx2, ry1, ry2;
+int px1, px2, py1, py2;
+int pw, ph;
+int count;
+/**/
+
+
+
+
+#if 0 /* Old clipping code commented-out by Kaben. */
int DSTX, DSTY, WIDTH, HEIGHT;
int SRCX, SRCY;
+ int count, dx, dy;
+#endif
+
+
+
+
#if DYNAMICREGIONS
MWRECT * prc;
@@ -1157,7 +1178,6 @@
extern MWCLIPRECT cliprects[];
extern int clipcount;
#endif
- int count, dx, dy;
/*FIXME: compare bpp's and convert if necessary*/
assert(dstpsd->planes == srcpsd->planes);
@@ -1194,6 +1214,11 @@
count = clipcount;
#endif
while(--count >= 0) {
+
+
+
+
+#if 0 /* Old partial-clipping code, commented-out by Kaben. */
#if DYNAMICREGIONS
dx = prc->left - dstx;
dy = prc->top - dsty;
@@ -1240,6 +1265,47 @@
dstpsd->Blit(dstpsd, DSTX, DSTY, WIDTH, HEIGHT,
srcpsd, SRCX, SRCY, rop);
}
+#endif
+
+
+
+/*
+ * Morten's clip-rect code, from GdArea(),
+ * adapted for GdBlit() by Kaben.
+ */
+#if DYNAMICREGIONS
+ rx1 = prc->left;
+ ry1 = prc->top;
+ rx2 = prc->right;
+ ry2 = prc->bottom;
+#else
+ rx1 = prc->x;
+ ry1 = prc->y;
+ rx2 = prc->x + prc->width;
+ ry2 = prc->y + prc->height;
+#endif
+ /* Check: does this rect intersect the one we want to draw? */
+ px1 = dstx;
+ py1 = dsty;
+ px2 = dstx + width;
+ py2 = dsty + height;
+ if (px1 < rx1) px1 = rx1;
+ if (py1 < ry1) py1 = ry1;
+ if (px2 > rx2) px2 = rx2;
+ if (py2 > ry2) py2 = ry2;
+
+ pw = px2 - px1;
+ ph = py2 - py1;
+ if(pw > 0 && ph > 0) {
+ GdCheckCursor(dstpsd, px1, py1, px2-1, py2-1);
+ dstpsd->Blit(dstpsd, px1, py1, pw, ph,
+ srcpsd, srcx + (px1-dstx), srcy + (py1-dsty),
+ rop);
+ }
+/**/
+
+
+
++prc;
}
GdFixCursor(dstpsd);
--- srvutil.c Mon Aug 21 18:55:28 2000
+++ srvutil.c Fri Sep 1 16:14:05 2000
@@ -586,6 +586,14 @@
GdIntersectRegion(reg, reg, regionp->rgn);
}
GdSetClipRegion(pp->psd, reg);
+
+ /*
+ * Shorthack by Kaben Nanlohy -- to prevent later calls to
+ * GsPrepareDrawing() from thinking that this is clipping
+ * for onscreen window.
+ */
+ clipwp = NULL;
+ /**/
#else
{
MWCLIPRECT cliprect;
@@ -595,15 +603,21 @@
cliprect.width = pp->psd->xvirtres;
cliprect.height = pp->psd->yvirtres;
GdSetClipRects(pp->psd, 1, &cliprect);
+
+ /*
+ * Shorthack by Kaben -- to prevent later calls to
+ * GsPrepareDrawing() from thinking that this is clipping
+ * for onscreen window.
+ */
+ clipwp = NULL;
+ /**/
}
#endif
} else {
-
if (!wp->output) {
GsError(GR_ERROR_INPUT_ONLY_WINDOW, id);
return GR_DRAW_TYPE_NONE;
}
-
if (wp->unmapcount)
return GR_DRAW_TYPE_NONE;