Pre-General Availability: 2017-05-23

11 Java 2D Pipeline Rendering and Properties

This chapter provides information and guidance for troubleshooting some of the most common issues that might be found in the Java 2D API when changing pipeline rendering and properties.

For a summary of Java 2D properties, see Java 2D Properties.

By choosing a different pipeline, or manipulating the properties of a pipeline, you might be able to determine the cause of the problem, and often find a workaround.

In general you can troubleshoot Java 2D pipeline issues by determining the default pipeline used in your configuration. Then, either change the pipeline to another one, or modify the properties of the default pipeline.

If the problem disappears, you have found a workaround. If the problem persists, try changing another property or pipeline.

Java 2D uses a set of pipelines, which can be roughly defined as different ways of rendering the primitives. These pipelines are as follows:

Oracle Solaris and Linux: X11 Pipeline

On Unix platforms the default pipeline is the X11 pipeline. This pipeline uses the X protocol for rendering to the screen or to certain types of offscreen images, such as VolatileImages, or "compatible" images (images that are created with the GraphicsConfiguration.createCompatibleImage() method).

Such types of images can be put into X11 pixmaps for improved performance, especially in the case of the Remote X server.

In addition, in certain cases Java 2D uses X server extensions, for example, the MIT X shared memory extension, or Direct Graphics Access extension, Double-buffer extension for double-buffering when using the BufferStrategy API.

An additional pipeline, the OpenGL pipeline, might offer greater performance in some configurations.

The following are X11 pipeline properties to troubleshoot.

X11 Pipeline Pixmaps Properties

Java 2D by default uses X11 pixmaps for storing or caching certain types of offscreen images.

Only the following types of images can be stored in pixmaps:

  • Opaque images, in which case ColorModel.getTransparency() returns Transparency.OPAQUE

  • 1-bit transparent images (also known as sprites, Transparency.BITMASK)

The advantage of using pixmaps for storing images is that they can be put into the framebuffer's Video memory at the driver's discretion, which improves the speed at which these pixmaps can be copied to the screen or another pixmap.

The use of pixmaps typically results in better performance. However, in certain cases, the opposite is true. Such cases typically involve the use of operations which cannot be performed using the X protocol, such as antialiasing, alpha compositing, and transforms that are more complex than simple translation transforms.

For these operations the X11 pipeline must do the rendering using the built-in software renderer. In most cases this includes reading the contents of the pixmap to a system memory (over the network in the case of remote X server), performing the rendering, and then sending the pixels back to the pixmap. Such operations could result in extremely poor performance, especially if the X server is remote.

The following are two cases to disable the use of X11 pipeline:

  1. Disable X11 pipeline pixmaps:

    To disable the use of pixmaps by Java2D, pass the following property to the Java VM: -Dsun.java2d.pmoffscreen=false.

  2. Disable X11 pipeline shared memory pixmaps:
    To minimize the effect of such operations requiring reading of pixels from a pixmap on overall performance, the X11 pipeline uses shared memory pixmaps for storing images which are often read from.

    Note:

    The shared memory pixmaps can only be used in the case of a local X server.

    The advantage of using shared memory pixmaps is that the pipeline can get direct access to the pixels in the pipeline bypassing the X11 protocol, which results in better performance.

    By default an image is stored in a normal X server pixmap, but it can be later moved to a shared memory pixmap if the pipeline detects excessive reading from such an image. The image can be moved back to a server pixmap if it is copied from often enough.

    The pipeline allows two ways of controlling the use of shared memory pixmaps: either disabling them, or forcing all images to be always stored in shared memory pixmaps.

    First try forcing the shared memory pixmaps, as it often improves performance. However, with certain video board/driver configurations it may be necessary to disable the shared memory pixmaps to avoid rendering artifacts or crashes.

    • To disable shared memory pixmaps, set the J2D_PIXMAPS environment variable to server. This is the default in remote X server case.
    • To force all pixmaps to be created in shared memory, set J2D_PIXMAPS to shared.

X11 Pipeline MIT Shared Memory Extension

The Java 2D X11 pipeline uses the MIT Shared Memory Extension (MIT SHM) allows faster exchange of data between the client and the X server.

By default, the Java 2D X11 pipeline uses the MIT Shared Memory Extension (MIT SHM). This extension allows a faster exchange of data between the client (the Java application) and the X server, and this can significantly improve the performance of Java applications.

