Revision: 4015
          http://vexi.svn.sourceforge.net/vexi/?rev=4015&view=rev
Author:   clrg
Date:     2011-02-03 17:49:20 +0000 (Thu, 03 Feb 2011)

Log Message:
-----------
Fix backbuffer and screen dirty regions getting out of sync

Modified Paths:
--------------
    trunk/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java
    trunk/org.vexi-core.main/src/main/java/org/vexi/plat/AWT.java

Modified: trunk/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java
===================================================================
--- trunk/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java   
2011-02-03 15:50:45 UTC (rev 4014)
+++ trunk/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java   
2011-02-03 17:49:20 UTC (rev 4015)
@@ -689,11 +689,11 @@
     }
 
     /** runs the pre-render() and render() pipelines in the root Box to 
regenerate the backbuffer, then blits it to the screen */
-    public synchronized void render() {
+    public synchronized RenderedRegions render() {
         scheduled = false;
         if (minimized) {
             abort = false;
-            return;
+            return null;
         }
         // make sure the root is properly sized
         abortcount = 0;
@@ -720,52 +720,62 @@
 
         final int numregions = dirtyRegions.num();
         final int[] dirt = dirtyRegions.flush();
-        if (dirt!=null) {
-            final PixelBuffer buff = getPixelBuffer();
-            final int rwidth = root.width;
-            final int rheight = root.height;
-            final int scar_y = rheight-scarImage.height;
-            for (int i = 0; dirt != null && i < numregions; i++) {
-                // DirtyList indicates invalid dirty rects (4 consecutive
-                // ints in dirt) by marking the first coordinate -1
-                if (dirt[4*i]<0) {
-                    continue;
-                }
-                // extract dirty area coordinates
-                int x = dirt[4*i];
-                int y = dirt[4*i+1];
-                int w = dirt[4*i+2];
-                int h = dirt[4*i+3];
-                if (x < 0) x = 0;
-                if (y < 0) y = 0;
-                if (w > rwidth) w = rwidth;
-                if (h > rheight) h = rheight;
-                if (w <= x || h <= y) {
-                    continue;
-                }
+        if (dirt==null) return null;
+        
+        final PixelBuffer buff = getPixelBuffer();
+        final int rwidth = root.width;
+        final int rheight = root.height;
+        final int scar_y = rheight-scarImage.height;
+        for (int i = 0; dirt != null && i < numregions; i++) {
+            // DirtyList indicates invalid dirty rects (4 consecutive
+            // ints in dirt) by marking the first coordinate -1
+            if (dirt[4*i]<0) {
+                continue;
+            }
+            // extract dirty area coordinates
+            int x = dirt[4*i];
+            int y = dirt[4*i+1];
+            int w = dirt[4*i+2];
+            int h = dirt[4*i+3];
+            if (x < 0) x = 0;
+            if (y < 0) y = 0;
+            if (w > rwidth) w = rwidth;
+            if (h > rheight) h = rheight;
+            if (w <= x || h <= y) {
+                continue;
+            }
 
-                root.render(0, 0, x, y, w, h, buff);
-                if (scarImage != null) {
-                    if (scarImage.width > x && scar_y < h) {
-                        buff.drawPicture(scarImage, 0, scar_y, x, y, w, h);
-                    }
+            root.render(0, 0, x, y, w, h, buff);
+            if (scarImage != null) {
+                if (scarImage.width > x && scar_y < h) {
+                    buff.drawPicture(scarImage, 0, scar_y, x, y, w, h);
                 }
+            }
 
-                if (abort) {
-                    // x,y,w,h is only partially reconstructed, so we must be 
careful not to re-blit it
-                    dirtyRegions.dirty(x, y, w, h);
-                    // put back all the dirty regions we haven't yet processed 
(including the current one)
-                    for (int j=i; j<numregions; j++) {
-                        int dx = dirt[4*j];
-                        if (dx >= 0) {
-                            dirtyRegions.dirty(dx, dirt[4*j+1], dirt[4*j+2], 
dirt[4*j+3]);
-                        }
+            if (abort) {
+                // x,y,w,h is only partially reconstructed, so we must be 
careful not to re-blit it
+                dirty(x, y, w, h);
+                // put back all the dirty regions we haven't yet processed 
(including the current one)
+                for (int j=i; j<numregions; j++) {
+                    int dx = dirt[4*j];
+                    if (dx >= 0) {
+                        dirty(dx, dirt[4*j+1], dirt[4*j+2], dirt[4*j+3]);
                     }
-                    return;
                 }
+                return new RenderedRegions(dirt, i);
             }
         }
+        return new RenderedRegions(dirt, numregions);
     }
+    
+    public static class RenderedRegions {
+        int[] regions;
+        int numregions;
+        RenderedRegions(int[] regions, int numregions) {
+            this.regions = regions;
+            this.numregions = numregions;
+        }
+    }
 
 
     // Default PixelBuffer implementation 
/////////////////////////////////////////////////////////
@@ -801,63 +811,42 @@
             backbuffer.fillTrapezoid(x1, x2, y1, x3, x4, y2, color);
         }
 
-        public void render() {
-            super.render();
-            final int numregions = screenDirtyRegions.num();
-            final int[] dirt = screenDirtyRegions.flush();
-            if (dirt==null) {
-                return;
-            }
+        public RenderedRegions render() {
+            RenderedRegions r = super.render();
+            if (r==null) return null;
+            int numregions = r.numregions;
+            int[] regions = r.regions;
+            
             final int rwidth = root.width;
             final int rheight = root.height;
             // REMARK: whilst in theory only blitting the dirty areas
             // would seem more efficient, in practise it results in a
             // large slowdown due to a delay in processing each blit,
-            // so instead we just blit a single area covering all the
-            // dirty parts (NB: original implementation below)
+            // so instead we just blit a single all-encompassing area
+            // NB: original implementation in r4011
             int x = root.width;
             int y = root.height;
             int w = 0;
             int h = 0;
             for (int i = 0; i < numregions; i++) {
                 // consumed dirty areas are marked with a -1
-                if (dirt[4*i]<0) {
+                if (regions[4*i]<0) {
                     continue;
                 }
                 // handle confirmed dirty areas
-                x = Math.min(x, dirt[4*i]);
-                y = Math.min(y, dirt[4*i+1]);
-                w = Math.max(w, dirt[4*i+2]);
-                h = Math.max(h, dirt[4*i+3]);
+                x = Math.min(x, regions[4*i]);
+                y = Math.min(y, regions[4*i+1]);
+                w = Math.max(w, regions[4*i+2]);
+                h = Math.max(h, regions[4*i+3]);
             }
             if (x < 0) x = 0;
             if (y < 0) y = 0;
             if (w > rwidth) w = rwidth;
             if (h > rheight) h = rheight;
-            if (w <= x || h <= y) {
-                return;
+            if (w > x && h > y) {
+                blit(backbuffer, x, y, x, y, w, h);
             }
-            blit(backbuffer, x, y, x, y, w, h);
-            // REMARK: the old way
-//            for (int i = 0; i < numregions; i++) {
-//                // consumed dirty areas are marked with a -1
-//                if (dirt[4*i]<0) {
-//                    continue;
-//                }
-//                // handle confirmed dirty areas
-//                int x = dirt[4*i];
-//                int y = dirt[4*i+1];
-//                int w = dirt[4*i+2];
-//                int h = dirt[4*i+3];
-//                if (x < 0) x = 0;
-//                if (y < 0) y = 0;
-//                if (w > rwidth) w = rwidth;
-//                if (h > rheight) h = rheight;
-//                if (w <= x || h <= y) {
-//                    continue;
-//                }
-//                blit(backbuffer, x, y, x, y, w, h);
-//            }
+            return r;
         }
 
         /** This is how subclasses signal a 'shallow dirty', indicating that 
although the backbuffer is valid, the screen is not */

Modified: trunk/org.vexi-core.main/src/main/java/org/vexi/plat/AWT.java
===================================================================
--- trunk/org.vexi-core.main/src/main/java/org/vexi/plat/AWT.java       
2011-02-03 15:50:45 UTC (rev 4014)
+++ trunk/org.vexi-core.main/src/main/java/org/vexi/plat/AWT.java       
2011-02-03 17:49:20 UTC (rev 4015)
@@ -366,7 +366,7 @@
     
     
     protected static class AWTSurface extends Surface.DoubleBufferedSurface
-        implements MouseListener, MouseMotionListener, MouseWheelListener, 
KeyListener, ComponentListener, WindowListener{
+        implements MouseListener, MouseMotionListener, MouseWheelListener, 
KeyListener, ComponentListener, WindowListener {
 
         /** synchronized as otherwise it is possible to blit before images 
have been rendered to the backbuffer */
         public synchronized void blit(PixelBuffer s, int sx, int sy, int dx, 
int dy, int dx2, int dy2) {
@@ -537,7 +537,7 @@
             window.setBackground(rootcolor);
         }
         
-        public void render() {
+        public RenderedRegions render() {
             // useful optimisation;
             if (rootfill != root.getIntFillcolor()) {
                 setBackgroundColor();
@@ -555,7 +555,7 @@
                backbuffer = new_backbuffer;
                dirty();
             }
-            super.render();
+            return super.render();
         }
 
         AWTSurface(Box root, boolean framed) {


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to