Hi Jim, Thanks, that makes things much clearer.
I was surprised how much was going on under the hood of GraphicsContext and hoped it was just magic glue that gave the best of GPU acceleration where available and immediate-mode-like simple rasterizing where not. I've managed to find an anomaly with GraphicsContext.fillPolygon where the software pipeline achieves the full 60fps but ES2 can only manage 30-35fps. It uses lots of overlapping filled triangles so I expect suffers from the problem you've described. SSCCE: https://github.com/chriswhocodes/DemoFX/blob/master/src/main/java/com/chrisnewland/demofx/standalone/Sierpinski.java Was full frame rate canvas drawing an expected use case for JavaFX or would I be better off with Graphics2D? Thanks, Chris On Mon, March 30, 2015 20:04, Jim Graham wrote: > 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%2 >>> 2In% >>> 20Progress%22%2C%20Reopened)%20AND%20labels%20in%20(macosx)%20%20AND%2 >>> 0la >>> 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 >>> >> >> >