The following are two ways to improve the performance of Java application.

  • Increase X Server and Java 2D shared memory:

    On Oracle Solaris operating system releases 8 and earlier it was sometimes necessary to increase the amount of shared memory available to the system (and to X server in particular) as the default was too low, resulting in poor rendering performance. Increasing the amount of shared memory and shared memory segments can result in better performance.

    To change the default settings on Oracle Solaris operating system, edit the /etc/system file, changing the shmsys:shminfo_* settings, as shown in the following example. Note that this is not needed on Oracle Solaris 9 and newer.

    set shmsys:shminfo_shmmax=10000000
    set shmsys:shminfo_shmni=200
    set shmsys:shminfo_shminfo=150
    

    On Linux this setting can be configured by editing the /proc/sys/kernel/shm* files.

  • Disable X11 pipeline shared memory extension:

    In case of problems (such as crashes, or rendering artifacts) with older X servers and Shared Memory Extension, it is useful to be able to disable the extension. To disable the use of MIT SHM, set the J2D_USE_MITSHM environment variable to false.

Oracle Solaris on SPARC: DGA Support

On SPARC hardware, if the framebuffer supports Sun's DGA (Direct Graphics Access) X server extension, and Java 2D has a corresponding module for accessing the framebuffer, DGA will be used for rendering to the screen.

All offscreen images will reside in Java heap memory, and Java 2D's software-only rendering pipeline is used for rendering to them. This is different from a typical UNIX configuration, where X11 pixmaps are used for offscreen images.

The following are use cases that describe how to detect DGA extension support and disable/enable DGA:

  • DGA extension for rending

    To detect if the DGA extension is used for rendering to the screen, run any Java application which does some rendering or displays a GUI, and check if a /tmp/wg* file was created when the application started. Exit the application and verify that the file has been deleted. If this is the case, then on this system Java 2D is using DGA.

  • Typical DGA Issues:

    Since DGA allows direct access to the framebuffer's video memory, the typical problems include corruption outside of window bounds, complete system, and X server lock-ups.

  • Enable or Disable DGA:

    If it is determined that DGA is being used, the first thing to try is to disable it. This can be done by setting the NO_J2D_DGA environment variable to true. This forces the default UNIX path to use only X11 for rendering to the screen, and pixmaps for accelerating offscreen images.

    Sometimes, it could be beneficial to enable the use of pixmaps, while also using DGA for rendering to the screen. To force the use of pixmaps for accelerating offscreen images, set the following property when starting the application: -Dsun.java2d.pmoffscreen=true.

Oracle Solaris on SPARC - Change Java 2D Default Visual

On certain video boards on the SPARC platform, more than one visual can be available from the X server.

By default Java 2D tries to select the best visual, where "best" is typically a higher-bit depth visual. For example, on some Oracle Solaris operating system releases the default X11 visual is 8-bit PseudoColor, although 24-bit visual is also available. In such cases Java 2D will select a 24-bit TrueColor visual as the default for Java windows.

While it is possible to create a Java top-level window with a GraphicsConfiguration object corresponding to a different visual, in some cases it is necessary to make Java use a different default visual instead. This can be done by setting the FORCEDEFVIS environment variable. It can be set to true to force the use of the default X server visual (even if it is not the best one), or it can be set to a hexadecimal number corresponding to the visual ID as reported by tools like xdpyinfo.

To determine your X server default visual, execute the xdpyinfo command and look at the default visual id field.

Windows OS - DirectDraw/GDI Pipeline

The default pipeline on the Windows platform is a mixture of the DirectDraw pipeline and the GDI pipeline, where some operations are performed with the DirectDraw pipeline and others with the GDI pipeline. DirectDraw and GDI APIs are used for rendering to accelerated offscreen and onscreen surfaces.

Starting with the Java SE 6 release, when the application enters full-screen mode, the new Direct3D pipeline can be used, if the drivers satisfy the requirements. Possible issues with the Direct3D pipeline include rendering artifacts, crashes, and performance related problems.

An additional pipeline, the OpenGL pipeline, might offer greater performance in some configurations.

