Bad performance with Canvas and extensive clipping
Tom Schindl
tom.schindl at bestsolution.at
Fri May 23 21:57:37 UTC 2014
In the current usecase it is a rect all time but that's just in this special use case.
I guess that rect clipping is the most common one so having an optimization for rects and a slow path for none rects might help.
Tom
Von meinem iPhone gesendet
> Am 23.05.2014 um 23:35 schrieb Jim Graham <james.graham at oracle.com>:
>
> 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