The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


campbell's Blog

Leaving Sun

Posted by campbell on January 7, 2010 at 10:29 PM PST

I’ve decided to leave Sun Microsystems, after spending 8+ years there (well, 10+ years if you count my two internships) working on graphics engines for the Java platform. Tomorrow, January 8th, 2010 will be my last day on the job.

For more on this change, check out this longer write-up that I posted to my new blog and website. Note that this will be my last blog entry on java.net, so if you’re accustomed to reading my (increasingly infrequent) entries here, please be sure to update your bookmarks.

Related Topics >> GUI      J2SE      Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

Effects in JavaFX: Chaining

Posted by campbell on June 11, 2009 at 2:04 AM PDT

Picking up where I left off six (cough, cough) months ago, in my series on the effects framework in JavaFX...

In JavaFX, you can chain effects together, contrary to a couple blog entries I've come across recently. This feature may not be entirely obvious from the API documentation, so let's look at chaining in a bit more detail here.

Just like Nodes in the JavaFX scene graph, Effects can be linked together in a tree-like structure. Most Effect subclasses expose one or more "input" variables that allow you to chain Effect instances together. By default, the input variable is set to null, indicating that the rendered contents of the Node to which the Effect is attached will be used as the input to the effect. For example, in the following code snippet, since we do not set the BoxBlur.input variable, the blur effect will be applied to the Text node content:


    Text {
        effect: BoxBlur {}
        content: "Hello!"
        ...
    }

If we instead explicitly set the BoxBlur.input variable to, say, a SepiaTone instance, the sepia effect will first be applied to the node content, and the result of that operation will then be blurred:


    Text {
        effect: BoxBlur {
            input: SepiaTone {}
        }
        content: "Hello!"
        ...
    }

The following is a simple applet that demonstrates what a Text node looks like when one or more effects are chained to it:


(The source bundle for this demo is available here.)

Note that in some situations, the order of the chained effects can be quite significant. One such scenario is in "cover flow" style components, where each node has a Reflection effect and is positioned in (faux) 3D using a PerspectiveTransform. In this case, it is important to apply the reflection effect first, and then transform the result last. If you try it the other way around, the result will be goofily [goofily, really?] non-realistic. The applet above demonstrates the difference in behavior of the two orderings.

Unfortunately, due to a minor technical limitation, we have not yet exposed an input variable on the DropShadow and InnerShadow classes as of the 1.2 release. This will certainly be resolved in an upcoming release. In the meantime, you can achieve the same result (albeit with a bit more code) by using nested Groups. For example, we can apply a Lighting effect to a Text, and then wrap that in a Group that has a DropShadow applied to it:


    Group {
        effect: DropShadow {
            radius: 14
            offsetX: 4
            offsetY: 4
        }
        content: Text {
            effect: Lighting {
                light: DistantLight { azimuth: -135 }
                surfaceScale: 5
            }
        }
    }

In the next few installments, I'll look at individual effects such as Lighting and Reflection in more detail. (Let's hope this time I get to it sooner than six months from now!)


In my ears: Charles Mingus, The Black Saint And The Sinner Lady
In my eyes: Ricky Gervais and Karl Pilkington, The World of Karl Pilkington

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

Its cool, but it would be infinitely more impressive if you bound the content of the Text object to an input box.

Effects in JavaFX: Chaining

Posted by campbell on June 11, 2009 at 2:04 AM PDT

Picking up where I left off six (cough, cough) months ago, in my series on the effects framework in JavaFX...

In JavaFX, you can chain effects together, contrary to a couple blog entries I've come across recently. This feature may not be entirely obvious from the API documentation, so let's look at chaining in a bit more detail here.

Just like Nodes in the JavaFX scene graph, Effects can be linked together in a tree-like structure. Most Effect subclasses expose one or more "input" variables that allow you to chain Effect instances together. By default, the input variable is set to null, indicating that the rendered contents of the Node to which the Effect is attached will be used as the input to the effect. For example, in the following code snippet, since we do not set the BoxBlur.input variable, the blur effect will be applied to the Text node content:


    Text {
        effect: BoxBlur {}
        content: "Hello!"
        ...
    }

If we instead explicitly set the BoxBlur.input variable to, say, a SepiaTone instance, the sepia effect will first be applied to the node content, and the result of that operation will then be blurred:


    Text {
        effect: BoxBlur {
            input: SepiaTone {}
        }
        content: "Hello!"
        ...
    }

The following is a simple applet that demonstrates what a Text node looks like when one or more effects are chained to it:


(The source bundle for this demo is available here.)

Note that in some situations, the order of the chained effects can be quite significant. One such scenario is in "cover flow" style components, where each node has a Reflection effect and is positioned in (faux) 3D using a PerspectiveTransform. In this case, it is important to apply the reflection effect first, and then transform the result last. If you try it the other way around, the result will be goofily [goofily, really?] non-realistic. The applet above demonstrates the difference in behavior of the two orderings.

Unfortunately, due to a minor technical limitation, we have not yet exposed an input variable on the DropShadow and InnerShadow classes as of the 1.2 release. This will certainly be resolved in an upcoming release. In the meantime, you can achieve the same result (albeit with a bit more code) by using nested Groups. For example, we can apply a Lighting effect to a Text, and then wrap that in a Group that has a DropShadow applied to it:


    Group {
        effect: DropShadow {
            radius: 14
            offsetX: 4
            offsetY: 4
        }
        content: Text {
            effect: Lighting {
                light: DistantLight { azimuth: -135 }
                surfaceScale: 5
            }
        }
    }

In the next few installments, I'll look at individual effects such as Lighting and Reflection in more detail. (Let's hope this time I get to it sooner than six months from now!)


In my ears: Charles Mingus, The Black Saint And The Sinner Lady
In my eyes: Ricky Gervais and Karl Pilkington, The World of Karl Pilkington

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

Its cool, but it would be infinitely more impressive if you bound the content of the Text object to an input box.

Effects in JavaFX: Quality

Posted by campbell on January 7, 2009 at 9:29 AM PST
Spitzenqualität

In my last entry, I showed how easy it is to use the Effect API in JavaFX. This time around, I'll focus on visual quality.

JavaFX includes a scene graph API that is vector-based, meaning that elements in the scene will be rendered with high quality, taking into account the resolution of the output device (i.e., the screen) and any transforms that have been applied to the scene graph nodes. Even in a vector graphics library, applying filter effects necessarily requires painting the relevant scene graph nodes into an offscreen raster image so that the implementation can access and manipulate the raw pixels. Care must be taken by the implementation to create an offscreen representation of sufficient resolution so that it still looks great when it is ultimately rendered to the screen.

Take for instance the following example which shows a rounded Rectangle node with a DropShadow applied to it. The slider controls the scale of the shape node, in the range [0.5, 5.0]. Generally speaking, Effect variables operate in the local coordinate system of the Node to which it is applied. In this example we have a DropShadow.radius of 10, which means that at a 1:1 scale the rectangle will be surrounded by a shadow that extends 10 pixels in every direction. But what happens when we change the scale of the Rectangle node? (Try this yourself by dragging the slider back and forth. Or grab the source bundle here.)