The following are three cases to troubleshoot issues with Direct3D pipeline such as, rendering artifacts, crashes, and performance related problems:

  • Disable DirectDraw pipeline:

    When DirectDraw is disabled, all operations are performed with GDI. Provide the following flag to disable the use of DirectDraw: -Dsun.java2d.noddraw=true. In this case all offscreen images will be created in the Java heap, and rendered to with the default software pipeline. All onscreen rendering, as well as copies of offscreen images to the screen will be performed using GDI.

  • Enable DirectDraw pipeline:

    In case the pipeline was disabled by default for some reason, it can be enabled by providing the -Dsun.java2d.noddraw=false flag to the VM.

    However, typically there was a reason why it was disabled in the first place, so it is better not to force it.

  • Disable built-in punting mechanism:

    In general, the DirectDraw pipeline attempts to place the offscreen surfaces in the framebuffer's video memory, which provides fast copies from these surfaces to the screen or other accelerated surfaces, as well as hardware accelerated rendering of certain graphics operations.

    To limit the impact of unaccelerated rendering to VRAM-based surfaces, there exists a punting mechanism, which moves the surface which is detected to be often read from to the system memory. If the surface is found to be copied from often enough, it may be promoted back to the video memory.

    However, if the pipeline cannot perform an operation using the DirectDraw API (operations using, for example, alpha compositing, or transforms, or antialiasing), the rendering is performed using the software pipeline. In some cases this means that the pixels of the destination surface, which resides in VRAM, need to be read into system memory, which is a very expensive operation.

    On certain video boards/drivers combinations the system-memory based DirectDraw surfaces are known to cause rendering artifacts and other issues. The DirectDraw pipeline provides a way to disable the punting mechanism so that the system memory surfaces are not used.

    To defeat the built-in surface punting mechanism provide the following flag to the Java VM: -Dsun.java2d.ddforcevram=true.

    Note:

    This can result in performance degradation, as the software loops may be reading pixels from VRAM on each operation. In this case you may consider disabling the DirectDraw pipeline (see above).

  • Disable DirectDraw BILT operations:

    In a BILT operation (Bit Block Transfer), two bitmap patterns are combined. This operation basically corresponds to a call to the Graphics.drawImage() API.

    In some cases it is possible to avoid rendering problems by disabling the DirectDraw blit operations. GDI blits will be used instead.

    Note:

    This might result in bad performance. Consider disabling the DirectDraw pipeline instead.

    To disable the use of DirectDraw blit operations, pass the parameter -Dsun.java2d.ddblit=false to the Java VM.

Windows OS - Direct3D Pipeline in Full-Screen Mode

Starting with the Java SE 6 release, the Direct3D pipeline uses the Direct3D API for rendering. This pipeline is enabled in full-screen mode by default, if the drivers support the required features and the level of rendering quality.

It is possible to enable the Direct3D pipeline or to force its use, as described in the subsections below.

Consider enabling the Direct3D pipeline for your application if it makes heavy use of rendering operations such as alpha compositing, antialiasing, and transforms.

However, use caution when deciding to enable this pipeline in your application. For example, some built-in video chipsets (which are used in most notebooks) do not perform well using Direct3D, even if they satisfy the quality requirements for Java 2D pipelines.

The following are three cases to troubleshoot problems with Direct3D API.

  1. Disable Direct3D pipeline:

    Some older video boards/drivers combinations are known to cause issues (both rendering and performance) with the Direct3D pipeline. To disable the pipeline in such cases, with Java SE 5 and later releases, pass the parameter -Dsun.java2d.d3d=false to the Java VM, or set the J2D_D3D environment variable to false.

  2. Enable Direct3D pipeline:
    With Java SE 5 and later releases, to enable the Direct3D pipeline in both windowed and full-screen mode, use the parameter -Dsun.java2d.d3d=true, or set the J2D_D3D environment variable to true.

    Note:

    The pipeline is enabled only if the drivers support minimum required features.
  3. Diagnose Direct3D pipeline rendering problems:

    With the Java SE 8 release, some rendering issues (like missing pixels, garbled rendering) can be diagnosed by forcing different Direct3D rasterizers. Set the J2D_D3D_RASTERIZER environment variable to one of the following: ref, rgb, hal, or tnl.

    See Direct3D documentation for a description of these rasterizers. By default the best rasterizer is chosen based on its advertised capabilities. In particular, the ref rasterizer forces the use of the reference Direct3D rasterizer from Microsoft. If a rendering problem is not reproducible with this rasterizer, then it is very likely to be a video driver bug.

    The rgb rasterizer is available only if the Direct3D SDK is installed. This SDK can be obtained from Microsoft Game Technologies Center.

    For performance or quality problems with text rendering with the Direct3D pipeline, you can force the use of ARGB texture instead of the default Alpha texture for the Direct3D pipeline's glyph cache. To do this, set the J2D_D3D_NOALPHATEXTURE environment variable to true.

OpenGL Pipeline in Oracle Solaris, Linux and Windows

The OpenGL pipeline is available on Oracle Solaris, Linux, and Windows.

This alternate pipeline uses the hardware-accelerated, cross-platform OpenGL API when rendering to VolatileImages, to backbuffers created with BufferStrategy API, and to the screen.

This pipeline can offer great performance advantages over the default (X11 or GDI/DirectDraw) pipelines for certain applications. Consider enabling the pipeline for your application if it makes heavy use of rendering operations like alpha compositing, antialiasing, and transforms.

The following are use cases for troubleshooting problems in OpenGL pipeline

Enable OpenGL Pipeline

The OpenGL pipeline is currently disabled by default.

To attempt to enable the OpenGL pipeline, provide the following option to the JVM:

-Dsun.java2d.opengl=true

To receive verbose console output about whether the OpenGL pipeline is initialized successfully for a particular screen, set the option to True (note the uppercase "T"):

Minimum Requirements

The OpenGL pipeline will not be enabled if the hardware or drivers do not meet the minimum requirements.

