From: Christoph S. <c.s...@un...> - 2003-10-13 08:44:51
|
Just my five cents - if there is something like a developers manual for=20 Jmol, then texts like this one should go into it. Actually, I even think=20 they could be part of the user manual. Cheers, Chris --=20 Dr. Christoph Steinbeck (e-mail: c.s...@un...) Groupleader Junior Research Group for Applied Bioinformatics Cologne University BioInformatics Center (http://www.cubic.uni-koeln.de) Z=FClpicher Str. 47, 50674 Cologne Tel: +49(0)221-470-7426 Fax: +49 (0) 221-470-7786 What is man but that lofty spirit - that sense of enterprise. ... Kirk, "I, Mudd," stardate 4513.3.. Miguel wrote: >>is it normal that the rendering time about scales 1 to 1 with the >>window size? >=20 >=20 > Good observation >=20 >=20 >>would have thought that the rendering was mostly determined by >>the number of atoms on screen, instead of the number of pixels... >=20 >=20 > The short answer is 'Yes, it is linear' >=20 > The long answer is ... probably longer than you expected :-) >=20 > At this point, we are effectively not using *any* of the java graphics > routines. All the rendering of all the shapes is being done by our own > routines in our own code. This is necessary because the graphics > primitives need to pay attention to the z dimension (by using the > zBuffer) to decide whether or not a pixel should be painted. >=20 > The rendering cycle is triggered by a call to update()/paint() and can = be > broken down as follows: > 1. clear the offscreen buffer > 2. render the entire scene into the offscreen buffer > 3. draw the offscreen buffer to the screen >=20 > I am going to talk about the first and third steps, then come back to > the second step, because it is a bit more complicated and more interest= ing. >=20 > Step 1. Clearing the offscreen buffer > ------------------------------------- > The offscreen buffer is actually two buffers, a pixelBuffer and a > zBuffer. The pixelBuffer is an int[] which contains ARGB values for the > pixels. The zBuffer is a short[] which contains the current z-depth of > the associated pixel. >=20 > The size of these buffers is width*height of the current window. When > the window size changes the pixelBuffer and zBuffer get reallocated. >=20 > The process of clearing each of these arrays is simply filling them up > with the same value. Each entry in the the pixelBuffer is set to the AR= GB > value of the current background color. Each entry in the the zBuffer is > set to be 'infinitely far away'. >=20 > This is clearly a linear function of the array size ... if the > arrays are twice the size it will take twice as long to fill them up. >=20 > [The step of clearing these buffers not normally the dominant step in t= he > paint cycle. Nevertheless, the time is *not* insignificant. For a windo= w > 316x316 you have 100K pixels. So the pixelBuffer is 4x100K=3D400Kb and = the > zBuffer is 2x100K=3D200Kb. If the scene that you are rendering is a > wireframe image then you may only touch a few thousand of those pixels = ... > a few percent. But regardless of how few pixels are modified, you still > have to clear the entire pixelBuffer and zBuffer *every* paint cycle.] >=20 >=20 > Step 3. java.awt.Graphics.drawImage() > ------------------------------------- > After the scene is rendered, the entire pixelBuffer is sent to the > screen with one drawImage operation. The image is the exact size of the > screen, so there is no rescaling or clipping required. (The zBuffer is = not > involved at this point.) >=20 > Each pixel in the image must be picked up, probably manipulated a littl= e, > then transferred to video memory. Potentially some of this could be > offloaded to the video card. >=20 > This is clearly a linear operation depending upon the number of pixels = in > the image ... the size of our int[] pixelBuffer. >=20 > [This would seem to be a simple operation, and an important operation t= hat > would have received a lot of attention and optimization. Unfortunately,= my > impression is that the implementation on my Linux box is slow. I think > that within the jvm the image *must* be being copied more than once ... > and these images are 500Kb and up. Sun would probably place some of the > blame on X Windows, but I feel quite certain that Java is noticably slo= wer > than if I did an equivalent 'drawImage' operation from C code.] >=20 >=20 > Step 2. Scene Rendering > ----------------------- > So, the entire scene needs to get rendered into our int[] pixelBuffer. >=20 > The code must iterate over all of the graphics shapes (atoms, bonds, > labels, etc.). Each of these shapes generates a set of pixels. Each of > these pixels has <x,y,z> coordinates. The z coordinate of each these > pixels must be tested against the corresponding zBuffer entry at <x,y>.= If > this pixel is closer to the user than the current zBuffer entry then th= e > corresponding <x,y> value in the pixelBuffer is updated. >=20 > Even relatively small spheres and cylinders involve hundreds of pixels. > Each of these pixels needs to be tested against the current zBuffer val= ue > to see whether or not it is in front of the current pixel. And this is > where all the time is spent. >=20 > And you can convince yourself that this process is linear ... if the in= t[] > pixelBuffer is twice as big then we are going to generate twice as > many pixels and it will take twice as long to fill it up. >=20 > This by itself does *not* imply that all windows of the same size will > have the same rendering time. But one can easily see that for a given > configuration of graphics shapes, for a given scene, if you blow it up = to > twice the size then you will have twice as many pixels and it will take > twice as long to construct the same scene. >=20 > However, for our molecular models it probably *is* the case that the > rendering time is almost independent of the model (for a given renderin= g > style). Because of the auto-scaling, if you load up a model with only a > few atoms then you get a few big atoms. If you then load up a model wit= h > lots of atoms then you get lots of small atoms. But the 'percentage of > coverage' or 'pixel density' is probably about the same. >=20 > You get a much more profound effect if you change the size of the atoms= by > using 'spacefill on'. Because now you have dramatically increased the > pixel density of the scene and there is a lot more testing and setting = of > pixels at the bottoms of our iterators. >=20 >=20 > So, we have three steps. The first and third steps are clearly linear > functions of the size of the int[] pixelBuffer ... the window size. And= , > while the second step is more complicated, it also is linear. >=20 >=20 >=20 > One more thing to remember. If you make your window 2 times wider and 2 > times higher then you have made it 4 times as big. |