1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/gfx/PanningPerfAPI.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,123 @@ 1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +package org.mozilla.gecko.gfx; 1.10 + 1.11 +import org.mozilla.gecko.mozglue.RobocopTarget; 1.12 + 1.13 +import android.os.SystemClock; 1.14 +import android.util.Log; 1.15 + 1.16 +import java.util.ArrayList; 1.17 +import java.util.List; 1.18 + 1.19 +public class PanningPerfAPI { 1.20 + private static final String LOGTAG = "GeckoPanningPerfAPI"; 1.21 + 1.22 + // make this large enough to avoid having to resize the frame time 1.23 + // list, as that may be expensive and impact the thing we're trying 1.24 + // to measure. 1.25 + private static final int EXPECTED_FRAME_COUNT = 2048; 1.26 + 1.27 + private static boolean mRecordingFrames = false; 1.28 + private static List<Long> mFrameTimes; 1.29 + private static long mFrameStartTime; 1.30 + 1.31 + private static boolean mRecordingCheckerboard = false; 1.32 + private static List<Float> mCheckerboardAmounts; 1.33 + private static long mCheckerboardStartTime; 1.34 + 1.35 + private static void initialiseRecordingArrays() { 1.36 + if (mFrameTimes == null) { 1.37 + mFrameTimes = new ArrayList<Long>(EXPECTED_FRAME_COUNT); 1.38 + } else { 1.39 + mFrameTimes.clear(); 1.40 + } 1.41 + if (mCheckerboardAmounts == null) { 1.42 + mCheckerboardAmounts = new ArrayList<Float>(EXPECTED_FRAME_COUNT); 1.43 + } else { 1.44 + mCheckerboardAmounts.clear(); 1.45 + } 1.46 + } 1.47 + 1.48 + @RobocopTarget 1.49 + public static void startFrameTimeRecording() { 1.50 + if (mRecordingFrames || mRecordingCheckerboard) { 1.51 + Log.e(LOGTAG, "Error: startFrameTimeRecording() called while already recording!"); 1.52 + return; 1.53 + } 1.54 + mRecordingFrames = true; 1.55 + initialiseRecordingArrays(); 1.56 + mFrameStartTime = SystemClock.uptimeMillis(); 1.57 + } 1.58 + 1.59 + @RobocopTarget 1.60 + public static List<Long> stopFrameTimeRecording() { 1.61 + if (!mRecordingFrames) { 1.62 + Log.e(LOGTAG, "Error: stopFrameTimeRecording() called when not recording!"); 1.63 + return null; 1.64 + } 1.65 + mRecordingFrames = false; 1.66 + return mFrameTimes; 1.67 + } 1.68 + 1.69 + public static void recordFrameTime() { 1.70 + // this will be called often, so try to make it as quick as possible 1.71 + if (mRecordingFrames) { 1.72 + mFrameTimes.add(SystemClock.uptimeMillis() - mFrameStartTime); 1.73 + } 1.74 + } 1.75 + 1.76 + public static boolean isRecordingCheckerboard() { 1.77 + return mRecordingCheckerboard; 1.78 + } 1.79 + 1.80 + @RobocopTarget 1.81 + public static void startCheckerboardRecording() { 1.82 + if (mRecordingCheckerboard || mRecordingFrames) { 1.83 + Log.e(LOGTAG, "Error: startCheckerboardRecording() called while already recording!"); 1.84 + return; 1.85 + } 1.86 + mRecordingCheckerboard = true; 1.87 + initialiseRecordingArrays(); 1.88 + mCheckerboardStartTime = SystemClock.uptimeMillis(); 1.89 + } 1.90 + 1.91 + @RobocopTarget 1.92 + public static List<Float> stopCheckerboardRecording() { 1.93 + if (!mRecordingCheckerboard) { 1.94 + Log.e(LOGTAG, "Error: stopCheckerboardRecording() called when not recording!"); 1.95 + return null; 1.96 + } 1.97 + mRecordingCheckerboard = false; 1.98 + 1.99 + // We take the number of values in mCheckerboardAmounts here, as there's 1.100 + // the possibility that this function is called while recordCheckerboard 1.101 + // is still executing. As values are added to this list last, we use 1.102 + // this number as the canonical number of recordings. 1.103 + int values = mCheckerboardAmounts.size(); 1.104 + 1.105 + // The score will be the sum of all the values in mCheckerboardAmounts, 1.106 + // so weight the checkerboard values by time so that frame-rate and 1.107 + // run-length don't affect score. 1.108 + long lastTime = 0; 1.109 + float totalTime = mFrameTimes.get(values - 1); 1.110 + for (int i = 0; i < values; i++) { 1.111 + long elapsedTime = mFrameTimes.get(i) - lastTime; 1.112 + mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime); 1.113 + lastTime += elapsedTime; 1.114 + } 1.115 + 1.116 + return mCheckerboardAmounts; 1.117 + } 1.118 + 1.119 + public static void recordCheckerboard(float amount) { 1.120 + // this will be called often, so try to make it as quick as possible 1.121 + if (mRecordingCheckerboard) { 1.122 + mFrameTimes.add(SystemClock.uptimeMillis() - mCheckerboardStartTime); 1.123 + mCheckerboardAmounts.add(amount); 1.124 + } 1.125 + } 1.126 +}