Last modified 16 years ago
Last modified on 08/31/09 11:31:02
Analysis
Overview
The goal of this task is to specify concrete design for the integration of the optimization ideas proposed in R0 and implement it. Most of the research was done in R0, we already have lots of code written with prototype implementations, now we'll write it clearly here and we'll have a nice demo for the sprint closing (:
Task requirements
- Algorithmic:
- develop and implement the ideas of a global tile cache described in the previous revision
- think about additional minor algoritmic optimizations
- remove obsolete properties in the scenes model, such as layer
- integrate the new logic in the project
- create a simple scene effect demonstration
- Hardware:
- Specify the needed jars and native libs and propose how to deal with their integration.
- Specify the compiler problems and propose how to solve them.
- Give a concrete design what new methods and classes will be added by the JOGL implementation of the Scenes and how they will be integrated.
- SimpleSceneDemo should work by only changing the used SceneVisual from SimpleSceneVisual to a new JoglSceneVisual. Some minor things might be different but it should work as a whole.
- Sophie should be able to run with the new implementation of the Scenes.
- Describe implementation and problems with the drawing of different ElementHelpers, most notably:
- HotTextElementHelper,
- ImageElementHelper,
- ShapeElementHelper,
- etc.
- Give some sort of explanation of the implementation because most people aren't familiar with OpenGL and JOGL requires in-depth knowledge for OpenGL. Links with resources and tutorials will be nice.
Task result
- Algorithmic:
- integration of the new scene logic in trunk
- a demo which shows a simple scene effect, for example a colour filter or a colour invert
- improved capability of scene drawing optimization utilizing sprites and tiles
- Hardware:
- Working SimpleSceneDemo with JOGL implementation.
- Working JOGL Scenes implementation integrated in the trunk.
- Some overall explanations of the JOGL implementation.
- Resources and tutorials for JOGL.
Implementation idea
- Algorithmic:
- improve and fully implement the design in the first revision of the task
- Hardware:
- use the newly found text rendering JOGL util lib for text
- use textures for ImageElementHelpers
- coordinate with Pav for the deployment issues of the natives.
Related
How to demo
- Algorithmic:
- run Sophie with simple scenes implementation
- run the scene effects demo
- Hardware:
- Show working SimpleSceneDemo,
- Run Sophie with the JOGL implementation
Design
- Algorithmic:
This revision stabilizes and improves the design of the previous one. Most of the changes are minor and were introduced for performance optimisation.- hashing
- Hash will not be an inner class for Hasher.
- Hasher will not aggregate a Hash object but will dublicate its state. Thus it will not be necessary to create a new Hash object every time a new entry is added which will make calculating hash values faster. A Hash object will be created only in the toHash() method.
- Most of the Hashable objects (especially sprites) will memoize their hash values.
- caching
- In QueryCache we will use LinkedHashMap instead of a simple HashMap. It will enable us to specify cache size and when the number of cache entries exceeds it, the least recently used entries will be deleted.
- inner representation of tiles - we are still looking for the best alternative.
- For each tile we can keep an array of integers representing its pixels (colors in ARGB format). We will have to write our own alpha composing function, color transformations and clipping operation. We hope that it will be faster than BufferedImage.
- The second option is to keep a BufferedImage for each tile and use its functions. It may prove that this is fast enough.
- Sprite fields:
- bounding rectangle - a rectangle that contains all points of the sprite
- space - a transformation matrix
- hash - memoized Hash code
- Sprite subclasses:
- ShapeSprite - sprite for filled shapes (ShapeSceneElements). It has a shape to fill and a filling to fill the shape with.
- ImageSprite - sprite for images. The only difference between ImageSprite and ShapeSprite with image as filling is that ImageSprite does not need a shape (it is determined by its space matrix only).
- ContourSprite - sprite for contour elements. It has an area and a line style (dashed or solid).
- ColorSprite - spite for color transformations. It multiplies all pixels of its source sprite by a given color.
- ClipSprite - sprite for clip effect. It limits the visible area of its source sprite.
- BlendSprite - sprite that combines two sprites in one. It has a static method that combines more than two sprites in one by constructing a binary tree of sprites. For now, the tree is almost a list, but it still enable us to reuse bottom tiles.
- http://sophie2.org/trac/browser/branches/private/deni/scenes?rev=4981
- hashing
- Hardware:
- Native stuff:
- This will be a pain in the ass. JOGL requires its own jars and native libs in order to function. Here you can find binaries and libraries for different platforms for the current stable release 1.1.1.
- My setup:
- Ubuntu 8.04 32 bit
- I use this download.
- I add the two jars as external libs in Eclipse
- My JDK dir is /usr/lib/jvm/jdk1.6.0_14/, so I put the four .so files in /usr/lib/jvm/jdk1.6.0_14/jre/lib/i386/. Something more clever must be thought of (:
- I've got no idea how this works under MacOSX or Windows. Something with Pav's build script must be done to get deployment right.
- There is also a compiler settings problem with these libraries. For every reference to these libs, you get a "Forbidden reference" error in Eclipse. This has to do something with Ganymede+ and some new policy. I guess that maybe using a later version of JOGL will be ok, I'm not sure. There is a JOGL 2.0 version but it's not stable yet. I guess I'll try using it in the next revision.
- The quick fix in Eclipse is to go to Windows->Preferences->Java->Compiler->Errors/Warnings->Deprecated And Restricted API and set the "Forbidden reference" field to "ignore" (: Currently I don't have a better solution to this problem.
- Real design stuff:
- I'll use the main.scene.jogl module finally
- Inside I'll create a JoglSceneVisual which will be analogical to SimpleSceneVisual but will provide a different swingComponent() which is OpenGL-powered. Actually it is called GLJPanel and is designed to have good integration with Swing.
- I'll provide an extension in the MainSceneJoglModule for this JoglSceneVisual.
- This new swingComponent will have a method analogical to paintComponent in the SimpleSceneVisual.ScenePanel component which will call a new method SceneHelper.paint(). This method won't have a Graphics2D as a parameter but a GLAutoDrawable which is the drawing surface in JOGL which I'll use.
- The new SceneHalper.paint(GLAutoDrawable ...) method will mimic the logic in the old SceneHelepr.paint(Graphics2D...) method but with JOGL draw primitives.
- The new SceneHalper.paint(GLAutoDrawable ...) will call a new ElementHelper.drawContent(GLAutoDrawable...) method which will mimic the old ElementHelper.drawContent(Graphics2D...) method but done with JOGL draw primitives.
- Each ElementHelper will have its own new implementation of this drawContent(GLAutoDrawable...) method.
- I'll need some util functions which I'll place in a SceneUtil class in org.sophie2.base.scene.util.
- There will be a transformation from an ImmMatrix to a float[16] representation, which is needed by OpenGL.
- There will be a helper method for loading and BufferedImage in memory and displaying it as a texture in OpenGL.
- I'll put some other minor helper functions there.
- More details on the implementation of different ElementHelpers:
- ShapeElementHelper / ContourElement:
- I'll iterate over the Shape boundary path and draw what's needed.
- ImageElementHelper:
- I'll convert the BufferedImage to a GL texture and span it over a rectangle in the Scene.
- (Hot)TextElementHelper:
- I'll reuse the existing implementation with Graphics2D - I'll create an off-screen BufferedImage, draw the text there and then treat it as an image.
- VideoElementHelper / AudioElementHelper:
- Will do them in next revision.
- CompositeelementHelper:
- Won't need any special treatment.
- SwingElementHelper:
- Won't implement it because we'll soon throw it away.
- ShapeElementHelper / ContourElement:
- I'll update SimpleSceneDemo and it should work like before by only changing the SceneVisual used. It now works like the original with some minor differences but ~10x faster.
- Sophie runs with the new implementation, though quite buggy and there are itnegration problems which I'll fix in the next revision.
- I already described some of the implementation details but here are some useful links:
- http://pepijn.fab4.be/software/nehe-java-ports/ -- the famous NeHe OpenGL lessons, ported to JOGL. Veeeeeery useful (:
- https://jogl-demos.dev.java.net/ -- a big pile of JOGL demos.
- http://ak.kiet.le.googlepages.com/theredbookinjava.html -- the RedBook in JOGL. Priceless (:
- I'll use the main.scene.jogl module finally
- This implementation is mostly visual, so no tests for now.
- Native stuff:
Implementation
(Describe and link the implementation results here (from the wiki or the repository).)
- The inner representation of tiles will be BufferedImage. This is easier to implement and use and turned out to be fast enough for now. The constructor with BufferedImage argument and the toBufferedImage() method do expose tiles' representation, but they are intended for inner use only and the performance is significantly better this way.
- The layer property in SceneElement was obsolete and was removed.
- The clip and color properties in SceneElement were also removed. Instead, clip and color effect were added.
- Since there are scene effects, such as clip, that change the visible and responsible area of the scene element, a new method was added to the SceneEffect interface - getResponsibleArea(ImmArea prevArea).
- The logic of finding the responsible element of a point in the scene (in Scene Helper) is slightly changed.
- The responsible area of a CompositeSceneElement is not empty, but at least the union of the responsible areas of all its subelements.
- Starting from the scene root element (which is responsible for the whole scene), we look for the last element in the tree responsible for the given point.
- The merge to the second_resource_refactoring branch was done with these revisions:
[5734], [5735], [5736], [5738]
- Some additional stuff was done, considerably more than the requirements of this task, but it's not cleared of warnings yet, so it will be documented in the next revision of this task.
Testing
(Place the testing results here.)
Comments
(Write comments for this or later revisions here.)