Is there anything I could do to help getting rectangular clipping into JavaFX - I tried to find my way through the sources but I'm not sure I have enough knowledge to provide a patch in this area.
BTW it looks like I'm not alone with the clipping performance problem see http://tomsondev.bestsolution.at/2014/05/24/swtonfx-javafx-canvas-with-many-clipping-calls-unacceptable-slow/#comments Tom On 27.05.14 23:47, Jim Graham wrote: > Canvas is, essentially, a "draw pixels" mechanism. We have to bundle > the requests into a command stream due to threading issues, but when the > requests get to the render thread then they get turned into pixels so > the command stream is a temporary intermediary. Some of the hw J2D > pipelines also have a temporary command stream due to platform threading > issues as well. It all depends on which pipeline you use and on which > platform in the case of J2D. FX simply normalized the threading on all > pipelines/platforms so that we have a separate UI and render thread in > all cases, but that concept is not foreign to J2D either. > > I'm fairly certain that the lack of simple rectangular clipping is > probably the biggest cause of your performance problems. We do AA on > everything in FX, though, whereas rendering to a BufferedImage by > default will be non-AA unless you requested AA using the graphics hints. > But on the up-side, we hw accelerate just about every operation in FX > so it should be on par with performance there, modulo the lack of > rectangular clipping... > > ...jim > > On 5/23/14 5:46 PM, Tom Schindl wrote: >> 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.gra...@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 >>>>> >>