One more try at bug 829 (same surface corruption)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



After talking with Lionel Ulmer offline I came up with the following 
patch for bug 829. It includes a hopefully more clear comment of when 
the corruption can occure and a better set of rules.

Change log: fix same surface corruption when no flags are set and areas 
are the same size

Tony Lambregts tony_lambregts@telusplanet.net
Index: dib.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/dib.c,v
retrieving revision 1.11
diff -u -r1.11 dib.c
--- dib.c	28 Jun 2002 17:32:25 -0000	1.11
+++ dib.c	9 Jul 2002 03:57:37 -0000
@@ -351,6 +351,7 @@
     int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
     int x, y;
     LPBYTE dbuf, sbuf;
+    BOOL SameSurfaceOK = TRUE;
 
     TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
 
@@ -474,6 +475,18 @@
 	sbase = (BYTE*)sdesc.lpSurface+(xsrc.top*sdesc.u1.lPitch)+xsrc.left*bpp;
 	xinc = (srcwidth << 16) / dstwidth;
 	yinc = (srcheight << 16) / dstheight;
+        SameSurfaceOK = ((src != iface)||
+                        (sbase >= dbuf)||
+                        (xdst.top > xsrc.bottom)||(xdst.left > xsrc.right)||(xdst.right < xsrc.left));
+
+        /* 
+        A little explination: Screen coruption can occure if the following set of circumstances is true 
+
+        1.) Both the source and destination are the same surface. -->(src != iface) 
+        2.) The start of the source is less than the destination .  -->(sbase >= dbuf) 
+        3.) There is overlap.  -->(xdst.top < xsrc.bottom)&&(xdst.left < xsrc.right)(xdst.right < xsrc.left)
+        This is fixed in the case where no flags are set and the areas are the same size. 
+        */
 
 	if (!dwFlags) {
 	    /* No effects, we can cheat here */
@@ -482,11 +495,29 @@
 		    /* No stretching in either direction. This needs to be as
 		     * fast as possible */
 		    sbuf = sbase;
-		    for (y = 0; y < dstheight; y++) {
-			memcpy(dbuf, sbuf, width);
-			sbuf += sdesc.u1.lPitch;
-			dbuf += ddesc.u1.lPitch;
-		    }
+                    if (SameSurfaceOK) {
+                       for (y = 0; y < dstheight; y++) {
+                          memcpy(dbuf, sbuf, width);
+                          sbuf += sdesc.u1.lPitch;
+                          dbuf += ddesc.u1.lPitch;
+                       }
+                    } else {
+                       sbuf += (sdesc.u1.lPitch*dstheight);
+                       dbuf += (ddesc.u1.lPitch*dstheight);
+                       if (xdst.top == xsrc.top) { /* Are the source and destination on the same line? */
+                          for (y = 0; y < dstheight; y++) {
+                             sbuf -= sdesc.u1.lPitch;
+                             dbuf -= ddesc.u1.lPitch;
+                             memmove(dbuf, sbuf, width);
+                          }   
+                       } else {
+                          for (y = 0; y < dstheight; y++) {
+                             sbuf -= sdesc.u1.lPitch;
+                             dbuf -= ddesc.u1.lPitch;
+                             memcpy(dbuf, sbuf, width);
+                          }
+                       }
+                    }
 		} else {
 		    /* Stretching in Y direction only */
 		    for (y = sy = 0; y < dstheight; y++, sy += yinc) {
@@ -544,6 +575,10 @@
 	    }
 	} else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE)) {
 	    DWORD keylow, keyhigh;
+
+            if (!SameSurfaceOK) {
+               FIXME("\tSoure and destination surfaces are the same and could cause display problems\n");
+            }
 
 	    if (dwFlags & DDBLT_KEYSRC) {
 		keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux