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