If for some reason one of the following requirements is not met, Java 2D will fall back and use the default pipeline (X11 on Oracle Solaris/Linux, GDI/DirectDraw on Windows), which means your application will continue to work correctly, but without the OpenGL acceleration.

The minimum requirements for Oracle Solaris and Linux operating systems are the following:

  • Hardware accelerated OpenGL/GLX libraries installed and configured properly

  • OpenGL version 1.2 or higher

  • GLX version 1.3 or higher

  • At least one TrueColor visual with an available depth buffer

The minimum requirements for Windows OS are the following:

  • Hardware accelerated drivers supporting the extensions WGL_ARB_pbuffer, WGL_ARB_render_texture, and WGL_ARB_pixel_format

  • OpenGL version 1.2 or higher

  • At least one pixel format with an available depth buffer

Diagnose Startup Issues

You can get detailed information about the startup procedures of the OpenGL-based Java 2D pipeline by using the J2D_TRACE_LEVEL environment variable.

As mentioned above, the OpenGL pipeline might not be enabled on certain machines for various reasons. For example, the drivers might not be properly installed and might report an insufficient version number. Alternatively, your machine might have an older graphics card that does not support the appropriate OpenGL version or extensions.

In the Java SE 6 and later releases, you can get detailed information about the startup procedures of the OpenGL-based Java 2D pipeline by using the J2D_TRACE_LEVEL environment variable as shown in the following examples.

Set the J2D_TRACE_LEVEL environment variable on Windows.

# set J2D_TRACE_LEVEL=4
# java -Dsun.java2d.opengl=True YourApp

Set the J2D_TRACE_LEVEL environment variable on Solaris and Linux.

# export J2D_TRACE_LEVEL=4
# java -Dsun.java2d.opengl=True YourApp

The output will be different depending on your platform and the installed graphics hardware, but it can give you some insight into the reasons why the OpenGL pipeline is not being successfully enabled for your configuration.

Note:

This output is especially useful when filing bug reports intended for the Java 2D team at Sun, as discussed below.

Diagnose Rendering and Performance Issues

Diagnose if rendering or performance issues are being caused by Java 2D or by the OpenGL drivers.

Since the OpenGL pipeline relies so heavily on the underlying graphics hardware and drivers, it might sometimes be difficult to determine whether rendering or performance issues are being caused by Java 2D or by the OpenGL drivers.

One feature new to the OpenGL pipeline in the Java SE 6 release is the use of the GL_EXT_framebuffer_object extension, which provides better performance for rendering and reduced VRAM consumption when using VolatileImages. This "FBO" codepath is enabled by default when the OpenGL pipeline is enabled, but only if your graphics hardware and driver support this OpenGL extension. This extension is generally available on Nvidia GeForce/Quadro FX series and newer, and on ATI Radeon 9500 and newer. If you suspect that the "FBO" codepath is causing problems in your application, you can disable it by setting the following system property:

-Dsun.java2d.opengl.fbobject=false

Setting this property will cause Java 2D to fall back on the older pbuffer-based codepath.

If you find that a certain Java 2D operation causes different visual results with the OpenGL pipeline enabled than without, it probably indicates a graphics driver bug. Similarly, if the performance of Java 2D rendering is significantly worse with the OpenGL pipeline enabled than without, it is most likely caused by a driver or hardware problem.

In either case, file a detailed bug report through the normal bug reporting channels. See Submit a Bug Report. When filing bug reports, be as detailed as possible, and always include the following information:

  • Operating system (for example, Ubuntu Linux 6.06, Windows XP SP2)
  • Name of graphics hardware manufacturer and device (for example, Nvidia GeForce 2 MX 440)
  • Exact driver version (for example, ATI Catalyst 6.8, Nvidia 91.33)
  • Output when J2D_TRACE_LEVEL=4 is specified on the command line (as described in previous section)
  • If on Oracle Solaris or Linux, the output of the glxinfo command

Latest OpenGL Drivers

List of graphics card manufacturers with their corresponding web sites, supported platforms, and some examples of cards.

Since the OpenGL pipeline relies heavily on the OpenGL API and the underlying graphics hardware and drivers, it is very important to ensure that you have the latest graphics drivers installed on your machine. Drivers can be downloaded from your graphics card manufacturer's web site, as shown in the following table.

Manufacturer Platforms Cards Known to Work

ATI

Linux, Windows

Radeon 8500 and above, FireGL series

Nvidia

Oracle Solaris on x64, Linux, Windows

GeForce 2 series and above, Quadro FX series and above

Oracle

Oracle Solaris on SPARC

Expert3D series, XVR-500, XVR-600, XVR-1200, XVR-2500

Xi Graphics

Oracle Solaris on x86, Linux

Various (check with Xi Graphics)