KDU Implementation
This page documents the code implementing calls to the Kakadu library used to read and write JPEG2000 files in Linden Lab's official Viewers (Snowstorm and all released viewers).
Note to TPV developers: If you want to use that code, you need to get a license from Kakadu, build the library and link it to the Viewer. This documentation gives some guidelines on how to do that.
Objective
In Snowstorm sprint 8, we took on the task to update the old v4.2.1 Kakadu library to the newer v6.4.1 version. In doing so, we tried to address the following issues:
- Performance: take advantage of the improvements provided by a newer version of the library
- Performance: study Kakadu v6.4.1 and see if some new techniques could be used to improve the texture decompression performance
- Linking: move from a dynamic linking scheme to a static linking scheme so that we conform to the terms of the Kakadu license
- Open Sourcing: get rid of the old proprietary llkdu libraries and instead make the llkdu code open source so that 3rd party who do have a proper Kakadu license can produce a viewer using that library
Improving decompression performance helps alleviate common "lag" problems: gray prims on loading or teleport, blurry textures, weird looking abstract sculpties, and so on. Decompression alone though is not the source of all lag issues.
Also, the JPEG2000 architecture gives us methods to load only the sub region of the relevant resolution needed by the viewer to render a piece of texture. Currently though, the viewer loads much more than it needs for general textures and not enough for sculpties. The viewer is not using all the Pyramidal Parametrics magic it could (it does once the texture is loaded as an OpenGL texture but not at fetch time).
Implementation
KDU Libraries
Linden Lab produces KDU binaries (mentioned in install.xml) that are only accessible to Linden Lab for licensing reasons.
TPV developers who wish to make use of this library for JPEG2000 need to get a license from Kakadu and build their own library.
Currently, the viewer uses only the Kakadu coresys library. TPV developers need to build a static version of this library, rename it as appropriate and drop it in the /libraries folder structure along with other 3rd party libraries. Kakadu headers need to be dropped in a libraries/include/kdu folder. Please refer to indra/cmake/LLKDU.cmake for naming conventions and detailed folder structure.
Linden Lab is using 32-bit binaries. It is possible to build the Kakadu libraries for 64 bits. However, Linden Lab does not test or support 64-bit binaries; no tests have been performed using such binaries and linking with a 64 bit viewer.
Reference:
Building with KDU
Once the libraries and headers are installed, the developer just needs to specify -DUSE_KDU:BOOL=ON
when invoking cmake or using develop.py which will pass the parameter to cmake, in order to link with KDU.
From a build standpoint, here's a detailed list of what has been changed in order to build with this new library and statically link to it:
- indra/cmake/Copy3rdPartyLibs.cmake, CopyWinLibs.cmake: Suppressed everything that was llkdu.dll copy orders.
- indra/cmake/LLKDU.cmake: New file. Sets where libraries and include for KDU are to be found.
- indra/llimage/CMakeLists.txt: Suppressed the explicitely link to LLImageJ2COJ library.
- indra/newview/CMakeLists.txt: Added the static kdu in the target_link_libraries, suppress the dependency on dll, add code to switch to openjpeg linking if kdu absent.
- indra/integration_tests/llui_libtest/CMakeLists.txt: Added explicit link to LLImageJ2COJ and LLIMAGE so that it gets build without relying on newview or LLIMAGE linking to LLImageJ2COJ.
- llimage/llimagej2c: Eliminated the llkdu.dll loading and the switch between openjpeg and kdu implementations through Impl. The switch is done at build time now using
USE_KDU
. - indra/llkdu: New folder and files. Implementation of the KDU calls.
Reference:
indra/llkdu
The KDU implementation is available in indra/llkdu and properly open sourced.
It contains only 2 modules (llimagej2ckdu and llkdumem) and one set of unit tests (tests/llimagej2ckdu_test.cpp).
llkdumem contains only memory helpers classes adapted to Kakadu code to handle data buffers in and out the compression/decompression library.
llimagej2ckdu contains the LLImageJ2CKDU
class, inheriting from the viewer LLImageJ2CImpl
and implementing the 3 virtual methods essential for JPEG2000 compression/decompression:
getMetadata()
decodeImpl()
encodeImpl()
Documentation:
Performance Data
As part of this work, we created a new set of performance metrics in order to compare the performances of v4.2.1 to v.6.4.1. The whole performance metric framework has been deeply reworked and improved as a result, allowing for specific test metrics to be produced and independently saved and analyzed.
The KDU results show that this new version is 30% faster in decompression than the old one.
References:
References
- JPEG2000: Wikipedia article. Read this short and clear review first.
- jpeg.org: The portal of the official JPEG organization. Not much substance unfortunately.
- Taubman: All papers by Taubman, the main author of Kakadu. Excellent source of ideas, pretty academic though.
- JPEG 2000 Image Coding Standard: Independent paper with very clear definition of more arcane JPEG2000 notions.
- OpenJpeg: The official page of the OpenJpeg project.