001: /*
002: * $Header: /cvs/j3dfly/J3dFly/src/org/jdesktop/j3dfly/utils/behaviors/PerfBehavior.java,v 1.2 2007/01/26 19:31:28 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is Java 3D(tm) Fly Through.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dfly.utils.behaviors;
019:
020: import javax.media.j3d.*;
021: import javax.vecmath.*;
022:
023: /**
024: * A performance measurment behavior. The behavior automatically calibrates
025: * itself so that the work in measuring performance does not itself impact
026: * performance.
027: *
028: * Performance information will be passed to a registered PerfBehaviorListener,
029: * if there is no listener then the frames per second will be printed to
030: * System.out
031: *
032: * The org.jdesktop.j3dfly.utils.gui.StatsDialog class provides a
033: * GUI Dialog which uses this behavior to display performance stats.
034: *
035: * @author Chien Yang, Paul Byrne
036: * @version 1.9, 01/18/02
037: */
038: public class PerfBehavior extends Behavior {
039: WakeupOnElapsedFrames FPSwakeup = new WakeupOnElapsedFrames(0);
040: private static final int numFramesToDiscard = 8;
041:
042: private boolean doCalibration = true;
043: private int discardedFrames = 0;
044: private int numframes = 0;
045: private int maxframes = 1;
046: private long currtime = 0;
047: private long lasttime = 0;
048: private long deltatime;
049: private boolean finiteLoop = false;
050: private int loop = 0;
051: private int loopCount = 6;
052:
053: private PerfBehaviorListener listener = null;
054:
055: /**
056: * Construct the Behavior
057: * The Scheduling bounds are set to inifinity
058: */
059: public PerfBehavior() {
060: setSchedulingBounds(new BoundingSphere(new Point3d(0, 0, 0),
061: Double.POSITIVE_INFINITY));
062: setEnable(true);
063: }
064:
065: /**
066: * Calibrate the behavior
067: */
068: public void calibrate() {
069: doCalibration = true;
070: discardedFrames = 0;
071: numframes = 0;
072: maxframes = 1;
073: currtime = 0;
074: lasttime = 0;
075: loop = 0;
076: loopCount = 6;
077: }
078:
079: /**
080: * Called by Java3D to initialize the behavior
081: */
082: public void initialize() {
083: // Set the trigger for the interpolator
084: wakeupOn(FPSwakeup);
085: }
086:
087: /**
088: * Add the listener which will be notified whenever the performance
089: * stats are updated.
090: *
091: * Current implementation only supports a single listener
092: */
093: public void addPerfBehaviorListener(PerfBehaviorListener listener) {
094: if (this .listener != null) {
095: throw new RuntimeException(
096: "Implementation only supports a single PerfListener");
097: }
098: this .listener = listener;
099: }
100:
101: /**
102: * Remove the PerfBehaviorListener
103: */
104: public void removePerfBehaviorListener(PerfBehaviorListener listener) {
105: if (this .listener == listener)
106: this .listener = null;
107: else
108: throw new RuntimeException(
109: "Trying to Remove listener which is not current");
110: }
111:
112: // Called every time the behavior is activated
113: public void processStimulus(java.util.Enumeration critera) {
114: // Apply Calibration Algorithm :
115: // To determine maxframes to run before sampling the time
116: // to determine frames per second.
117: // testduration = 10000 ,To run test pass for 10 seconds
118:
119: if (doCalibration) { // do the calibration
120: // Always throw away the next "N" frames *after* the first, dummy
121: // call to postSwap
122: if (discardedFrames <= numFramesToDiscard) {
123: if (false) {
124: if (discardedFrames == 0)
125: System.out
126: .println("postSwap: initial call discarded");
127: else
128: System.out.println("postSwap: frame #"
129: + discardedFrames + " discarded");
130: }
131:
132: discardedFrames += 1;
133: lasttime = System.currentTimeMillis();
134: } else {
135: numframes += 1;
136: //System.out.println(maxframes+" "+numframes+" "+lasttime+" ");
137: if (numframes >= maxframes) {
138: currtime = System.currentTimeMillis();
139: deltatime = currtime - lasttime;
140: //System.out.println("deltatime = " + deltatime +
141: // ", numframes = " + numframes);
142:
143: if (deltatime > 1000 && maxframes >= 8) {
144: maxframes = (int) Math.ceil((double) maxframes
145: * 1000 / (double) deltatime);
146: //System.out.println("maxframes = " + maxframes);
147:
148: // reset the value for the measurement
149: doCalibration = false;
150: numframes = 0;
151: lasttime = System.currentTimeMillis();
152: } else {
153: maxframes *= 2;
154: }
155: }
156: }
157: } else { // do the measurement
158: numframes += 1;
159: if (numframes >= maxframes) {
160: currtime = System.currentTimeMillis();
161: deltatime = currtime - lasttime;
162: double fps = (double) numframes
163: / ((double) deltatime / 1000.0d);
164: //System.out.println( numframes+" "+(deltatime/1000.0)+" "+fps);
165: if (listener != null) {
166: listener.updatePerformanceFigures((float) fps);
167: } else {
168: System.out.println("fps : " + fps);
169: }
170: if (finiteLoop) {
171: loop++;
172: if (loop >= loopCount)
173: System.exit(0);
174: }
175: lasttime = System.currentTimeMillis();
176: numframes = 0;
177: }
178: }
179:
180: // Set the trigger for the interpolator
181: wakeupOn(FPSwakeup);
182:
183: }
184: }
|