summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorKevin Rushforth <[email protected]>2004-06-09 04:25:41 +0000
committerKevin Rushforth <[email protected]>2004-06-09 04:25:41 +0000
commit343b658c32a6473c545187c1e276ee5d06c2686a (patch)
treead2606538b7db1c3553c53a79ccccb2ed5b5e4e2 /docs
parent06cebb1e576da6f7222f999ab059dcfa3d8edd39 (diff)
Initial creation of j3d-core-utils sources in CVS repository
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@7 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'docs')
-rw-r--r--docs/perf_guide.txt409
1 files changed, 409 insertions, 0 deletions
diff --git a/docs/perf_guide.txt b/docs/perf_guide.txt
new file mode 100644
index 0000000..074a03d
--- /dev/null
+++ b/docs/perf_guide.txt
@@ -0,0 +1,409 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+ Performance Guide for Java 3D 1.3
+
+I - Introduction
+
+ The Java 3D API was designed with high performance 3D graphics
+as a primary goal. This document presents the performance features of
+Java 3D in a number of ways. It describes the specific APIs that were
+included for performance. It describes which optimizations are currently
+implemented in Java 3D 1.3. And, it describes a number of tips and tricks
+that application writers can use to improve the performance of their
+application.
+
+
+II - Performance in the API
+
+ There are a number of things in the API that were included specifically
+to increase performance. This section examines a few of them.
+
+ - Capability bits
+ Capability bits are the applications way of describing its intentions
+ to the Java 3D implementation. The implementation examines the
+ capability bits to determine which objects may change at run time.
+ Many optimizations are possible with this feature.
+
+ - isFrequent bits
+ Setting the isFrequent bit indicates that the application may frequently
+ access or modify those attributes permitted by the associated capability bit.
+ This can be used by Java 3D as a hint to avoid certain optimizations that
+ could cause those accesses or modifications to be expensive. By default the
+ isFrequent bit associated with each capability bit is set.
+
+ - Compile
+ The are two compile methods in Java 3D. They are in the
+ BranchGroup and SharedGroup classes. Once an application calls
+ compile(), only those attributes of objects that have their
+ capability bits set may be modified. The implementation may then
+ use this information to "compile" the data into a more efficient
+ rendering format.
+
+ - Bounds
+ Many Java 3D object require a bounds associated with them. These
+ objects include Lights, Behaviors, Fogs, Clips, Backgrounds,
+ BoundingLeafs, Sounds, Soundscapes, ModelClips, and AlternateAppearance.
+ The purpose of these bounds is to limit the spatial scope of the
+ specific object. The implementation may quickly disregard the
+ processing of any objects that are out of the spatial scope of a
+ target object.
+
+ - Unordered Rendering
+ All state required to render a specific object in Java 3D is
+ completely defined by the direct path from the root node to the
+ given leaf. That means that leaf nodes have no effect on other
+ leaf nodes, and therefore may be rendered in any order. There
+ are a few ordering requirements for direct descendents of
+ OrderedGroup nodes or Transparent objects. But, most leaf nodes
+ may be reordered to facilitate more efficient rendering.
+
+ - OrderedGroup
+ OrderedGroup now supports an indirection table to allow the user to
+ specify the order that the children should be rendered. This will
+ speed up order update processing, eliminating the expensive
+ attach and detach cycle.
+
+ - Appearance Bundles
+ A Shape3D node has a reference to a Geometry and an Appearance.
+ An Appearance NodeComponent is simply a collection of other
+ NodeComponent references that describe the rendering characteristics
+ of the geometry. Because the Appearance is nothing but a
+ collection of references, it is much simpler and more efficient for
+ the implementation to check for rendering characteristic changes when
+ rendering. This allows the implementation to minimize state changes
+ in the low level rendering API.
+
+ - NIO buffer support for Geometry by-reference
+ NOTE: Use of this feature requires version 1.4 of the JavaTM 2 Platform.
+
+ This provides a big win in both memory and performance for applications
+ that use native C code to generate their geometric data. In many cases,
+ they will no longer need to maintain two copies of their data (one in
+ Java and one in C). The performance win comes mainly from not having to
+ copy the data from their C data structures to the Java array using JNI.
+ Also, since the array isn't part of the pool of memory managed by the
+ garbage collector, it should speed up garbage collection.
+
+
+III - Current Optimizations in Java 3D 1.3
+
+ This section describes a number of optimizations that are currently
+implemented in Java 3D 1.3. The purpose of this section is to help
+application programmers focus their optimizations on things that will
+compliment the current optimizations in Java 3D.
+
+ - Hardware
+ Java 3D uses OpenGL or Direct3D as its low level rendering
+ APIs. It relies on the underlying OpenGL or Direct3D drivers
+ for its low level rendering acceleration. Using a graphics
+ display adapter that offers OpenGL or Direct3D acceleration is
+ the best way to increase overall rendering performance in Java 3D.
+
+ - Compile
+ The following compile optimizations are implemented in the Java 3D
+ 1.2.1 and 1.3 release:
+
+ . Scene graph flattening: TransformGroup nodes that are
+ neither readable nor writable are collapsed into a
+ single transform node.
+
+ . Combining Shape3D nodes: Non-writable Shape3D nodes
+ that have the same appearance attributes, not pickable,
+ not collidable, and are under the same TransformGroup
+ (after flattening) are combined, internally, into a single
+ Shape3D node that can be rendered with less overhead.
+
+ - State Sorted Rendering
+ Since Java 3D allows for unordered rendering for most leaf
+ nodes, the implementation sorts all objects to be rendered on
+ a number of rendering characteristics. The characteristics
+ that are sorted on are, in order, Lights, Texture, Geometry
+ Type, Material, and finally localToVworld transform. The only
+ 2 exceptions are to (a) any child of an OrderedGroup node, and
+ (b) any transparent object with View's Transparency sorting policy
+ set to TRANSPARENCY_SORT_GEOMETRY. There is no state sorting for
+ those objects.
+
+ - View Frustum Culling
+ The Java 3D implementation implements view frustum culling.
+ The view frustum cull is done when an object is processed for
+ a specific Canvas3D. This cuts down on the number of objects
+ needed to be processed by the low level graphics API.
+
+ - Multithreading
+ The Java 3D API was designed with multithreaded environments
+ in mind. The current implementation is a fully multithreaded
+ system. At any point in time, there may be parallel threads
+ running performing various tasks such as visibility detection,
+ rendering, behavior scheduling, sound scheduling, input
+ processing, collision detection, and others. Java 3D is
+ careful to limit the number of threads that can run in
+ parallel based on the number of CPUs available.
+
+ - Space versus time property
+ By default, Java3d only builds display list for by-copy geometry. If
+ an application wishes to have display list build for by-ref geometry
+ to improve performance at the expense of memory, it can instruct Java3d
+ by disable the j3d.optimizeForSpace property to false. For example :
+
+ java -Dj3d.optimizeForSpace=false MyProgram
+
+ This will cause Java3d to build display list for by-ref geometry and
+ infrequently changing geometry.
+ See also : Part II - isFrequent bits, and Part IV - Geometry by reference.
+
+
+IV - Tips and Tricks
+
+ This section presents a number of tips and tricks for an application
+programmer to try when optimizing their application. These tips focus on
+improving rendering frame rates, but some may also help overall application
+performance.
+
+ - Move Object vs. Move ViewPlatform
+ If the application simply needs to transform the entire scene,
+ transform the ViewPlatform instead. This changes the problem
+ from transforming every object in the scene into only
+ transforming the ViewPlatform.
+
+ - Capability bits
+ Only set them when needed. Many optimizations can be done
+ when they are not set. So, plan out application requirements
+ and only set the capability bits that are needed.
+
+ - Bounds and Activation Radius
+ Consider the spatial extent of various leaf nodes in the scene
+ and assign bounds accordingly. This allows the implementation
+ to prune processing on objects that are not in close
+ proximity. Note, this does not apply to Geometric bounds.
+ Automatic bounds calculations for geometric objects is fine.
+ In cases such as the influencing or scheduling bounds
+ encompass the entire scene graph, setting this bounds to
+ infinite bounds may help improve performance. Java3d will
+ shortcircuit intersection test on bounds with infinite
+ volume. A BoundingSphere is a infinite bounds if it's radius
+ is set to Double.POSITIVE_INFINITY. A BoundingBox is a
+ infinite bounds if it's lower(x, y, z) are set to
+ Double.NEGATIVE_INFINITY, and it's upper(x, y, z) are set
+ Double.POSITIVE_INFINITY.
+ Bounds computation does consume CPU cycles. If an application
+ does a lot of geometry coordinate updates, to improve
+ performance, it is better to turn off auto bounds compute. The
+ application will have to do the bounds update itself.
+
+ - Change Number of Shape3D Nodes
+ In the current implementation there is a certain amount of
+ fixed overhead associated with the use of the Shape3D node.
+ In general, the fewer Shape3D nodes that an application uses,
+ the better. However, combining Shape3D nodes without
+ factoring in the spatial locality of the nodes to be combined
+ can adversely effect performance by effectively disabling view
+ frustum culling. An application programmer will need to
+ experiment to find the right balance of combining Shape3D
+ nodes while leveraging view frustum culling. The .compile
+ optimization that combines shape node will do this
+ automatically, when possible.
+
+ - Geometry Type and Format
+ Most rendering hardware reaches peak performance when
+ rendering long triangle strips. Unfortunately, most geometry
+ data stored in files is organized as independent triangles or
+ small triangle fans (polygons). The Java 3D utility package
+ includes a stripifier utility that will try to convert a given
+ geometry type into long triangle strips. Application
+ programmers should experiment with the stripifier to see if it
+ helps with their specific data. If not, any stripification
+ that the application can do will help. Another option is that
+ most rendering hardware can process a long list of independent
+ triangles faster than a long list of single triangle triangle
+ fans. The stripifier in the Java 3D utility package will be
+ continually updated to provided better stripification.
+
+ - Sharing Appearance/Texture/Material NodeComponents
+ To assist the implementation in efficient state sorting, and
+ allow more shape nodes to be combined during compilation,
+ applications can help by sharing Appearance/Texture/Material
+ NodeComponent objects when possible.
+
+ - Geometry by reference
+ Using geometry by reference reduces the memory needed to store
+ a scene graph, since Java 3D avoids creating a copy in some
+ cases. However, using this features prevents Java 3D from
+ creating display lists (unless the scene graph is compiled),
+ so rendering performance can suffer in some cases. It is
+ appropriate if memory is a concern or if the geometry is
+ writable and may change frequently. The interleaved format
+ will perform better than the non-interleaved formats, and
+ should be used where possible. In by-reference mode, an
+ application should use arrays of native data types; referring
+ to TupleXX[] arrays should be avoided.
+ See also : Part III - Space versus time property.
+
+ - Texture by reference and Y-up
+ Using texture by reference and Y-up format may reduce the
+ memory needed to store a texture object, since Java 3D avoids
+ creating a copy in some cases. When a copy of the by-reference
+ data is made in Java3D, users should be aware that this case
+ will use twice as much memory as the by copy case. This is due
+ to the fact that Java3D internally makes a copy in addition to
+ the user's copy to the reference data. Currently, Java3D will not
+ make a copy of texture image for the following combinations of
+ BufferedImage format and ImageComponent format (byReference
+ and Yup should both be set to true):
+
+ On both Solaris and Win32 OpenGL:
+
+ BufferedImage.TYPE_CUSTOM ImageComponent.FORMAT_RGB8 or
+ of form 3BYTE_RGB ImageComponent.FORMAT_RGB
+
+ BufferedImage.TYPE_CUSTOM ImageComponent.FORMAT_RGBA8 or
+ of form 4BYTE_RGBA ImageComponent.FORMAT_RGBA
+
+ BufferedImage.TYPE_BYTE_GRAY ImageComponent.FORMAT_CHANNEL8
+
+ On Win32/OpenGL:
+
+ BufferedImage format ImageComponentFormat
+ ---------------------- ----------------------
+ BufferedImage.TYPE_3BYTE_BGR ImageComponent.FORMAT_RGB8 or
+ ImageComponent.FORMAT_RGB
+
+ On Solaris/OpenGL:
+
+ BufferedImage format ImageComponentFormat
+ ---------------------- ----------------------
+ BufferedImage.TYPE_4BYTE_ABGR ImageComponent.FORMAT_RGBA8 or
+ ImageComponent.FORMAT_RGBA
+
+ - Drawing 2D graphics using J3DGraphics2D
+ The J3DGraphics2D class allows you to mix 2D and 3D drawing
+ into the same window. However, this can be very slow in many
+ cases because Java 3D needs to buffer up all of the data and
+ then composite it into the back buffer of the Canvas3D. A new
+ method, drawAndFlushImage, is provided to accelerate the
+ drawing of 2D images into a Canvas3D. To use this, it is
+ recommended that an application create their own BufferedImage
+ of the desired size, use Java2D to render into their
+ BufferedImage, and then use the new drawAndFlushImage method
+ to draw the image into the Canvas3D.
+
+ This has the advantage of only compositing the minimum area
+ and, in some cases, can be done without making an extra copy
+ of the data. For the image to not be copied, this method must
+ be called within a Canvas3D callback, the specified
+ BufferedImage must be of the format
+ BufferedImage.TYPE_4BYTE_ABGR, and the GL_ABGR_EXT extension
+ must be supported by OpenGL. If these conditions are not met,
+ the image will be copied, and then flushed.
+
+ The following methods have also been optimized : all drawImage()
+ routines, drawRenderableImage(), draw(Shape s), fill(Shape s),
+ drawString(), drawLine() without strokeSet to copy only the
+ minimum affected region without the restriction imposed in
+ drawAndFlushImage method.
+
+ - Application Threads
+ The built in threads support in the Java language is very
+ powerful, but can be deadly to performance if it is not
+ controlled. Applications need to be very careful in their
+ threads usage. There are a few things to be careful of when
+ using Java threads. First, try to use them in a demand driven
+ fashion. Only let the thread run when it has a task to do.
+ Free running threads can take a lot of cpu cycles from the
+ rest of the threads in the system - including Java 3D threads.
+ Next, be sure the priority of the threads are appropriate.
+ Most Java Virtual Machines will enforce priorities
+ aggressively. Too low a priority will starve the thread and
+ too high a priority will starve the rest of the system. If in
+ doubt, use the default thread priority. Finally, see if the
+ application thread really needs to be a thread. Would the
+ task that the thread performs be all right if it only ran once
+ per frame? If so, consider changing the task to a Behavior
+ that wakes up each frame.
+
+ - Java 3D Threads
+ Java 3D uses many threads in its implementation, so it also
+ needs to implement the precautions listed above. In almost
+ all cases, Java 3D manages its threads efficiently. They are
+ demand driven with default priorities. There are a few cases
+ that don't follow these guidelines completely.
+
+ - Behaviors
+ One of these cases is the Behavior scheduler when there
+ are pending WakeupOnElapsedTime criteria. In this case,
+ it needs to wakeup when the minimum WakeupOnElapsedTime
+ criteria is about to expire. So, application use of
+ WakeupOnElapsedTime can cause the Behavior scheduler to
+ run more often than might be necessary.
+
+ - Sounds
+ The final special case for Java 3D threads is the Sound
+ subsystem. Due to some limitations in the current sound
+ rendering engine, enabling sounds cause the sound engine
+ to potentially run at a higher priority than other
+ threads. This may adversely effect performance.
+
+ - Threads in General
+ There is one last comment to make on threads is general.
+ Since Java 3D is a fully multithreaded system, applications
+ may see significant performance improvements by increasing the
+ number of CPUs in the system. For an application that does
+ strictly animation, then two CPUs should be sufficient. As
+ more features are added to the application (Sound, Collision,
+ etc.), more CPUs could be utilized.
+
+ - Switch Nodes for Occlusion Culling
+ If the application is a first person point of view
+ application, and the environment is well known, Switch nodes
+ may be used to implement simple occlusion culling. The
+ children of the switch node that are not currently visible may
+ be turned off. If the application has this kind of knowledge,
+ this can be a very useful technique.
+
+ - Switch Nodes for Animation
+ Most animation is accomplished by changing the transformations
+ that effect an object. If the animation is fairly simple and
+ repeatable, the flip-book trick can be used to display the
+ animation. Simply put all the animation frames under one
+ switch node and use a SwitchValueInterpolator on the switch
+ node. This increases memory consumption in favor of smooth
+ animations.
+
+ - OrderedGroup Nodes
+ OrderedGroup and its subclasses are not as high performing as
+ the unordered group nodes. They disable any state sorting
+ optimizations that are possible. If the application can find
+ alternative solutions, performance will improve.
+
+ - LOD Behaviors
+ For complex scenes, using LOD Behaviors can improve
+ performance by reducing geometry needed to render objects that
+ don't need high level of detail. This is another option that
+ increases memory consumption for faster render rates.
+
+ - Picking
+ If the application doesn't need the accuracy of geometry based
+ picking, use bounds based picking. For more accurate picking
+ and better picking performance, use PickRay instead of
+ PickCone/PickCylnder unless you need to pick line/point.
+ PickCanvas with a tolerance of 0 will use PickRay for picking.
+
+ - D3D user only
+ Using Quad with Polygon line mode is very slow. This is because
+ DirectX doesn't support Quad. Breaking down the Quad
+ into two triangles causes the the diagonal line to be displayed.
+ Instead Java 3D draws the polygon line and does the hidden surface
+ removal manually.
+
+ Automatic texture generation mode Eye Linear is slower
+ because D3D doesn't support this mode.