Notice that the shadow scales in proportion to the shape itself, which is the desired behavior in nearly all cases. (Think about it: if this red shape represented a button, you'd want the drop shadow to be rendered with the same proportions regardless of whether it is on a relatively low-pixel-density laptop display or on a hi-dpi mobile device.) Also notice that the actual node "content" (the red rectangle) looks crisp under any transform. Pretty, innit?

There are a few different approaches the implementation could take to make this all work. One naïve approach would be to simply render the rectangle at a 1:1 scale into an offscreen image, create a shadow at the same 1:1 scale, merge the two images, and then render the resulting image with a scaling transform and, say, bilinear filtering (see Fig. 1 below). This would offer reasonable performance, but quality would suffer under non-identity transforms, since we're relying on image filtering to smooth the results of the scaling operation (and all this flies in the face of having a vector-based scene graph in the first place). Another dubious approach would be to render the rectangle in the transformed coordinate space, and then create the shadow with a scaled radius (and a potentially huge Gaussian kernel). This would offer great quality, but performance would take a nose dive due to the processing of the large shadow/blur operation.

raster.png
Fig. 1: Raster scaling (bad)
vector.png
Fig. 2: Hybrid vector scaling (good)

Fortunately, the effects framework in JavaFX currently takes a hybrid approach (see Fig. 2 above) that offers the best of both worlds for compound effects like DropShadow and others: high-quality rendering of the actual node content, a shadow that scales in proportion with the content under any transform, and good performance to boot. The implementation is smart enough to 1) render the original node content into an offscreen image with an identity transform for the purposes of creating the shadow, 2) use a filtered image scaling operation to bring it into the final transformed coordinate space, and then 3) render the original node content again over the shadow using the cumulative transform so that it looks just as lovely on the screen as if the effect hadn't been applied at all. Similar techniques are used for other effects, such as Glow and Lighting, to find a good balance between quality and performance, and to keep things looking great at any resolution.

Well, that was a mouthful. Since I'm trying (and struggling) to keep these blog entries short and sweet, let me just say that if you didn't follow all this, that's okay. The takeaway message is that we go through great lengths to make sure that your applications that use JavaFX, and effects in particular, look their best at any resolution.


In my ears: Public Image Ltd., Second Edition
In my eyes: Orhan Pamuk, My Name Is Red

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

does this mean that the shadow is rasterised small and scaled up and the rectangle is rendered as vector graphic after transformation (the "obvious way for rectangles ;)")? this would mean that we would get a performance decrease the other way around: fancy shadowed 1024x1024 rectangle scaled down to 48x48 would be rendered slower than a "native" unscaled but still fancy shadowed 48x48 quad is this correct? very good blog entry, there are not many sources which tell us useful things about jfx

Slider fails to work on Mac OS X 10.5.6 with Java 1.6.0_07.

only one applet starts if i visit the main blog page: http://weblogs.java.net/blog/campbell/ the second spins forever in the loading icon state. 6u11 winxp

skip to the JSL! :) No kidding, this stuff is interesting. bwt, I get the same on the second applet issue: 6u11b3, winxp

@mbien: Currently, yes, that is correct. However, a long time ago I had an idea that for the downscaling case, like the one you cite, we should be able to scale the kernel and work on the downscaled representation, sort of the opposite of the "dubious approach" I referred to above. I never got around to investigating it more, so I just filed a bug on this (http://javafx-jira.kenai.com/browse/RT-2908); thanks for bringing this up.

@mbien, @ilazarte: I'm seeing the same thing on Mac OS X with Safari too. Others have reported it to me internally as well. I've filed a bug here: http://javafx-jira.kenai.com/browse/RT-2907 Thanks for bringing these deployment issues up. I purposely decided to embed JavaFX applets in my last two entries exactly for this reason. Yes, it will be a distraction from the topic at hand at first (because of bugs like these), but it helps to shed light on the pain points in the JavaFX deployment story. If we can't successfully embed simple applets like these, then we can forget about success at a larger scale. Anyway, our deployment team is working to fix these things, so I hope soon we can get back to talking about effects without distraction :)

Reproduced on Vista Ultimate (SP1). Desktop deployment is never an easy task - but at least you have a rock solid language and library to start off with ;-) java version "1.6.0_11" Java(TM) SE Runtime Environment (build 1.6.0_11-b03) Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing) Microsoft Windows [Version 6.0.6001]

Thank you very much for your work Please check you page without Java plugin installed in your browser or without java installed at all. You get 2 message dialogs only with OK button: "Java is required to run JavaFX applications. You will now be redirected to a Java update site..." -- after redirection to java.com/... "The current java on this system (0 - Java Not enabled) ..." So there is no chance to read you blog without Java because of redirection to Java update site. There should be Yes/No dialog to confirm redirection to Java updates. Without redirection the page should be readable and without running applets... Thank you. Martin JANDA

how does the JavaFX deployment script detect the installed java version? I don't think it uses the deployment toolkit... -I installed 6u12b3 and got the "please install 6u11 popups". -removed 6u12 and installed 6u11 -still get please install 6u11 popups... -if i cancel the installation twice, the applet loads deployment toolkit reports u11 so everything seems to be fine: http://people.fh-landshut.de/~mbien/cafebabe.html btw i get two dialogs + installation attempts per applet this means 4 on the aggregated page

found a bug report, same symptoms: http://javafx-jira.kenai.com/browse/RT-2870

Effects in JavaFX: Quality

Posted by campbell on January 7, 2009 at 9:29 AM PST
Spitzenqualität

In my last entry, I showed how easy it is to use the Effect API in JavaFX. This time around, I'll focus on visual quality.

JavaFX includes a scene graph API that is vector-based, meaning that elements in the scene will be rendered with high quality, taking into account the resolution of the output device (i.e., the screen) and any transforms that have been applied to the scene graph nodes. Even in a vector graphics library, applying filter effects necessarily requires painting the relevant scene graph nodes into an offscreen raster image so that the implementation can access and manipulate the raw pixels. Care must be taken by the implementation to create an offscreen representation of sufficient resolution so that it still looks great when it is ultimately rendered to the screen.

Take for instance the following example which shows a rounded Rectangle node with a DropShadow applied to it. The slider controls the scale of the shape node, in the range [0.5, 5.0]. Generally speaking, Effect variables operate in the local coordinate system of the Node to which it is applied. In this example we have a DropShadow.radius of 10, which means that at a 1:1 scale the rectangle will be surrounded by a shadow that extends 10 pixels in every direction. But what happens when we change the scale of the Rectangle node? (Try this yourself by dragging the slider back and forth. Or grab the source bundle here.)

Notice that the shadow scales in proportion to the shape itself, which is the desired behavior in nearly all cases. (Think about it: if this red shape represented a button, you'd want the drop shadow to be rendered with the same proportions regardless of whether it is on a relatively low-pixel-density laptop display or on a hi-dpi mobile device.) Also notice that the actual node "content" (the red rectangle) looks crisp under any transform. Pretty, innit?

There are a few different approaches the implementation could take to make this all work. One naïve approach would be to simply render the rectangle at a 1:1 scale into an offscreen image, create a shadow at the same 1:1 scale, merge the two images, and then render the resulting image with a scaling transform and, say, bilinear filtering (see Fig. 1 below). This would offer reasonable performance, but quality would suffer under non-identity transforms, since we're relying on image filtering to smooth the results of the scaling operation (and all this flies in the face of having a vector-based scene graph in the first place). Another dubious approach would be to render the rectangle in the transformed coordinate space, and then create the shadow with a scaled radius (and a potentially huge Gaussian kernel). This would offer great quality, but performance would take a nose dive due to the processing of the large shadow/blur operation.

raster.png
Fig. 1: Raster scaling (bad)
vector.png
Fig. 2: Hybrid vector scaling (good)

Fortunately, the effects framework in JavaFX currently takes a hybrid approach (see Fig. 2 above) that offers the best of both worlds for compound effects like DropShadow and others: high-quality rendering of the actual node content, a shadow that scales in proportion with the content under any transform, and good performance to boot. The implementation is smart enough to 1) render the original node content into an offscreen image with an identity transform for the purposes of creating the shadow, 2) use a filtered image scaling operation to bring it into the final transformed coordinate space, and then 3) render the original node content again over the shadow using the cumulative transform so that it looks just as lovely on the screen as if the effect hadn't been applied at all. Similar techniques are used for other effects, such as Glow and Lighting, to find a good balance between quality and performance, and to keep things looking great at any resolution.

