JavaFX and Hardware Acceleration (Take 3)
Firstly, forget everything I said in part 1 and part 2 of this series.
I’m serious.
Mind clear?
Right, lets begin again.
Judging by what I’ve learned over the last two days I should really be calling this blog enter ‘getAccelType() and its idiosyncracies‘, not ‘JavaFX and Hardware acceleration‘.
The first thing you need to know is that JavaFX will use your machines GPU capabilities if they exist.
The second thing you need to know is that getAccelType() may not report the correct answers unless you take some explicit steps to ensure that occurs.
Here is a summary
What does getAccelType() do?
From the javafxoc: Returns a
Stringrepresenting the type of hardware acceleration, if any, that is used when applying thisEffecton the givenGraphicsConfiguration.
It would appear to return 1 of 5 of values for each effect
- OpenGL (Mac)
Seen on MacBook Pro’s with the appropriate video cards - Direct3D (Windows)
Windows only, widely seen on Windows platform - CPU/SIMD (Any platform)
Believed that it uses the SSE (or like) extensions on your CPU, this is the method seen on MacBook’s with Intel video cards - CPU/Java (Any platform)
Meaning of this one isn’t immediately apparent, but its been observed on Linux platforms - Intrinsic (Any platform)
“Intrinsic just means the “platform” handles the filtering operation. For instance Reflection is implemented using Java2D operations, no shaders, no special software loops, so it’s marked “intrinsic” ”
When should you use it?
Never. Probably. Chris Campbell from Sun remarked “people aren’t supposed to know about getAccelType()”.
I suppose it could be useful if you specifically wanted to test for Direct3D or OpenGL prior to adding lots of effects, but I would strongly suggest you do some benchmarking first to see if its going to make a difference… (See below)
How should I use it?
Well, you probably shouldn’t, but now that you’ve decided you need to use it, here is the caveat you need to know.
You need to make any decision about hardware capabilities you are running on at the appropriate point in time in your application, otherwise you are going to get the wrong answer (it will erroneously return CPU/SIMD not the Direct3D you should get under Windows). Note this erroneous answer has no relationship to what JavaFX will actually use, for instance, you may get the return value of ‘CPU/SIMD’ and then JavaFX will happily go on and use Direct3D.
When is this time? Well, its either ‘at any time’ in a signed Webstart app with the appropriate security permissions, or at the ‘right time’ in an unsigned webstart application. When is the he right time you ask?
Dmitri Trembovetski (from Sun) notes this as:
“Note that this (ed: requirement for signing) becomes an issue only if the application explicitly initializes effect’s peers by calling Effect.getAccelType() before the runtime has a chance to do so.”
This means you need to call your effects tests AFTER the runtime has done its full initialization, in Dimitri’s example, he does this the use of FX.deferAction after the creation of the Stage
FX.deferAction(function():Void {
accel = for (effect in effects)
“{effect.getClass().getSimpleName()}.getAccelType(gc)={effect.getAccelType(gc)}”;
});
Final points
This need for signing, or testing and the right time is probably going to change in the future, as we said in part 2, a bug has been raised and indications are it will be corrected but as the man reportedly said, premature optimization is the root of all evil so my advice, just get busy writing apps and don’t try and outfox the runtime with conditional effects.
Below is the full sourcecode of Leadfoot as of today, this will run in an unsigned Webstart app. This is effectively Dimitri’s code now, so… um thanks
I owe you a beer (or vodka or orange juice).
/*
package leadfoot;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.effect.*;
import javafx.stage.Stage;
import java.awt.GraphicsEnvironment;
import javafx.scene.shape.Rectangle;
def gc = GraphicsEnvironment.
getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
def effects = [
Blend {}
Bloom {}
BoxBlur {}
ColorAdjust {}
DisplacementMap {}
DropShadow {}
Flood {}
GaussianBlur {}
Glow {}
Identity {}
InnerShadow {}
InvertMask {}
Lighting {}
MotionBlur {}
PerspectiveTransform {}
Reflection {}
SepiaTone {}
Shadow {}
];
var accel : String[];
Stage {
scene: Scene {
content: [
Rectangle { width: 10 height: 10 effect: GaussianBlur {} }
ListView {
width: 350
items: bind accel
}
]
}
}
FX.deferAction(function():Void {
accel = for (effect in effects)
“{effect.getClass().getSimpleName()}.getAccelType(gc)={effect.getAccelType(gc)}”;
});
You can run the final version here
[...] this entry has been superceeded by Take 3, you can read it for historical context/further explanation, but you should forget its conclusion, [...]
[...] Steven Herod on Jul 20, 2009 in Uncategorized | Subscribe Note, this entry has been superceeded by Take 3, you can read it for historical context/further explanation. The comments of this blog are also [...]
I have the same results since first version
Regards,
@krzychukula
Steven, so the conclusion is if I have a GPU, JavaFX will be accelerated with the GPU always? But JavaFX (still) does not support shaders, it is that right?.
[...] View post: Fumbling Forward » Blog Archive » JavaFX and Hardware Acceleration … [...]
[...] posted here: Fumbling Forward » Blog Archive » JavaFX and Hardware Acceleration … 21 Jul 09 | [...]
> But JavaFX (still) does not support shaders, it is that right?.
Depends on your definition of “support”. Shaders are used for implementing built in effects. They aren’t exposed to the developers (yet).
Dmitri
Oh great, except for a few intrinsic methods (obviously Identity and Flood, for example), I have only CPU/SIMD on my old Windows XP box. According to dxdiag, I do have Direct3D 9.0 working. Although according to my JGears tests it is excruciatingly slow (1 or 2 FPS with the translucent gradient texture) when OpenGL performs at a decent rate (around 45 FPS). So I wonder why we don’t have OpenGL acceleration on Windows platforms.
Philippe, the current implementation (as of JavaFX 1.2) requires Pixel Shader 3.0 level of hardware for JavaFX hw accelerated pipeline (and it also requires JDK 6u10+), and it’s only enabled on Nvidia and ATI video boards, Intel ones are excluded due to driver stability and performance issues.
Dmitri
[...] into hardware acceleration of effects in JavaFX. After a number of issues were resolved, information started flowing (with the help of Dmitri Trembovetski and Chris Campbell from Sun). In short, if your hardware is [...]
Thanks for the info, Dmitri.
So no wonder, I have a Nvidia graphics card, but as I said, an old one: GeForce4 MX 4000
I have JDK 1.6.0_13, but not a good enough card, I suppose.
That’s very interesting info !
Now, I would love to have some more details on when HW acceleration is in use and optimal (and/or what sort of “system” config we need to make on Linux to make it work).
I need to choose the HW for a dedicated netbox running a JavaFx application, and for now the only solution I see is to test different HW until I find the one that works perfectly with JavaFx…..