Hi Chris,
drawLine() is a very simple primitive that can be optimized with a GPU
shader. It either looks like a (potentially rotated) rectangle or a
rounded rect - and we have optimized shaders for both cases. A large
number of drawLine() calls turns into simply accumulating a large vertex
list and uploading it to the GPU with an appropriate shader which is
very fast.
drawPolygon() is a very complex operation that involves things like:
- dealing with line joins between segments that don't exist for drawLine()
- dealing with only rendering common points of intersection once
To handle all of that complexity we have to involve a rasterizer that
takes the entire collection of lines, analyzes the stroke attributes and
interactions and computes a coverage mask for each pixel in the region.
We do that in software currently for all pipelines.
For the ES2 pipeline Line.v.Poly is dominated by pure GPU vs CPU path
rasterization.
For the SW pipeline, drawLine is a simplified case of drawPolygon and so
the overhead of lots of calls to drawLine() dominates its performance.
I would expect ES2 to blow the SW pipeline out of the water with
drawLine() performance (as long as there are no additional rendering
primitives interspersed in the set of lines).
But, both should be on the same footing for the drawPolygon case. Does
the ES2 pipeline compare similarly (hopefully better than) the SW
pipeline for the polygon case?
One thing I noticed is that we have no optimized case for drawLine() on
the SW pipeline. It generates a path containing a single MOVETO and
LINETO and feeds it to the generalized path rasterizer when it could
instead compute the rounded/square rectangle and render it more
directly. If we added that support then I'd expect the SW pipeline to
perform the set of drawLine calls faster than drawPolygon as well...
...jim
On 3/28/15 3:22 AM, Chris Newland wrote:
Hi Robert,
I've not filed a Jira yet as I was hoping to find time to investigate
thoroughly but when I saw your question I thought I'd better add my
findings.
I believe the issue is in the ES2Pipeline as if I run with
-Dprism.order=sw then strokePolygon outperforms the series of strokeLine
commands as expected:
java -cp target/DemoFX.jar -Dprism.order=sw
com.chrisnewland.demofx.DemoFXApplication -c 500 -m line
Result: 44fps
java -cp target/DemoFX.jar -Dprism.order=sw
com.chrisnewland.demofx.DemoFXApplication -c 500 -m poly
Result: 60fps
Will see if I can find the root cause as I've got plenty more examples
where ES2Pipeline performs horribly on my Mac which should have no problem
throwing around a few thousand polys.
I realise there's a *lot* of indirection involved in making JavaFX support
such a wide range of underlying graphics systems but I do think there's a
bug here.
Will file a Jira if I can contribute a bit more than "feels slow" ;)
Cheers,
Chris
On Sat, March 28, 2015 10:06, Robert Krüger wrote:
This is consistent with what I am observing. Is this something that
Oracle
is aware of? Looking at Jira, I don't see that anyone is working on this:
https://javafx-jira.kenai.com/issues/?jql=status%20in%20(Open%2C%20%22In%
20Progress%22%2C%20Reopened)%20AND%20labels%20in%20(macosx)%20%20AND%20la
bels%20in%20(performance)
Given that one of the One of the main reasons to use JFX for me is to be
able to develop with one code base for at least OSX and Windows and the
official statement what JavaFX is for, i.e.
"JavaFX is a set of graphics and media packages that enables developers
to design, create, test, debug, and deploy rich client applications that
operate consistently across diverse platforms"
and the fact that this is clearly not the case currently (8u40) as soon
as I do something else than simple forms, I run into performance/quality
problems on the Mac, I am a bit unsure what to make of all that. Is Mac
OSX
a second-class citizen as far as dev resources are concerned?
Tobi and Chris, have you filed Jira Issues on Mac graphics performance
that can be tracked?
I will file an issue with a simple test case and hope for the best.
On Fri, Mar 27, 2015 at 11:08 PM, Chris Newland
<cnewl...@chrisnewland.com>
wrote:
Possibly related:
I can reproduce a massive (90%) performance drop on OSX between drawing
a wireframe polygon on a Canvas using a series of gc.strokeLine(double
x1, double y1, double x2, double y2) commands versus using a single
gc.strokePolygon(double[] xPoints, double[] yPoints, int count)
command.
Creating the polygons manually with strokeLine() is significantly
faster using the ES2Pipeline on OSX.
This is reproducible in a little GitHub JavaFX benchmarking project
I've
created: https://github.com/chriswhocodes/DemoFX
Build with ant
Run with:
# use strokeLine
./run.sh -c 5000 -m line
result: 60 (sixty) fps
# use strokePolygon
./run.sh -c 5000 -m poly
result: 6 (six) fps
System is 2011 iMac 27" / Mavericks / 3.4GHz Core i7 / 20GB RAM /
Radeon
6970M 1024MB
Looking at the code paths in javafx.scene.canvas.GraphicsContext:
gc.strokeLine() maps to writeOp4(x1, y1, x2, y2, NGCanvas.STROKE_LINE)
gc.strokePolygon() maps to writePoly(xPoints, yPoints, nPoints, true,
NGCanvas.STROKE_PATH) which involves significantly more work with
adding to and flushing a GrowableDataBuffer.
I've not had time to dig any deeper than this but it's surely a bug
when building a poly manually is 10x faster than using the convenience
method.
Cheers,
Chris
On Fri, March 27, 2015 21:26, Tobias Bley wrote:
In my opinion the whole graphics performance on MacOSX isn’t
good at all with JavaFX….
Am 27.03.2015 um 22:10 schrieb Robert Krüger
<krue...@lesspain.de>:
The bad full screen performance is without the arcs. It is just one
call to fillRect, two to strokeOval and one to fillOval, that's
all. I will build a simple test case and file an issue.
On Fri, Mar 27, 2015 at 9:58 PM, Jim Graham
<james.gra...@oracle.com>
wrote:
Hi Robert,
Please file a Jira issue with a simple test case. Arcs are
handled as a generalized shape rather than via a predetermined
shader, but it shouldn't be that slow. Something else may be
going on.
Another test might be to replace the arcs with rectangles or
ellipses and see if the performance changes...
...jim
On 3/27/15 1:52 PM, Robert Krüger wrote:
Hi,
I have a super-simple animation implemented using
AnimationTimer
and Canvas where the canvas just performs a few draw operations,
i.e. fills the screen with a color and then draws and fills 2-3
circles and I have already observed that each drawing operation
I add, results in
significant CPU load (e.g. when I draw < 10 arcs in addition to
the circles, the CPU load goes up to 30-40% on a Mac Book Pro
for a Canvas size of 600x600(!).
Now I tested the animation in full screen mode (only with a few
circles) and playback is unusable for a serious application
(very
choppy). Is 2D canvas performance known to be very bad on Mac or
am I doing something
wrong? Are there workarounds for this?
Thanks,
Robert
--
Robert Krüger
Managing Partner
Lesspain GmbH & Co. KG
www.lesspain-software.com
--
Robert Krüger
Managing Partner
Lesspain GmbH & Co. KG
www.lesspain-software.com