1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package com.jme3.renderer; 34 35 import com.jme3.scene.Mesh; 36 import com.jme3.shader.Shader; 37 import com.jme3.texture.FrameBuffer; 38 import com.jme3.texture.Image; 39 import java.util.HashSet; 40 41 /** 42 * The statistics class allows tracking of real-time rendering statistics. 43 * <p> 44 * The <code>Statistics</code> can be retrieved by using {@link Renderer#getStatistics() }. 45 * 46 * @author Kirill Vainer 47 */ 48 public class Statistics { 49 50 protected int numObjects; 51 protected int numTriangles; 52 protected int numVertices; 53 protected int numShaderSwitches; 54 protected int numTextureBinds; 55 protected int numFboSwitches; 56 protected int numUniformsSet; 57 58 protected int memoryShaders; 59 protected int memoryFrameBuffers; 60 protected int memoryTextures; 61 62 protected HashSet<Integer> shadersUsed = new HashSet<Integer>(); 63 protected HashSet<Integer> texturesUsed = new HashSet<Integer>(); 64 protected HashSet<Integer> fbosUsed = new HashSet<Integer>(); 65 66 /** 67 * Returns a list of labels corresponding to each statistic. 68 * 69 * @return a list of labels corresponding to each statistic. 70 * 71 * @see #getData(int[]) 72 */ getLabels()73 public String[] getLabels(){ 74 return new String[]{ "Vertices", 75 "Triangles", 76 "Uniforms", 77 78 "Objects", 79 80 "Shaders (S)", 81 "Shaders (F)", 82 "Shaders (M)", 83 84 "Textures (S)", 85 "Textures (F)", 86 "Textures (M)", 87 88 "FrameBuffers (S)", 89 "FrameBuffers (F)", 90 "FrameBuffers (M)" }; 91 92 } 93 94 /** 95 * Retrieves the statistics data into the given array. 96 * The array should be as large as the array given in 97 * {@link #getLabels() }. 98 * 99 * @param data The data array to write to 100 */ getData(int[] data)101 public void getData(int[] data){ 102 data[0] = numVertices; 103 data[1] = numTriangles; 104 data[2] = numUniformsSet; 105 data[3] = numObjects; 106 107 data[4] = numShaderSwitches; 108 data[5] = shadersUsed.size(); 109 data[6] = memoryShaders; 110 111 data[7] = numTextureBinds; 112 data[8] = texturesUsed.size(); 113 data[9] = memoryTextures; 114 115 data[10] = numFboSwitches; 116 data[11] = fbosUsed.size(); 117 data[12] = memoryFrameBuffers; 118 } 119 120 /** 121 * Called by the Renderer when a mesh has been drawn. 122 * 123 */ onMeshDrawn(Mesh mesh, int lod)124 public void onMeshDrawn(Mesh mesh, int lod){ 125 numObjects ++; 126 numTriangles += mesh.getTriangleCount(lod); 127 numVertices += mesh.getVertexCount(); 128 } 129 130 /** 131 * Called by the Renderer when a shader has been utilized. 132 * 133 * @param shader The shader that was used 134 * @param wasSwitched If true, the shader has required a state switch 135 */ onShaderUse(Shader shader, boolean wasSwitched)136 public void onShaderUse(Shader shader, boolean wasSwitched){ 137 assert shader.getId() >= 1; 138 139 if (!shadersUsed.contains(shader.getId())) 140 shadersUsed.add(shader.getId()); 141 142 if (wasSwitched) 143 numShaderSwitches++; 144 } 145 146 /** 147 * Called by the Renderer when a uniform was set. 148 */ onUniformSet()149 public void onUniformSet(){ 150 numUniformsSet ++; 151 } 152 153 /** 154 * Called by the Renderer when a texture has been set. 155 * 156 * @param image The image that was set 157 * @param wasSwitched If true, the texture has required a state switch 158 */ onTextureUse(Image image, boolean wasSwitched)159 public void onTextureUse(Image image, boolean wasSwitched){ 160 assert image.getId() >= 1; 161 162 if (!texturesUsed.contains(image.getId())) 163 texturesUsed.add(image.getId()); 164 165 if (wasSwitched) 166 numTextureBinds ++; 167 } 168 169 /** 170 * Called by the Renderer when a framebuffer has been set. 171 * 172 * @param fb The framebuffer that was set 173 * @param wasSwitched If true, the framebuffer required a state switch 174 */ onFrameBufferUse(FrameBuffer fb, boolean wasSwitched)175 public void onFrameBufferUse(FrameBuffer fb, boolean wasSwitched){ 176 if (fb != null){ 177 assert fb.getId() >= 1; 178 179 if (!fbosUsed.contains(fb.getId())) 180 fbosUsed.add(fb.getId()); 181 } 182 183 if (wasSwitched) 184 numFboSwitches ++; 185 } 186 187 /** 188 * Clears all frame-specific statistics such as objects used per frame. 189 */ clearFrame()190 public void clearFrame(){ 191 shadersUsed.clear(); 192 texturesUsed.clear(); 193 fbosUsed.clear(); 194 195 numObjects = 0; 196 numTriangles = 0; 197 numVertices = 0; 198 numShaderSwitches = 0; 199 numTextureBinds = 0; 200 numFboSwitches = 0; 201 numUniformsSet = 0; 202 } 203 204 /** 205 * Called by the Renderer when it creates a new shader 206 */ onNewShader()207 public void onNewShader(){ 208 memoryShaders ++; 209 } 210 211 /** 212 * Called by the Renderer when it creates a new texture 213 */ onNewTexture()214 public void onNewTexture(){ 215 memoryTextures ++; 216 } 217 218 /** 219 * Called by the Renderer when it creates a new framebuffer 220 */ onNewFrameBuffer()221 public void onNewFrameBuffer(){ 222 memoryFrameBuffers ++; 223 } 224 225 /** 226 * Called by the Renderer when it deletes a shader 227 */ onDeleteShader()228 public void onDeleteShader(){ 229 memoryShaders --; 230 } 231 232 /** 233 * Called by the Renderer when it deletes a texture 234 */ onDeleteTexture()235 public void onDeleteTexture(){ 236 memoryTextures --; 237 } 238 239 /** 240 * Called by the Renderer when it deletes a framebuffer 241 */ onDeleteFrameBuffer()242 public void onDeleteFrameBuffer(){ 243 memoryFrameBuffers --; 244 } 245 246 /** 247 * Called when video memory is cleared. 248 */ clearMemory()249 public void clearMemory(){ 250 memoryFrameBuffers = 0; 251 memoryShaders = 0; 252 memoryTextures = 0; 253 } 254 255 } 256