Well, that was a mouthful. Since I'm trying (and struggling) to keep these blog entries short and sweet, let me just say that if you didn't follow all this, that's okay. The takeaway message is that we go through great lengths to make sure that your applications that use JavaFX, and effects in particular, look their best at any resolution.


In my ears: Public Image Ltd., Second Edition
In my eyes: Orhan Pamuk, My Name Is Red

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

does this mean that the shadow is rasterised small and scaled up and the rectangle is rendered as vector graphic after transformation (the "obvious way for rectangles ;)")? this would mean that we would get a performance decrease the other way around: fancy shadowed 1024x1024 rectangle scaled down to 48x48 would be rendered slower than a "native" unscaled but still fancy shadowed 48x48 quad is this correct? very good blog entry, there are not many sources which tell us useful things about jfx

Slider fails to work on Mac OS X 10.5.6 with Java 1.6.0_07.

only one applet starts if i visit the main blog page: http://weblogs.java.net/blog/campbell/ the second spins forever in the loading icon state. 6u11 winxp

skip to the JSL! :) No kidding, this stuff is interesting. bwt, I get the same on the second applet issue: 6u11b3, winxp

@mbien: Currently, yes, that is correct. However, a long time ago I had an idea that for the downscaling case, like the one you cite, we should be able to scale the kernel and work on the downscaled representation, sort of the opposite of the "dubious approach" I referred to above. I never got around to investigating it more, so I just filed a bug on this (http://javafx-jira.kenai.com/browse/RT-2908); thanks for bringing this up.

@mbien, @ilazarte: I'm seeing the same thing on Mac OS X with Safari too. Others have reported it to me internally as well. I've filed a bug here: http://javafx-jira.kenai.com/browse/RT-2907 Thanks for bringing these deployment issues up. I purposely decided to embed JavaFX applets in my last two entries exactly for this reason. Yes, it will be a distraction from the topic at hand at first (because of bugs like these), but it helps to shed light on the pain points in the JavaFX deployment story. If we can't successfully embed simple applets like these, then we can forget about success at a larger scale. Anyway, our deployment team is working to fix these things, so I hope soon we can get back to talking about effects without distraction :)

Reproduced on Vista Ultimate (SP1). Desktop deployment is never an easy task - but at least you have a rock solid language and library to start off with ;-) java version "1.6.0_11" Java(TM) SE Runtime Environment (build 1.6.0_11-b03) Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing) Microsoft Windows [Version 6.0.6001]

Thank you very much for your work Please check you page without Java plugin installed in your browser or without java installed at all. You get 2 message dialogs only with OK button: "Java is required to run JavaFX applications. You will now be redirected to a Java update site..." -- after redirection to java.com/... "The current java on this system (0 - Java Not enabled) ..." So there is no chance to read you blog without Java because of redirection to Java update site. There should be Yes/No dialog to confirm redirection to Java updates. Without redirection the page should be readable and without running applets... Thank you. Martin JANDA

how does the JavaFX deployment script detect the installed java version? I don't think it uses the deployment toolkit... -I installed 6u12b3 and got the "please install 6u11 popups". -removed 6u12 and installed 6u11 -still get please install 6u11 popups... -if i cancel the installation twice, the applet loads deployment toolkit reports u11 so everything seems to be fine: http://people.fh-landshut.de/~mbien/cafebabe.html btw i get two dialogs + installation attempts per applet this means 4 on the aggregated page

found a bug report, same symptoms: http://javafx-jira.kenai.com/browse/RT-2870

Effects in JavaFX: The Basics

Posted by campbell on January 5, 2009 at 12:12 AM PST
Still Alive

In early 2008, I wrote my only blog entry of the year, on the subject of the filter effects framework that serves as part of the foundation of JavaFX. It has been a fun project to work on, and I'm fairly proud of the result. There was so much more I wanted to write about on the subject, but I wanted to wait until we first had a stable API and delivered an actual product.

It was a long road to JavaFX 1.0, but now that it has shipped, I can finally talk more about using filter effects in JavaFX and what's going on behind the scenes. Since it's a big subject, I'll try to break things up into smaller, more focused blog entries instead of my usual monolithic tomes. (At minimum, it will provide the illusion that I'm more prolific in 2009 than I was in 2008.)

Like any good graphics API, the filter effects framework in JavaFX is easy to use, provides high-quality visual results, and offers top-notch performance. In this entry, I'll just focus on the ease-of-use angle.


Bunny Jump, Bunny Jump

The best place to start is to look at the javafx.scene.effect package API. All of the core filter effect classes extend the abstract javafx.scene.effect.Effect base class. Any Effect instance can be applied to a scene graph Node by setting the Node.effect variable. Each Effect subclass exposes a small number of variables that control the visual appearance of the Node. In addition, most Effect subclasses provide one or more input variables that can be used to "chain" effects (more on that in a future blog entry).

To take a specific example, the DropShadow class provides 5 variables, analogous to knobs on a control panel: color, offsetX, offsetY, radius, and spread. Each "knob" is generally documented with default, minimum, maximum, and identity values, which makes it easy to see the acceptable range of values. Here's a really simple example that shows how to apply a DropShadow effect to a rounded Rectangle and control its appearance through the magic of the bind operator.

And here's the relevant code (or download the complete sources here):

            Rectangle {
                effect: DropShadow {
                    radius: bind radius
                }
                x: 50 y: 30 width: 150 height: 100
                arcWidth: 40 arcHeight: 40
                fill: Color.RED
            }

That's it! Pretty easy, isn't it? You, the developer, only need to concern yourself with turning these simple knobs. The effects framework does all the heavy lifting for you, such as painting the Node into an offscreen image at the appropriate resolution, manipulating the pixels in one of the CPU and/or GPU accelerated backends, and automatically repainting the affected portion of the scene.

For more interactive examples of the built-in Effect subclasses, check out the EffectsPlayground applet featured in the JavaFX Samples Gallery. Stay tuned for entries on quality, performance, and more...


In my ears: No Age, Nouns
In my eyes: Woody Allen, Mere Anarchy

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

jdk7, windows, firefox, errors: netscape.javascript.JSException at netscape.javascript.JSObject.getWindow(Unknown Source) at com.sun.javafx.runtime.adapter.Applet.hideOverlay(Unknown Source) at com.sun.javafx.runtime.adapter.AppletStartupRoutine.run(Unknown Source) at com.sun.javafx.tk.swing.SwingToolkit$StartupRoutine.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) java.lang.ClassCastException: com.sun.scenario.effect.impl.j2d.J2DMergePeer cannot be cast to com.sun.scenario.effect.impl.j2d.rsl.RSLEffectPeer at com.sun.scenario.effect.impl.j2d.rsl.RSLRenderer.dispose(Unknown Source) at com.sun.scenario.effect.impl.j2d.rsl.RSLRenderer$1.onDeviceReset(Unknown Source) at sun.java2d.pipe.hw.AccelDeviceEventNotifier.notifyListeners(Unknown Source) at sun.java2d.pipe.hw.AccelDeviceEventNotifier.eventOccured(Unknown Source) at sun.awt.windows.WToolkit.eventLoop(Native Method) at sun.awt.windows.WToolkit.run(Unknown Source) at java.lang.Thread.run(Unknown Source) BTW, I think it's not very wise to install JavaFX runtime separately. Java applets and webstart applications should be able to include a JavaFX runtime jar from the JavaFX site and cache it without any user interference.

