Bad performance with Canvas and extensive clipping

Jim Graham james.graham at oracle.com
Fri May 23 21:35:23 UTC 2014


Are you clipping to an arbitrary path in all cases or just a rectangle? 
  Unfortunately we only offer the arbitrary clip-to-current-path method 
that isn't optimized for basic rectangular clipping and it implements 
soft clipping.

There is an outstanding tweak that we added faster clipping support for 
WebNode and we need to start using it for 
Node.setClipNode(non-rectangle) and Canvas, but we haven't implemented 
that yet.  (https://javafx-jira.kenai.com/browse/RT-30107)  It basically 
is a direct "render this texture through that other texture as a clip" 
operation instead of the current code that runs it through some Blend 
effect filters.  It would definitely improve your run times, but I'm not 
sure how much.

Even more savings could be had for rectangular clips if we provided some 
way to communicate them to the GC...

			...jim

On 5/23/14 11:47 AM, Tom Schindl wrote:
> Hi,
>
> Maybe as some of you might know I've been working since sometime on SWT
> on JavaFX and to implement direct drawing operations we use JavaFX-Canvas.
>
> I've today tried to run a heavy direct drawing grid implementation and
> it performed very bad because it makes heavy use of clipping.
>
> For a grid I've counted ~1500 clipping operations the library works
> something like this:
>
> boolean activeClip;
> Canvas canvas = new Canvas();
>
> public void setClipping(PathIterator pathIterator) {
>    GraphicsContext gc = canvas.getGraphicsContext2D();
>    if(activeClip) {
>      gc.restore();
>      activeClip= false;
>    }
>
>    if( pathIterator == null ) {
>      return;
>    }
>
>    activeClip = true;
>    float coords[] = new float[6];
>    gc.save();
> 		gc.beginPath();
> 		
> 		float x = 0;
> 		float y = 0;
> 		
> 		
> 		gc.moveTo(0, 0);
> 		
> 		while( ! pathIterator.isDone() ) {
> 			switch (pathIterator.currentSegment(coords)) {
> 			case PathIterator.SEG_CLOSE:
> 				gc.lineTo(x, y);
> 				break;
> 			case PathIterator.SEG_CUBICTO:
> 				gc.bezierCurveTo(coords[0], coords[1], coords[2], coords[3],
> coords[4], coords[5]);
> 				break;
> 			case PathIterator.SEG_LINETO:
> 				gc.lineTo(coords[0], coords[1]);
> 				break;
> 			case PathIterator.SEG_MOVETO:
> 				gc.moveTo(coords[0], coords[1]);
> 				x = coords[0];
> 				y = coords[1];
> 				break;
> 			case PathIterator.SEG_QUADTO:
> 				gc.quadraticCurveTo(coords[0], coords[1], coords[2], coords[3]);
> 				break;
> 			default:
> 				break;
> 			}
> 			pathIterator.next();
> 		}
> 		
> 		gc.clip();
> 		gc.closePath();
> }
>
> Am I doing something ultimately wrong, totally wrong? Has anyone an idea
> how I would work around the problem?
>
> Tom
>


More information about the openjfx-dev mailing list