{"id":165,"date":"2009-07-08T21:42:42","date_gmt":"2009-07-08T20:42:42","guid":{"rendered":"http:\/\/lqd.hybird.org\/journal\/?p=165"},"modified":"2009-09-01T16:03:57","modified_gmt":"2009-09-01T15:03:57","slug":"hardware-accelerated-effects-in-swing-with-jxlayer-and-decora","status":"publish","type":"post","link":"https:\/\/lqd.hybird.org\/journal\/?p=165","title":{"rendered":"Hardware Accelerated Effects in Swing with JXLayer and Decora"},"content":{"rendered":"<p><strong>Update (August, 31st)<\/strong>: I released version 0.2 of this library, fixing a couple of problems, and adding the possibility of making your own custom pixel shaders. You can find the second part of this series on pixel shaders <a href=\"https:\/\/lqd.hybird.org\/journal\/?p=196\">here<\/a>.<\/p>\n<h3>The Olive Branch<\/h3>\n<p>A lot has been said about Swing and JavaFX recently, in a seemingly unending flame war between fans of each side. Both have merits and flaws, and as you&#8217;ve seen over time, i&#8217;m advocating a 3rd way, which i decided to pompously call The Olive Branch for no reason whatsoever, which is using the best of both worlds.<\/p>\n<p>The plan is to use, directly from java, scenario and decora -the graphics libraries that power the javafx runtime, and which i love probably more than my girlfriend, but don&#8217;t tell her (: &#8211; (btw if you don&#8217;t like crappy jokes, you better stop reading now, and grab a taco or something) . Of course, things have changed since their release, what was once an open source public API (albeit destined to change heavily) is now an internal proprietary one, which means danger, will robinson. So, the plan is to have the community build things that are so cool, and innovative, that Sun will allow us to do just that and make scenario\/decora public and usable from java, as they said they would, like with a jnlp extension or something. I think when things have stabilized a little, they&#8217;ll get to it. But at the moment, i have succeeded in doing that, at a level of 2% (and i&#8217;ve mailed Sun telling them everything i&#8217;ve done with scenario in the last 18 months &#8211; which is quite a bit in retrospect). Let&#8217;s see if we can crank that baby up.<\/p>\n<h3>Introducing jfxlayer<\/h3>\n<p>I&#8217;ve started this a long time ago, i wanted to help people use scenario and decora in swing, not only in a pure scenario scene as with Scenile, but from regular, real world swing, because some tasks are better handled by scenario and decora, and vice versa. The best of both worlds. I never got around to releasing it because i haven&#8217;t gotten to a satisfying point in this endeavour (+ i&#8217;m lazy), i&#8217;ve just planned the whole shebang, and coded the first little step, how to use hardware accelerated decora effects in plain old swing. It&#8217;s like 30 lines of code, that i kept in sync with every JavaFX release. I&#8217;ll get to the other planned features eventually, in the meantime, here&#8217;s the result of this piece of work. Hopefully, it&#8217;s interesting enough for regular Swing java users, or more &#8220;exotic&#8221; ones, like them groovy folks (:<\/p>\n<p>It&#8217;s almost nothing code and work-wise. However, this opens a *huge* realm of possibilities for swing apps, and i hope you&#8217;ll see that too.<\/p>\n<p>The concept is simple: add decora&#8217;s effects to the BufferedImageOps effects that jxlayer allows.<\/p>\n<p>Decora. OpenJFX. JXLayer. JFXLayer.<\/p>\n<h3>Decora ?<\/h3>\n<p>Decora is Chris Campbell&#8217;s baby, if you don&#8217;t know who that is, you can stop reading now, bye. This library is arguably the smallest, the easiest to use and most powerful one you&#8217;ll ever come across if you&#8217;re dealing with effects, image processing, and shaders. A decora effect is made with a JSL file (Java Shader Language) which is basically a mix between Java (in order to get\/set parameters and control the effect) and GLSL\/HLSL ie, a generic high level OpenGL\/DirectX shader language. This JSL file is then &#8220;compiled&#8221; (by a code generation utility) into a specific effect for each supported backend. The backends are mutually exclusive branches of code that target a specific architecture\/3D API, etc. Depending on your software and hardware configuration, decora will choose the backend that will perform the best on your computer, whether you&#8217;re on windows mac or linux for instance. You have a regular &#8220;software&#8221; backend in pure java, one using JNI, one targetting OpenGL, another one OpenGL ES2 for mobile devices, another one Direct3D, and one targeting Prism, the next gen JavaFX graphics renderer, which will allow 3D and more perf, which is about as far as everyone knows. Back in the open source decora days, i&#8217;ve also written a backend myself, which multithreaded the regular Java backend, so that effects would use all your available cpus\/cores.<\/p>\n<p>All that from one tiny JSL file, they really are small, check the old open source version you&#8217;ll see. For the user, it&#8217;s of course transparent, you create an instance of the effect you want, and use it, decora handles the rest behind the scenes.<\/p>\n<p>Sure, there aren&#8217;t that many effects yet (in fact there haven&#8217;t been any new ones since it was released, the work is done on the architecture, perf, backends, for the existing effects, which is very logical if you think about it) compared to, say, what Jerry Huxtable offers in his jhlabs filters library. In practice, it&#8217;s enough, for instance you have blurs and shadows, a perspective effect (think coverflow), color transforms, etc and a way to mix and chain all of the effects. If we had access to the compiler (or if we reverse engineered and forward ported that to the open source version) we could add new effects, but it&#8217;s not the case anymore. I think it&#8217;s doable if you really want it, especially for GLSL shaders which&#8217;ll be very interesting once Prism is released, if the compiler isn&#8217;t available at that time. I haven&#8217;t felt the need to create new effects until this week where i needed a better displacement effect than the one provided. So we&#8217;ll see how it goes but i&#8217;m not planning on doing it anytime soon.<\/p>\n<h3>How do i use it in swing ?<\/h3>\n<p>Enough about decora. In your Swing app, use JXLayer, and use the JFXLayer effect bridge with stock decora effects. It&#8217;s very simple:<br \/>\n[sourcecode language=&#8217;java&#8217;]<br \/>\nBufferedLayerUI ui = &#8230;; \/\/ your regular JXLayer LayerUI<br \/>\nEffect decoraEffect = &#8230;; \/\/ your regular decora effect<br \/>\n\/\/ like GaussianBlur, Bloom, DropShadow, etc<br \/>\nui.setLayerEffects (new DecoraLayerEffect  (effect));<br \/>\n[\/sourcecode]<\/p>\n<p>Compare that with using JOGL and pixel shaders directly as Romain did in the Filthy Rich Clients book (the sample is like 500 lines long, and which are mostly low level code for setting everything up for rendering, here it takes 5 at most, thanks Chris!)<\/p>\n<h3>Demos. Finally! I&#8217;m as tired reading this awfully long blog post as you are writing it<\/h3>\n<p>I know you&#8217;re all about demos and eye candy, and today, i have 3 of them for you. Not one, but three, and if you call right now with your credit card number, i&#8217;ll add a set of Ginsu2000 knifes for only 3 easy payments of 9.99$, they can cut a shoe, you know ?<\/p>\n<p>Since this post is about hardware accelerated effects, you&#8217;ll obviously need a decent graphics card with up to date drivers.<\/p>\n<p><a href=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/07\/basicdemo.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/07\/basicdemo-150x150.png\" alt=\"basicdemo\" title=\"basicdemo\" width=\"150\" height=\"150\" class=\"aligncenter size-thumbnail wp-image-176\" \/><\/a><\/p>\n<a href=\"http:\/\/lqd.hybird.org\/apps\/demos\/jfxlayer\/basic.jnlp\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/06\/webstart.png\" alt=\"Launch the basic demo\" title=\"Basic demo\" width=\"88\" height=\"23\" class=\"size-full wp-image-153\" \/><\/a>\n<p>The first one is pretty basic, it&#8217;s two buttons. Pushing each one starts an animation (using the same code that powers the eMotionBlur demo of last time) that progressively blurs the component (but remains live). The button on the left is using a jhlabs blur filter, while the one on the right is using decora&#8217;s one. At the default size, it&#8217;s really close, but maximize the window and you&#8217;ll see the difference, and possibly start to envision the possibilities this offers. Who knows maybe it can be used to power screen transitions (even though i&#8217;m still not fully satisfied with the perf yet &#8211; maybe Alexander Potochkin, or Dmitri Trembovetski can help us out here, pajalusta (or whatever it&#8217;s spelled in cyrillic (: &#8211; you&#8217;ll see it&#8217;s decent enough for me to release it) &#8211; Mark, you can keep us updated on that (:<\/p>\n<p><a href=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/07\/lockabledemo.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/07\/lockabledemo-150x150.png\" alt=\"lockabledemo\" title=\"lockabledemo\" width=\"150\" height=\"150\" class=\"aligncenter size-thumbnail wp-image-177\" \/><\/a><\/p>\n<a href=\"http:\/\/lqd.hybird.org\/apps\/demos\/jfxlayer\/lockable.jnlp\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/06\/webstart.png\" alt=\"Launch the LockableUI demo\" title=\"LockableUI demo\" width=\"88\" height=\"23\" class=\"size-full wp-image-153\" \/><\/a>\n<p>The second one is a modified demo from the JXLayer distribution, using the LockableUI, here also you can compare blurs. On my machine it&#8217;s almost instantaneous with decora.<\/p>\n<p><a href=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/07\/twimber2demo.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/07\/twimber2demo-150x150.png\" alt=\"twimber2demo\" title=\"twimber2demo\" width=\"150\" height=\"150\" class=\"aligncenter size-thumbnail wp-image-178\" \/><\/a><\/p>\n<p><a href=\"http:\/\/lqd.hybird.org\/apps\/demos\/jfxlayer\/twimber2.jnlp\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lqd.hybird.org\/journal\/wp-content\/uploads\/2009\/06\/webstart.png\" alt=\"webstart\" title=\"Twimber2 demo\" width=\"88\" height=\"23\" class=\"aligncenter size-full wp-image-153\" \/><\/a><\/p>\n<p>And finally the 3rd one is a modified version of Twimber, my tiny twitter provider for Kirill&#8217;s great Amber project. I&#8217;ve hacked animated blooms, blurs, and color transforms into it in a matter of an hour, where it would have probably taken me days fiddling with jogl. Bear in my mind this demo is *heavy* with animated effects, and absolutely not optimized at all (for instance the repaints are too big, the effects target components that are too big, etc) and might run slowly (it does a little on my machine) or quite possibly crash your vm (which it does on another machine, probably a bug in my graphics card driver that crashes everything)<del datetime=\"2009-07-10T18:55:20+00:00\">, plus there are some deadlocks somewhere between Amber and the latest releases of Trident, that i haven&#8217;t tried to remove, maybe Kirill can help us with that, if need be. If that happens, you can only close the webstart window by killing the process, sorry about that, guys.<\/del> Hopefully, we fixed the problem, it stll won&#8217;t be optimized though ^^<\/p>\n<h3>Is it safe to use ?<\/h3>\n<p>Sure, using internal APIs is going to be a pain in the neck, it already has been for me. But, all in all, Decora&#8217;s API did not change much in the last 18 months, and especially not the effects&#8217;. And as the saying goes, no pain no gain. Plus they work fine with JavaFX 1.2 and JFXLayer right now, you don&#8217;t have to use the next version if you don&#8217;t want to have to modify them.<\/p>\n<h3>Downloads and source<\/h3>\n<p><strong>Update (August, 31st)<\/strong>: As mentioned earlier, I released version 0.2 of this library, fixing a couple of problems, and adding the possibility of making your own custom pixel shaders. You can find the second part of this series on pixel shaders <a href=\"https:\/\/lqd.hybird.org\/journal\/?p=196\">here<\/a>. I didn&#8217;t change the code linked here for archive purposes though.<\/p>\n<p>You can find JFXLayer <a href=\"http:\/\/lqd.hybird.org\/apps\/demos\/jfxlayer\/jfxlayer-0.1.jar\">here<\/a> (<a href=\"http:\/\/lqd.hybird.org\/apps\/demos\/jfxlayer\/jfxlayer-0.1-src.zip\">zipped source project + demos<\/a>), and twimber2 <a href=\"http:\/\/lqd.hybird.org\/apps\/demos\/jfxlayer\/Twimber2-src.zip\">here<\/a> (zipped source project).<\/p>\n<p>Let me know what you think, if the demos run well, or whatever in the comments, or sooner on <a href=\"http:\/\/www.twitter.com\/lqd\">twitter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to use Decora to add hardware accelerated effects to your Swing UIs, as usual with open source code and demos<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[14,4,15],"class_list":["post-165","post","type-post","status-publish","format-standard","hentry","category-demo","category-java","tag-decora","tag-scenario","tag-swing"],"_links":{"self":[{"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=\/wp\/v2\/posts\/165","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=165"}],"version-history":[{"count":23,"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=\/wp\/v2\/posts\/165\/revisions"}],"predecessor-version":[{"id":179,"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=\/wp\/v2\/posts\/165\/revisions\/179"}],"wp:attachment":[{"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lqd.hybird.org\/journal\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}