Interesting article, thanks.I don't see your example applet though, and I have the following error in my Java console: java.io.FileNotFoundException: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas...

Applet works fine. I think I need to look into JavaFX now that demos are starting to appear. It looks great.

Rats! Can't see the applet either: exception: null. java.io.FileNotFoundException: JNLP not available: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas... at sun.plugin2.applet.JNLP2Manager.loadJarFiles(Unknown Source) at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Exception: java.io.FileNotFoundException: JNLP not available: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas...

Had a horrible experience with the Applet too. First it demanded 6.0u10 wasn't up-tp-date enough to show JavaFX, then tried to download a web start ext of 6.0.u11 the cancelling of which isn't handled at all well. Almost couldn't see the post for all the popup dialogs & errors. Wouldn't 1.6+ work just as well in the JNLP? the UX ruins the JavaFX experience for me. May have to install noscript if this keeps up (would that work or do I need to greasemonkey java.net to knock out any applets?).

Oh the EffectBasics_browser.jnlp is missing for me too? (didnt see the error until switching to ie) what initiated the runtime download then? that looks like the usual JWS ext (which'd need the jnlp). Error dialogs dont look much like JWS though.. Hmm unless the u11 culprit was the decora, jmc extensions which get loaded first.. UX needs work on error trapping and how many times do I have to hit cancel to really mean it?

Sorry, forgot to re-upload the jnlp file (which is needed on 6u10 and above). Hopefully things are working again...

Works for me in Firefox with 6u10 now thanks, ie7 is still reporting no Java installed and trying to download 6u11 constantly. Well it did that until I cancelled the download now the ie7 browser crashes every time I try to visit this page or any of the JavaFX demos. No Java installed error prompts seem to be coming from the dtfx.js script. Not sure why a reboot would be necessary as I've not reinstalled anything recently and Firefox seems happy now (after restarting that browser - was doing the no java, install u11 trick before your fix). Nuking the ie7 cache and restarting ie7 didnt help.

Ps something really odd happens every time I've commented (from Firefox) after hitting POST the page gets replaced by just the applet..?

Very small and effective example. Hope to see more filter supports soon. Applet is running in my case.

Looks good on my mac osx 10.5.6 Nice job!

Having some trouble on my mac. Any thoughts on how to fix it? JNLPAppletLauncher: static initializer java.io.IOException: Cannot access /tmp/jnlp-applet/jln39035 at org.jdesktop.applet.util.JNLPAppletLauncher.initTmpRoot(Unknown Source) at org.jdesktop.applet.util.JNLPAppletLauncher.(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at java.lang.Class.newInstance0(Class.java:350) at java.lang.Class.newInstance(Class.java:303) at sun.applet.AppletPanel.createApplet(AppletPanel.java:723) at sun.plugin.AppletViewer.createApplet(AppletViewer.java:1864) at sun.applet.AppletPanel.runLoader(AppletPanel.java:652) at sun.applet.AppletPanel.run(AppletPanel.java:326) at java.lang.Thread.run(Thread.java:613)

Surprised to see how well JavaFX works in Ubuntu and that JavaFX can run under Sun JRE 6 (update 7). When the applet started up the JavaFX runtime was installed very easily with no fuss and Firefox did not freeze at all!

Effects in JavaFX: The Basics

Posted by campbell on January 5, 2009 at 12:12 AM PST
Still Alive

In early 2008, I wrote my only blog entry of the year, on the subject of the filter effects framework that serves as part of the foundation of JavaFX. It has been a fun project to work on, and I'm fairly proud of the result. There was so much more I wanted to write about on the subject, but I wanted to wait until we first had a stable API and delivered an actual product.

It was a long road to JavaFX 1.0, but now that it has shipped, I can finally talk more about using filter effects in JavaFX and what's going on behind the scenes. Since it's a big subject, I'll try to break things up into smaller, more focused blog entries instead of my usual monolithic tomes. (At minimum, it will provide the illusion that I'm more prolific in 2009 than I was in 2008.)

Like any good graphics API, the filter effects framework in JavaFX is easy to use, provides high-quality visual results, and offers top-notch performance. In this entry, I'll just focus on the ease-of-use angle.


Bunny Jump, Bunny Jump

The best place to start is to look at the javafx.scene.effect package API. All of the core filter effect classes extend the abstract javafx.scene.effect.Effect base class. Any Effect instance can be applied to a scene graph Node by setting the Node.effect variable. Each Effect subclass exposes a small number of variables that control the visual appearance of the Node. In addition, most Effect subclasses provide one or more input variables that can be used to "chain" effects (more on that in a future blog entry).

To take a specific example, the DropShadow class provides 5 variables, analogous to knobs on a control panel: color, offsetX, offsetY, radius, and spread. Each "knob" is generally documented with default, minimum, maximum, and identity values, which makes it easy to see the acceptable range of values. Here's a really simple example that shows how to apply a DropShadow effect to a rounded Rectangle and control its appearance through the magic of the bind operator.

And here's the relevant code (or download the complete sources here):

            Rectangle {
                effect: DropShadow {
                    radius: bind radius
                }
                x: 50 y: 30 width: 150 height: 100
                arcWidth: 40 arcHeight: 40
                fill: Color.RED
            }

That's it! Pretty easy, isn't it? You, the developer, only need to concern yourself with turning these simple knobs. The effects framework does all the heavy lifting for you, such as painting the Node into an offscreen image at the appropriate resolution, manipulating the pixels in one of the CPU and/or GPU accelerated backends, and automatically repainting the affected portion of the scene.

For more interactive examples of the built-in Effect subclasses, check out the EffectsPlayground applet featured in the JavaFX Samples Gallery. Stay tuned for entries on quality, performance, and more...


In my ears: No Age, Nouns
In my eyes: Woody Allen, Mere Anarchy

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

jdk7, windows, firefox, errors: netscape.javascript.JSException at netscape.javascript.JSObject.getWindow(Unknown Source) at com.sun.javafx.runtime.adapter.Applet.hideOverlay(Unknown Source) at com.sun.javafx.runtime.adapter.AppletStartupRoutine.run(Unknown Source) at com.sun.javafx.tk.swing.SwingToolkit$StartupRoutine.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) java.lang.ClassCastException: com.sun.scenario.effect.impl.j2d.J2DMergePeer cannot be cast to com.sun.scenario.effect.impl.j2d.rsl.RSLEffectPeer at com.sun.scenario.effect.impl.j2d.rsl.RSLRenderer.dispose(Unknown Source) at com.sun.scenario.effect.impl.j2d.rsl.RSLRenderer$1.onDeviceReset(Unknown Source) at sun.java2d.pipe.hw.AccelDeviceEventNotifier.notifyListeners(Unknown Source) at sun.java2d.pipe.hw.AccelDeviceEventNotifier.eventOccured(Unknown Source) at sun.awt.windows.WToolkit.eventLoop(Native Method) at sun.awt.windows.WToolkit.run(Unknown Source) at java.lang.Thread.run(Unknown Source) BTW, I think it's not very wise to install JavaFX runtime separately. Java applets and webstart applications should be able to include a JavaFX runtime jar from the JavaFX site and cache it without any user interference.

