Dienstag, 10. November 2009

Multi-Threading Jules

I played with the idea of making Jules multi-threaded, by rasterizing the trapezoids using multiple threads.
For large shapes it does improve things quite a bit (on my Core2Duo notebook):

Hey, in one case jules now even beats ductus :)

However it reminded me again how hard it is to write well performing multi-threaded code in real-world.
The outcome is a 2-thread producer/consumer implementation, where the consumer can produce for itself if it has catched up with the producer.
The first implementation (multi-unopt) simply fetched idle tiles from a pool, and added rasterized tiles to another one. And there was a volatile variable for communication. That makes 4 uncontended monitorenter/exit + volatile read/write.
With that approach the synchronization overhead eat up almost any speedup, in some cases I even saw ugly regressions.

I now batch fetch/store from the idle/completed tile lists in order to minimize synchronization costs, as well as let the worker start a bit ahead of the consumer.

I am still not sure wether the whole effort makes much sence, it makes the whole thing quite complex.
After all, it was fun ;)

I wonder how much speedup can be archived by using profile-driven optimizations and -O3 when compiling pixman and jules. I guess arround 10-20%, which could be enough to push threaded Jules in front of ductus.

Donnerstag, 5. November 2009

"Jules" cairo binding 0.0.1 release

I've prepared a webrev/patch of the XRender Java2D backend based on jdk7-master. It also includes a preview of "Jules", a cairo based RenderingEngine implementation, for faster antialiased rendering.

Please note Jules is more or less proof-of-concept, especially the native code is ugly, full of dirty assumptions and its probably not 64-bit clean.
However it runs Java2Demo quite well, and usually is a good deal faster than pisces even when rendering to software-surfaces. (and a *lot* faster when rendering to XRender surfaces), especially with the client-jvm.

Because of the need for a modified version of cairo and its complex build-system, I've seperated the native components and build them indepent from OpenJDK - falling back to pisces when loading fails.


1.) Download
The webrev can be downloaded from:

The native jules/cairo code is located at:

2.) Patch
To patch your local jdk7 repository, just do
> hg import ~/webrev/jdk.patch
or if your hg has that option:
> hg import --no-commit ~/webrev/*.patch

3.) Build
- Build your JDK as usual
- Compile Jules by running build_jules.sh (some makefile guru here?) ;)
- Copy libjules.so into build/linux-i586/lib/i386 or elsewhere, where it can be found by the JVM

4. Use it
Simply adding "-Dsun.java2d.renderer=sun.java2d.jules.JulesRenderingEngine" should do the trick :)
In addition you can enable the xrender-backend too, "-Dsun.java2d.xrender=True".
If everything works you should see:
XRender pipeline enabled
Jules library successfully loaded

Known problems:
- Some clipping problems when rendering to software surfaces
- Paints get wrong transformation when rendering to XRender surfaces

Last but not least the usual screenshot:

Update: Unfourtunatly my Nokia-770 where the stuff is hosted went down. Its up&running again.

Sonntag, 1. November 2009

cairo integration continued...

The cairo guys made clear the functions in use are subject to change anytime, and won't be exported.
I'll create a custom cairo-version as shared library, which will include the JNI-binding code, with a different name.

That will:
- Not change the OpenJDK build process (just add a few pure-java files to it)
- Provide native code that fullfills all the assumptions I need.
- Allow distributors to package it as an extension library, if they wish to enhance performance of OpenJDK.
- Allow us to detect at runtime, wether the native rasterizer is available and fall back to pisces if not.

Unfourtunatly it will also waste a few KB of your disk ;)