--- old/src/solaris/classes/sun/java2d/xr/XRRenderer.java 2013-08-24 14:31:20.531912913 +0200 +++ new/src/solaris/classes/sun/java2d/xr/XRRenderer.java 2013-08-24 14:31:20.427912203 +0200 @@ -53,10 +53,15 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { XRDrawHandler drawHandler; MaskTileManager tileManager; + XRDrawLine lineGen; + GrowableRectArray rectBuffer; public XRRenderer(MaskTileManager tileManager) { this.tileManager = tileManager; + this.rectBuffer = tileManager.getMainTile().getRects(); + this.drawHandler = new XRDrawHandler(); + this.lineGen = new XRDrawLine(); } /** @@ -77,20 +82,16 @@ int transX2 = Region.clipAdd(x2, sg2d.transX); int transY2 = Region.clipAdd(y2, sg2d.transY); - // Non clipped fast path - if (compClip.contains(transX1, transY1) - && compClip.contains(transX2, transY2)) { - SunToolkit.awtLock(); - try { - validateSurface(sg2d); - tileManager.addLine(transX1, transY1, transX2, transY2); - tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); - } finally { - SunToolkit.awtUnlock(); - } - } else { - draw(sg2d, new Line2D.Float(x1, y1, x2, y2)); - } + SunToolkit.awtLock(); + try { + validateSurface(sg2d); + lineGen.rasterizeLine(rectBuffer, transX1, transY1, + transX2, transY2, compClip.getLoX(), compClip.getLoY(), + compClip.getHiX(), compClip.getHiY(), true, true); + tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); + } finally { + SunToolkit.awtUnlock(); + } } public void drawRect(SunGraphics2D sg2d, @@ -148,7 +149,7 @@ SunToolkit.awtLock(); try { validateSurface(sg2d); - tileManager.addRect(x, y, width, height); + rectBuffer.pushRectValues(x, y, width, height); tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); } finally { SunToolkit.awtUnlock(); @@ -199,11 +200,13 @@ } private class XRDrawHandler extends ProcessPath.DrawHandler { - + DirtyRegion region; + XRDrawHandler() { // these are bogus values; the caller will use validate() // to ensure that they are set properly prior to each usage super(0, 0, 0, 0); + this.region = new DirtyRegion(); } /** @@ -218,15 +221,32 @@ } public void drawLine(int x1, int y1, int x2, int y2) { - tileManager.addLine(x1, y1, x2, y2); + region.setDirtyLineRegion(x1, y1, x2, y2); + int xDiff = region.x2 - region.x; + int yDiff = region.y2 - region.y; + + if (xDiff == 0 || yDiff == 0) { + // horizontal / diagonal lines can be represented by a single + // rectangle + rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x + + 1, region.y2 - region.y + 1); + } else if (xDiff == 1 && yDiff == 1) { + // fast path for pattern commonly generated by + // ProcessPath.DrawHandler + rectBuffer.pushRectValues(x1, y1, 1, 1); + rectBuffer.pushRectValues(x2, y2, 1, 1); + } else { + lineGen.rasterizeLine(rectBuffer, x1, y1, x2, y2, 0, 0, + 0, 0, false, false); + } } public void drawPixel(int x, int y) { - tileManager.addRect(x, y, 1, 1); + rectBuffer.pushRectValues(x, y, 1, 1); } public void drawScanline(int x1, int x2, int y) { - tileManager.addRect(x1, y, x2 - x1 + 1, 1); + rectBuffer.pushRectValues(x1, y, x2 - x1 + 1, 1); } } @@ -263,7 +283,7 @@ validateSurface(sg2d); int[] spanBox = new int[4]; while (si.nextSpan(spanBox)) { - tileManager.addRect(spanBox[0] + transx, + rectBuffer.pushRectValues(spanBox[0] + transx, spanBox[1] + transy, spanBox[2] - spanBox[0], spanBox[3] - spanBox[1]);