Interesting article, thanks.I don't see your example applet though, and I have the following error in my Java console: java.io.FileNotFoundException: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas...

Applet works fine. I think I need to look into JavaFX now that demos are starting to appear. It looks great.

Rats! Can't see the applet either: exception: null. java.io.FileNotFoundException: JNLP not available: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas... at sun.plugin2.applet.JNLP2Manager.loadJarFiles(Unknown Source) at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Exception: java.io.FileNotFoundException: JNLP not available: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas...

Had a horrible experience with the Applet too. First it demanded 6.0u10 wasn't up-tp-date enough to show JavaFX, then tried to download a web start ext of 6.0.u11 the cancelling of which isn't handled at all well. Almost couldn't see the post for all the popup dialogs & errors. Wouldn't 1.6+ work just as well in the JNLP? the UX ruins the JavaFX experience for me. May have to install noscript if this keeps up (would that work or do I need to greasemonkey java.net to knock out any applets?).

Oh the EffectBasics_browser.jnlp is missing for me too? (didnt see the error until switching to ie) what initiated the runtime download then? that looks like the usual JWS ext (which'd need the jnlp). Error dialogs dont look much like JWS though.. Hmm unless the u11 culprit was the decora, jmc extensions which get loaded first.. UX needs work on error trapping and how many times do I have to hit cancel to really mean it?

Sorry, forgot to re-upload the jnlp file (which is needed on 6u10 and above). Hopefully things are working again...

Works for me in Firefox with 6u10 now thanks, ie7 is still reporting no Java installed and trying to download 6u11 constantly. Well it did that until I cancelled the download now the ie7 browser crashes every time I try to visit this page or any of the JavaFX demos. No Java installed error prompts seem to be coming from the dtfx.js script. Not sure why a reboot would be necessary as I've not reinstalled anything recently and Firefox seems happy now (after restarting that browser - was doing the no java, install u11 trick before your fix). Nuking the ie7 cache and restarting ie7 didnt help.

Ps something really odd happens every time I've commented (from Firefox) after hitting POST the page gets replaced by just the applet..?

Very small and effective example. Hope to see more filter supports soon. Applet is running in my case.

Looks good on my mac osx 10.5.6 Nice job!

Having some trouble on my mac. Any thoughts on how to fix it? JNLPAppletLauncher: static initializer java.io.IOException: Cannot access /tmp/jnlp-applet/jln39035 at org.jdesktop.applet.util.JNLPAppletLauncher.initTmpRoot(Unknown Source) at org.jdesktop.applet.util.JNLPAppletLauncher.(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at java.lang.Class.newInstance0(Class.java:350) at java.lang.Class.newInstance(Class.java:303) at sun.applet.AppletPanel.createApplet(AppletPanel.java:723) at sun.plugin.AppletViewer.createApplet(AppletViewer.java:1864) at sun.applet.AppletPanel.runLoader(AppletPanel.java:652) at sun.applet.AppletPanel.run(AppletPanel.java:326) at java.lang.Thread.run(Thread.java:613)

Surprised to see how well JavaFX works in Ubuntu and that JavaFX can run under Sun JRE 6 (update 7). When the applet started up the JavaFX runtime was installed very easily with no fuss and Firefox did not freeze at all!

Effectuation: The Intro

Posted by campbell on February 1, 2008 at 2:32 AM PST

For the past few months, I've been involved with various aspects of Project Scene Graph and the JavaFX Script runtime libraries. Hans has already introduced the core elements of the scenegraph package, and Chet has donned his Groucho mask to explain the animation package in great detail (three chairs for that!).

Today I'm finally going to talk about the third major component of the overall Scene Graph project, and that is the Effects Framework. If you've been wondering why I've been quiet lately, this is the reason.

Our team has already had plenty of experience in delivering GPU-accelerated imaging operations. Now we've taken it to the next level, by offering a long list of effects commonly used by designers, packaging them up into an easy-to-use API, and providing a sophisticated implementation that can take advantage of GPU acceleration (and later, SIMD instructions on the CPU) for blazingly fast performance.

All of this integrates seamlessly with the scenegraph and animation packages, and soon will be exposed just as pleasantly through the JavaFX Script runtime APIs. You can even take advantage of the Effects Framework in existing Swing and Java 2D applications.

Anyway, enough yapping; let's move on to the introductory demo... This application demonstrates just a few of the effects available in the new API. I'll let it speak for itself. (Requires Java SE 6 or above.)


intro.png

      webstart.small2.gif    With default options -- will take advantage of the Direct3D-based backend (if possible*) on Windows...

      webstart.small2.gif    With OpenGL backend enabled -- for Windows, Linux, and Solaris (if possible*); Mac OS X coming soon...

      webstart.small2.gif    With all GPU-acceleration disabled -- try this if you have problems with one of the above.

(*) GPU acceleration requires the latest build of JDK 6uN, a compatible graphics card, and up-to-date graphics drivers. If GPU acceleration cannot be enabled for any reason, the framework will automatically fall back on the software-based implementation. Yes, the software-based backend is much slower than it should be; we're working on that.


These projects are still in the early stages, but over the next few weeks, I'll have much more to say about (and more demos to share from) the Effects Framework and the Scene Graph project at large, so stay tuned. In the meantime, take a gander at the JavaDocs and let us know what you think. Hans should have news shortly of an 0.5 release that includes all of this and more.



In my ears: Enon, "High Society"
In my eyes: Found Magazine #3

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

Would be nice if you say somewhere if you fell back on the software-based implementation. My cpu is 100% but I don't know if the hardware- or software-based implementation is on.

@keeskuip: When the blend mode scene starts up, look in the lower left corner of the window. It should say "Using {CPU/OpenGL/Direct3D} backend"; if it's pegging your CPU, I'm guessing it's not able to use one of the GPU backends.

benloud, could you please set env. variable J2D_TRACE_LEVEL=4 and run any swing app from the console and post the output (or send to me: tdv at sun dot com)?

On my system with Nvidia 7800 it runs fine with the d3d pipeline. CPU
utilization is <5% during the demo..

Thanks,
Dmitri
Java2D Team

Duh. ... utilization is less than 5% during the demo. Dmitri

Ah, benloud, do you have a multiscreen system? If so, currently d3d accelelrated effects will only work on the primary screen. To be fixed soon.

Dmitri

@benloud As far as i can tell, this seems self-contained and does not depend on scenegraph and animation at all. I guess that's chris meant by seamlessly.

I had to fiddle a bit to integrate it with a scenegraph scene, but it really is simple, create an SGEffect, and setEffect one of the effects in the library, setChild one SGNode.

(Severely blurring some swing components in real time allowed me to experience how one of my friends 'sees' without his glasses, thanks for that Chris :)

And when were you planning on telling us about JSL?!? That's the most exciting part of this project! JSL appears to let us write our own effects and have them run on the graphics card. Can you give us any more information on it?

All demos fails with: com.sun.deploy.net.FailedDownloadException: Unable to load resource: http://download.java.net/javadesktop/scenario/effects/demos/Intro.jar

martin_dk: download.java.net is apparently down right now.

This is why web start is really cool. I got the demo while it was up and even though the link seems to be broken I can still show it to people. I know I would have had to jump through some hoops to load an applet once the original site went down.

w00t ! That's very, very cool. Do you have any plan to expose the SiMD stuff to Java developpers too ? A SIMD framework with aligned data structure, the common operators, ect, would be very cool to have in Java.

oh god
* now i need a fresh set of underwear *

Unfortunately with 6uNb11 with D3D, I see no images at all. Just the text and big solid color squares. Normal apps seem to work just fine. I can see it all with the non-GPU version though, and the blend modes work fast enough to play smoothly. We can always count on you for the coolest demos chris. How did you get 3D text and lighting effects without D3D or OGL! I'm interested in how I might use these effects with Java2D though, without the scene graph. I hope to see Composite/BufferedImageOp classes for these.

They're still having issues with download.java.net's content, unfortunately =(

someone should please put the data to an other server and update the links of the project page. The effects framework is currently on the opengl.org frontpage. the first impression works just once ;)

It doesn't use my GPU here on Linux Ubuntu 8.04.1, although all the proprietary drivers are installed and anything else in my system is able to use the GPU. I hope Sun will not keep Linux out with a CPU-only solution. I got GeForce 7600GT 256MB. Java update 10 build 27.

Not strictly related to this post, but javagaming refuses to let me sign in up, so I thought I'd try here. I've been trying to get my Java Playstation emulator to play nicely with Vista. Basically I need to do a copy-up from a portion of emulated VRAM (basically an int[] I keep in a sensible Java2d format (RGB)) to the display. This needs to be a stretched blit based on the h/v scan rate of the TV mode. In the past I had used an int[] backed BufferedImage in main RAM (since I need to write to it a lot), and then the copy up would do an unstretched blit of the displayed portion of the VRAM to a VolatileImage, and a DirectX accelerated stretch blit to the display from the VolatileImage (this seemed to be the fastest way,and gives you the nice anti-aliasing you need given PSX's strange display modes). Vista obviously screwed stuff up with the disabling of the DirectX acceleration. I had been looking at using JOGL/Direct3d to do the streched blit, but it seems like stuff might be fixed again in this new release of Java 6, plus also I can't seem to tell what of that stuff is broken by Aero anyways I ran the attached demo and saw Direct3D backend usage, however my emu doesn't appear to be using DirectX (at least the stretch blit is not anti-aliased and doesn't seem particularly fast). I've been scouring the web, but can't seem to find the exact latest status on where Vista support lies. I'd happily plug in a JOGL based blit if that should be fast, but first I'd like to check I have the right system properties enabled, and/or debug what Java2d is doing. Obviously in the long run, I should add a JOGL based GPU anyway (rather than Java software rendered, but that surprisingly isn't as much of a bottleneck as the screen blit)

oops; ok i did find some documentation on debug options; this is what I'm seeing with the new JDK 6 sun.java2d.d3d.D3DSwToSurfaceBlit::Blit(IntRgb, AnyAlpha, "D3D Surface") sun.java2d.d3d.D3DRTTSurfaceToSurfaceScale::ScaledBlit("D3D Surface (render-to-texture)", AnyAlpha, "D3D Surface") vs previous versions on vista sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntRgb) sun.java2d.loops.ScaledBlit::ScaledBlit(IntRgb, SrcNoEa, IntRgb) So at least I seem to be using Direct3D; is there a way to turn on anti-aliasing for this blit, and/or how do I turn on JOGL instead of D3D

ok, it turns out I'm an idiot. The old direct X stuff I was using (sun.java2d.ddscale=true) did anti-aliasing without asking, setting the hint on the graphics2d helped a lot with the new code ;-) So one question; assuming I was to want to do some automated timings to pick between a few different copy up methodologies, can I rely on stuff being synchronous, or is there something I can do to force a flush?

OMG! it's animation! Again (and again and ... and again ...). The effects are nice, but the CPU is running near-flat-out (on my adequate but not a gaming machine laptop), and the result is occasionally jittery. As "Q" said to 007: "never let them see you bleed". Applications with special effects that shudder badly when they cannot get a firehose worth of CPU are going to look lousy. You never want your applications to look lousy. Every few years new developers fall in love with the latest special effect that looks "kewl" in demos but prove tedious in repeated use. Seems this cycle has repeated every few years since (at least) the late 1980's. I am all for adding interesting and useful visual effects to GUI applications, but the end effect has to be seamless, even when the box we are running on is not the fastest, and even when the box is busy doing other things. Otherwise the user experience is ugly. It is a natural thing for developers to consider their application the most important thing running on the box, but users do not see things the same way. You have to be a good citizen in the little community of code running on the end user's box, and CPU-sucking special effects are ... at least dubious.

@pbannister: These effects use close to 0% CPU when the GPU-accelerated backends are in use, which will be the case for a majority of end users' machines by the time JDK 6u10 ships in a few months. As for the remaining machines where the GPU is not a viable option... Since this blog was posted, performance of the CPU-based backend has improved considerably thanks to an optimized native backend, which is significantly faster than the unoptimized pure Java backend (50% faster, and that's just the beginning).

Unfortunately all of OGL-pipeline related demos result in black artefacts (Geforce8800GTS, Windows XP, Update N b12) . From time to time I can see new rendered regions with text. I have the same problems with all the jogl-demos which utilize the OGL-pipeline. At first it seemed to be a driver bug. My system crashed when I tried the pipeline using the first drivers I got for my card. The crashes gone away but the artefacts came. Maybe it's something with cleaning up the FBO that's going wrong on the newer Geforce series.

hi Chris, sorry this is off topic a bit, but I'm wondering whether heavyweight and lightweight components are closer to playing nice together. E.g. will a lightweight component ever be able to render over a heavyweight component? I remember hearing this was on the horizon a year ago ... thanks!

@xcolwell: The AWT forum could provide more details, but heavyweight/lightweight mixing should be improved in an upcoming JDK 6 update release. This means better support for heavyweight components embedded in lightweight, but not necessarily the other way around (heavyweight rendering typically blows through to the screen, so we can't render on top).

Effectuation: The Intro

Posted by campbell on February 1, 2008 at 2:32 AM PST

For the past few months, I've been involved with various aspects of Project Scene Graph and the JavaFX Script runtime libraries. Hans has already introduced the core elements of the scenegraph package, and Chet has donned his Groucho mask to explain the animation package in great detail (three chairs for that!).

Today I'm finally going to talk about the third major component of the overall Scene Graph project, and that is the Effects Framework. If you've been wondering why I've been quiet lately, this is the reason.

Our team has already had plenty of experience in delivering GPU-accelerated imaging operations. Now we've taken it to the next level, by offering a long list of effects commonly used by designers, packaging them up into an easy-to-use API, and providing a sophisticated implementation that can take advantage of GPU acceleration (and later, SIMD instructions on the CPU) for blazingly fast performance.

All of this integrates seamlessly with the scenegraph and animation packages, and soon will be exposed just as pleasantly through the JavaFX Script runtime APIs. You can even take advantage of the Effects Framework in existing Swing and Java 2D applications.

Anyway, enough yapping; let's move on to the introductory demo... This application demonstrates just a few of the effects available in the new API. I'll let it speak for itself. (Requires Java SE 6 or above.)


intro.png

      webstart.small2.gif    With default options -- will take advantage of the Direct3D-based backend (if possible*) on Windows...

      webstart.small2.gif    With OpenGL backend enabled -- for Windows, Linux, and Solaris (if possible*); Mac OS X coming soon...

      webstart.small2.gif    With all GPU-acceleration disabled -- try this if you have problems with one of the above.

(*) GPU acceleration requires the latest build of JDK 6uN, a compatible graphics card, and up-to-date graphics drivers. If GPU acceleration cannot be enabled for any reason, the framework will automatically fall back on the software-based implementation. Yes, the software-based backend is much slower than it should be; we're working on that.


These projects are still in the early stages, but over the next few weeks, I'll have much more to say about (and more demos to share from) the Effects Framework and the Scene Graph project at large, so stay tuned. In the meantime, take a gander at the JavaDocs and let us know what you think. Hans should have news shortly of an 0.5 release that includes all of this and more.



In my ears: Enon, "High Society"
In my eyes: Found Magazine #3

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)

Would be nice if you say somewhere if you fell back on the software-based implementation. My cpu is 100% but I don't know if the hardware- or software-based implementation is on.

@keeskuip: When the blend mode scene starts up, look in the lower left corner of the window. It should say "Using {CPU/OpenGL/Direct3D} backend"; if it's pegging your CPU, I'm guessing it's not able to use one of the GPU backends.

benloud, could you please set env. variable J2D_TRACE_LEVEL=4 and run any swing app from the console and post the output (or send to me: tdv at sun dot com)?

On my system with Nvidia 7800 it runs fine with the d3d pipeline. CPU
utilization is <5% during the demo..

Thanks,
Dmitri
Java2D Team

Duh. ... utilization is less than 5% during the demo. Dmitri

Ah, benloud, do you have a multiscreen system? If so, currently d3d accelelrated effects will only work on the primary screen. To be fixed soon.

Dmitri

@benloud As far as i can tell, this seems self-contained and does not depend on scenegraph and animation at all. I guess that's chris meant by seamlessly.

I had to fiddle a bit to integrate it with a scenegraph scene, but it really is simple, create an SGEffect, and setEffect one of the effects in the library, setChild one SGNode.

(Severely blurring some swing components in real time allowed me to experience how one of my friends 'sees' without his glasses, thanks for that Chris :)

And when were you planning on telling us about JSL?!? That's the most exciting part of this project! JSL appears to let us write our own effects and have them run on the graphics card. Can you give us any more information on it?

All demos fails with: com.sun.deploy.net.FailedDownloadException: Unable to load resource: http://download.java.net/javadesktop/scenario/effects/demos/Intro.jar

martin_dk: download.java.net is apparently down right now.

This is why web start is really cool. I got the demo while it was up and even though the link seems to be broken I can still show it to people. I know I would have had to jump through some hoops to load an applet once the original site went down.

w00t ! That's very, very cool. Do you have any plan to expose the SiMD stuff to Java developpers too ? A SIMD framework with aligned data structure, the common operators, ect, would be very cool to have in Java.

oh god
* now i need a fresh set of underwear *

Unfortunately with 6uNb11 with D3D, I see no images at all. Just the text and big solid color squares. Normal apps seem to work just fine. I can see it all with the non-GPU version though, and the blend modes work fast enough to play smoothly. We can always count on you for the coolest demos chris. How did you get 3D text and lighting effects without D3D or OGL! I'm interested in how I might use these effects with Java2D though, without the scene graph. I hope to see Composite/BufferedImageOp classes for these.

They're still having issues with download.java.net's content, unfortunately =(

someone should please put the data to an other server and update the links of the project page. The effects framework is currently on the opengl.org frontpage. the first impression works just once ;)

It doesn't use my GPU here on Linux Ubuntu 8.04.1, although all the proprietary drivers are installed and anything else in my system is able to use the GPU. I hope Sun will not keep Linux out with a CPU-only solution. I got GeForce 7600GT 256MB. Java update 10 build 27.

Not strictly related to this post, but javagaming refuses to let me sign in up, so I thought I'd try here. I've been trying to get my Java Playstation emulator to play nicely with Vista. Basically I need to do a copy-up from a portion of emulated VRAM (basically an int[] I keep in a sensible Java2d format (RGB)) to the display. This needs to be a stretched blit based on the h/v scan rate of the TV mode. In the past I had used an int[] backed BufferedImage in main RAM (since I need to write to it a lot), and then the copy up would do an unstretched blit of the displayed portion of the VRAM to a VolatileImage, and a DirectX accelerated stretch blit to the display from the VolatileImage (this seemed to be the fastest way,and gives you the nice anti-aliasing you need given PSX's strange display modes). Vista obviously screwed stuff up with the disabling of the DirectX acceleration. I had been looking at using JOGL/Direct3d to do the streched blit, but it seems like stuff might be fixed again in this new release of Java 6, plus also I can't seem to tell what of that stuff is broken by Aero anyways I ran the attached demo and saw Direct3D backend usage, however my emu doesn't appear to be using DirectX (at least the stretch blit is not anti-aliased and doesn't seem particularly fast). I've been scouring the web, but can't seem to find the exact latest status on where Vista support lies. I'd happily plug in a JOGL based blit if that should be fast, but first I'd like to check I have the right system properties enabled, and/or debug what Java2d is doing. Obviously in the long run, I should add a JOGL based GPU anyway (rather than Java software rendered, but that surprisingly isn't as much of a bottleneck as the screen blit)

oops; ok i did find some documentation on debug options; this is what I'm seeing with the new JDK 6 sun.java2d.d3d.D3DSwToSurfaceBlit::Blit(IntRgb, AnyAlpha, "D3D Surface") sun.java2d.d3d.D3DRTTSurfaceToSurfaceScale::ScaledBlit("D3D Surface (render-to-texture)", AnyAlpha, "D3D Surface") vs previous versions on vista sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntRgb) sun.java2d.loops.ScaledBlit::ScaledBlit(IntRgb, SrcNoEa, IntRgb) So at least I seem to be using Direct3D; is there a way to turn on anti-aliasing for this blit, and/or how do I turn on JOGL instead of D3D

ok, it turns out I'm an idiot. The old direct X stuff I was using (sun.java2d.ddscale=true) did anti-aliasing without asking, setting the hint on the graphics2d helped a lot with the new code ;-) So one question; assuming I was to want to do some automated timings to pick between a few different copy up methodologies, can I rely on stuff being synchronous, or is there something I can do to force a flush?

OMG! it's animation! Again (and again and ... and again ...). The effects are nice, but the CPU is running near-flat-out (on my adequate but not a gaming machine laptop), and the result is occasionally jittery. As "Q" said to 007: "never let them see you bleed". Applications with special effects that shudder badly when they cannot get a firehose worth of CPU are going to look lousy. You never want your applications to look lousy. Every few years new developers fall in love with the latest special effect that looks "kewl" in demos but prove tedious in repeated use. Seems this cycle has repeated every few years since (at least) the late 1980's. I am all for adding interesting and useful visual effects to GUI applications, but the end effect has to be seamless, even when the box we are running on is not the fastest, and even when the box is busy doing other things. Otherwise the user experience is ugly. It is a natural thing for developers to consider their application the most important thing running on the box, but users do not see things the same way. You have to be a good citizen in the little community of code running on the end user's box, and CPU-sucking special effects are ... at least dubious.

@pbannister: These effects use close to 0% CPU when the GPU-accelerated backends are in use, which will be the case for a majority of end users' machines by the time JDK 6u10 ships in a few months. As for the remaining machines where the GPU is not a viable option... Since this blog was posted, performance of the CPU-based backend has improved considerably thanks to an optimized native backend, which is significantly faster than the unoptimized pure Java backend (50% faster, and that's just the beginning).

Unfortunately all of OGL-pipeline related demos result in black artefacts (Geforce8800GTS, Windows XP, Update N b12) . From time to time I can see new rendered regions with text. I have the same problems with all the jogl-demos which utilize the OGL-pipeline. At first it seemed to be a driver bug. My system crashed when I tried the pipeline using the first drivers I got for my card. The crashes gone away but the artefacts came. Maybe it's something with cleaning up the FBO that's going wrong on the newer Geforce series.

hi Chris, sorry this is off topic a bit, but I'm wondering whether heavyweight and lightweight components are closer to playing nice together. E.g. will a lightweight component ever be able to render over a heavyweight component? I remember hearing this was on the horizon a year ago ... thanks!

@xcolwell: The AWT forum could provide more details, but heavyweight/lightweight mixing should be improved in an upcoming JDK 6 update release. This means better support for heavyweight components embedded in lightweight, but not necessarily the other way around (heavyweight rendering typically blows through to the screen, so we can't render on top).

Faster Java 2D Via Shaders

Posted by campbell on April 7, 2007 at 7:58 PM PDT

We've been doing a lot of work over the past couple years to accelerate many complex Java 2D operations on the GPU via OpenGL fragment shaders. (Fragment shaders are little programs that operate on each pixel being rendered on the screen; they're infinitely more flexible than the fixed functionality that's historically been available in OpenGL.) The sky's the limit when it comes to the kind of effects one can achieve by writing shader programs.

The first GPUs with fully programmable shader support were made available from Nvidia and ATI in 2002. It took a couple years for the new hardware to penetrate into the consumer market, but now shader-capable GPUs are extremely prevalent (thanks in part to the hefty graphical requirements of Mac OS X and Windows Vista), so much so that we can reliably take advantage of shaders to accelerate complex Java 2D operations. Even those first-generation boards are capable of providing huge performance gains, and each new generation of hardware seems to give an order of magnitude improvement over the last. This should be quite evident from the charts that follow. While CPU speeds seem to be nearing an asymptote, GPU performance continues to rocket, and now Java 2D is able to benefit from that power. Not only does this mean improved performance for your Swing or Java 2D application, but also reduced CPU consumption, thus freeing up your CPU to crunch on application logic rather than getting bogged down with rendering tasks.

[This is one of those blog entries that could be novel length, but no one would actually read the words, because there are too many pretty bar charts to distract the reader. Blah blah blah, words words words. See? No one's reading. So let's skip the prose and get on with it... Oh, but first, I have to tell you how to read these charts. I generated these numbers on a couple different machines, using J2DBench on Windows XP with the latest graphics drivers (ATI Catalyst 7.3 and Nvidia 93.71). Since the machines vary slightly in processor performance and bus speed (the GeForce 7800 is a PCI-E board, the rest are AGP), I decided to use our software pipeline as a baseline, and then compare the OGL pipeline numbers to that baseline. For example, if you see a result that lines up with the number 2000, it means that test is 2000% of baseline, or in other words, it is about 20 times faster on the GPU than on the CPU. Your mileage may vary, but the big takeaway is that most operations are many times faster when executed on the GPU...]


Text Rendering (Bug 6274813: Available in JDK 6)

LCD-Optimized Text
I already discussed this a bit in a blog entry from about a year ago. Since then, we've enabled this by default in JDK 7 (and soon in a JDK 6 update) when the OGL pipeline is enabled. It's cool to see how software performance improves little over time, but each new generation of GPUs brings big performance improvements.

lcdtext.png


BufferedImageOps (Bug 6514990: Available in JDK 7 b08)

ConvolveOp
ConvolveOp is commonly used for modern UI effects such as blurs and drop shadows. Due to limitations in first-generation shader-level hardware, we are currently only accelerating ConvolveOp for 3x3 and 5x5 sized Kernels. These are fairly common kernel sizes, but most drop shadow and glow effects require larger kernels, so we are working to loosen these restrictions and accelerate a wider range of kernel sizes.

convolve.png

LookupOp
LookupOp is often used to perform simple brightness and contrast adjustments on images. To simplify our code, we are currently only accelerating LookupOp for ByteLookupTables and ShortLookupTables with a maximum length of 256 elements, and for 1-, 3-, and 4-band sRGB images only.

lookup.png

RescaleOp
RescaleOp is basically a degenerate case of LookupOp that can be accelerated very efficiently in shaders; after all, it's just a multiply and an add. We are currently accelerating RescaleOp for 1-, 3-, and 4-band sRGB images only.

rescale.png


Multi-stop Gradient Paints (Bug 6521533: Available in JDK 7 b10)

LinearGradientPaint
For 2-stop linear gradients (NO_CYCLE or REFLECT), we can delegate to our existing GradientPaint codepath, which is already ridiculously fast via OpenGL's fixed functionality. For all other linear gradients (for all CycleMethods and ColorSpaceTypes, up to a maximum of 12 color stops), we can accelerate the operation using shaders, for both antialiased and non-antialiased rendering.

linear.png

RadialGradientPaint
The same restrictions for linear gradients also apply to radial gradients (maximum of 12 color stops, etc). For gradients with more than 12 stops, we simply fall back on our existing software routines.

radial.png


Extended Composite Modes (Bugs 6531647, 5094232: On the way)

Antialiased Painting (with Non-SrcOver AlphaComposite)
Historically the OGL pipeline has been able to accelerate the compositing step of an antialiased painting operation only when AlphaComposite.SrcOver (or AlphaComposite.Src, if the paint is opaque) due to the math involved. (This is described in the quasi-official guide to the OpenGL-based Java 2D pipeline, but that document could use a refresh for JDK 6 and beyond.) But now with shaders we're able to accelerate antialiased rendering for any arbitrary AlphaComposite mode.

Coming Soon: PhotoComposite
It's not officially approved (or integrated) yet, but I've been working on adding more blending modes to Java 2D, in addition to those already provided by AlphaComposite. Many of these modes come from traditional photography techniques, thus the name "PhotoComposite". Some modes are simple (Add, Multiply) and can be accelerated easily using OpenGL's built-in blending rules, others are more involved (ColorBurn, SoftLight) and benefit greatly from the use of shaders for efficient rendering.


What's Next?

There are plenty more optimizations that can be made to common Java 2D operations by leveraging shader technology; we'll keep working on this. Also, there have been some discussion on the interest list recently about the use of shaders in Java 2D. Some folks would like to be able to write arbitrary shaders and have them work on Java 2D content. I think it would be hard to come up with a general solution (in the public API) to make this work everywhere, and would shift an unreasonable burden to Java 2D (which is designed with WORA in mind).

However, I do recognize that it would be great if it were easy for developers to make use of shaders in their applications (as Romain has demonstrated) without getting bogged down in the OpenGL/GLSL learning curve. To that extent, I've been working on a few utility classes for JOGL in the vein of TextureIO and related classes. This is another way to make the transition easier for existing Swing developers to leverage JOGL in their applications. More on that in a future blog entry.

Finally, it's worth mentioning that all the shader-based optimizations I've described above are currently only available for the OpenGL-based Java 2D pipeline, but that will soon change. For JDK 7 (maybe sooner?), we have a newly redesigned Direct3D-9-based pipeline in the works that will share much of the architecture (and code) of the OpenGL-based pipeline. We fully expect that all of these shader-based optimizations will be available for most Windows users in the near future. Stay tuned.



In my ears: Panda Bear, "Person Pitch"
In my eyes: JPG, Issue 9

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)