Bad performance with Canvas and extensive clipping
Tom Schindl
tom.schindl at bestsolution.at
Sat May 24 00:46:05 UTC 2014
Hi,
As an experiment I've now written a SWT-GC implementation using a
BufferedImage & Graphics2D and transfering the pixels over to JavaFX and
the performance is as it is with native SWT.
I always thought Canvas works similar to Image and one only draws pixels
- looks like that is not the case, having a dep in my application
java.awt is not what I'm aiming at but without acceptable performance in
conjunction with clipping it looks like i have to go this route :-(
Tom
On 23.05.14 23:57, Tom Schindl wrote:
> 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