KDU Implementation

From Second Life Wiki
Jump to navigation Jump to search

This page documents the code implementing calls to the Kakadu library used to read and write JPEG2000 files in Linden Lab's official Viewers (development versions 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 on Mac and Linux, 12% faster on Windows in decompression than the old one.

References:

KDU_X86_INTRINSICS

The Kakadu documentation mentions that performance on 32bits architecture are better using the KDU_X86_INTRINSICS compilation directive. We ran some tests using that directive on Mac and Windows and found that the performance of v6.4.1 were actually back to the level of v4.2.1 for Mac, even slightly worse for Windows (see tables here under).

We therefore do not recommend to use this compilation directive.

Mac : Base = Kakadu v4.2.1 vs. Target = Kakadu v6.4.1 with KDU_X86_INTRINSICS

<tab class=lltable head=top border=1> Metric Base(B) Target(T) Diff(T-B) Percentage(100*T/B) Time Decompression (s) 55.2314 49.0371 -6.1943 88.7848 Volume In Decompression (kB) 59110.2734 56797.7852 -2312.4883 96.0878 Volume Out Decompression (kB) 571937.6875 532159.9375 -39777.7500 93.0451 Decompression Ratio (x:1) 9.6758 9.3694 -0.3064 96.8334 Perf Decompression (kB/s) 1070.2286 1158.2612 88.0326 108.2256 Time Compression (s) 0.3415 0.4206 0.0791 123.1523 Volume In Compression (kB) 2359.2959 3145.7280 786.4321 133.3333 Volume Out Compression (kB) 294.5330 392.3960 97.8630 133.2265 Compression Ratio (x:1) 8.0103 8.0167 0.0064 100.0802 Perf Compression (kB/s) 6908.8086 7479.9619 571.1533 108.2670 </tab>

Windows : Base = Kakadu v4.2.1 vs. Target = Kakadu v6.4.1 with KDU_X86_INTRINSICS

<tab class=lltable head=top border=1> Metric Base(B) Target(T) Diff(T-B) Percentage(100*T/B) Time Decompression (s) 32.7087 35.8386 3.1299 109.5690 Volume In Decompression (kB) 69416.0313 70317.5547 901.5234 101.2987 Volume Out Decompression (kB) 639489.0625 659563.9375 20074.8750 103.1392 Decompression Ratio (x:1) 9.2124 9.3798 0.1674 101.8169 Perf Decompression (kB/s) 2122.2468 1962.0601 -160.1868 92.4520 Time Compression (s) 0.3180 0.3279 0.0099 103.1266 Volume In Compression (kB) 3145.7280 3145.7280 0.0000 100.0000 Volume Out Compression (kB) 393.0400 392.8940 -0.1460 99.9629 Compression Ratio (x:1) 8.0036 8.0066 0.0030 100.0372 Perf Compression (kB/s) 9892.3506 9592.4316 -299.9189 96.9682 </tab>

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.