1 /* 2 * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #define LOG_NDDEBUG 0 31 #include "profiler.h" 32 33 #ifdef DEBUG_CALC_FPS 34 35 36 ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::CalcFps) ; 37 38 namespace qdutils { 39 40 CalcFps::CalcFps() { 41 debug_fps_level = 0; 42 Init(); 43 } 44 45 CalcFps::~CalcFps() { 46 } 47 48 void CalcFps::Init() { 49 char prop[PROPERTY_VALUE_MAX]; 50 property_get("debug.gr.calcfps", prop, "0"); 51 debug_fps_level = atoi(prop); 52 if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) { 53 ALOGW("out of range value for debug.gr.calcfps, using 0"); 54 debug_fps_level = 0; 55 } 56 57 ALOGD("DEBUG_CALC_FPS: %d", debug_fps_level); 58 populate_debug_fps_metadata(); 59 } 60 61 void CalcFps::Fps() { 62 if (debug_fps_level > 0) 63 calc_fps(ns2us(systemTime())); 64 } 65 66 void CalcFps::populate_debug_fps_metadata(void) 67 { 68 char prop[PROPERTY_VALUE_MAX]; 69 70 /*defaults calculation of fps to based on number of frames*/ 71 property_get("debug.gr.calcfps.type", prop, "0"); 72 debug_fps_metadata.type = (debug_fps_metadata_t::DfmType) atoi(prop); 73 74 /*defaults to 1000ms*/ 75 property_get("debug.gr.calcfps.timeperiod", prop, "1000"); 76 debug_fps_metadata.time_period = atoi(prop); 77 78 property_get("debug.gr.calcfps.period", prop, "10"); 79 debug_fps_metadata.period = atoi(prop); 80 81 if (debug_fps_metadata.period > MAX_FPS_CALC_PERIOD_IN_FRAMES) { 82 debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES; 83 } 84 85 /* default ignorethresh_us: 500 milli seconds */ 86 property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000"); 87 debug_fps_metadata.ignorethresh_us = atoi(prop); 88 89 debug_fps_metadata.framearrival_steps = 90 (debug_fps_metadata.ignorethresh_us / 16666); 91 92 if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) { 93 debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS; 94 debug_fps_metadata.ignorethresh_us = 95 debug_fps_metadata.framearrival_steps * 16666; 96 } 97 98 /* 2ms margin of error for the gettimeofday */ 99 debug_fps_metadata.margin_us = 2000; 100 101 for (unsigned int i = 0; i < MAX_FRAMEARRIVAL_STEPS; i++) 102 debug_fps_metadata.accum_framearrivals[i] = 0; 103 104 ALOGD("period: %d", debug_fps_metadata.period); 105 ALOGD("ignorethresh_us: %lld", debug_fps_metadata.ignorethresh_us); 106 } 107 108 void CalcFps::print_fps(float fps) 109 { 110 if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) 111 ALOGD("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps); 112 else 113 ALOGD("FPS for last (%f ms, %d frames): %3.2f", 114 debug_fps_metadata.time_elapsed, 115 debug_fps_metadata.curr_frame, fps); 116 117 debug_fps_metadata.curr_frame = 0; 118 debug_fps_metadata.time_elapsed = 0.0; 119 120 if (debug_fps_level > 1) { 121 ALOGD("Frame Arrival Distribution:"); 122 for (unsigned int i = 0; 123 i < ((debug_fps_metadata.framearrival_steps / 6) + 1); 124 i++) { 125 ALOGD("%lld %lld %lld %lld %lld %lld", 126 debug_fps_metadata.accum_framearrivals[i*6], 127 debug_fps_metadata.accum_framearrivals[i*6+1], 128 debug_fps_metadata.accum_framearrivals[i*6+2], 129 debug_fps_metadata.accum_framearrivals[i*6+3], 130 debug_fps_metadata.accum_framearrivals[i*6+4], 131 debug_fps_metadata.accum_framearrivals[i*6+5]); 132 } 133 134 /* We are done with displaying, now clear the stats */ 135 for (unsigned int i = 0; 136 i < debug_fps_metadata.framearrival_steps; 137 i++) 138 debug_fps_metadata.accum_framearrivals[i] = 0; 139 } 140 return; 141 } 142 143 void CalcFps::calc_fps(nsecs_t currtime_us) 144 { 145 static nsecs_t oldtime_us = 0; 146 147 nsecs_t diff = currtime_us - oldtime_us; 148 149 oldtime_us = currtime_us; 150 151 if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type && 152 diff > debug_fps_metadata.ignorethresh_us) { 153 return; 154 } 155 156 if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) { 157 debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff; 158 } 159 160 debug_fps_metadata.curr_frame++; 161 162 if (debug_fps_level > 1) { 163 unsigned int currstep = (diff + debug_fps_metadata.margin_us) / 16666; 164 165 if (currstep < debug_fps_metadata.framearrival_steps) { 166 debug_fps_metadata.accum_framearrivals[currstep-1]++; 167 } 168 } 169 170 if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) { 171 if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) { 172 /* time to calculate and display FPS */ 173 nsecs_t sum = 0; 174 for (unsigned int i = 0; i < debug_fps_metadata.period; i++) 175 sum += debug_fps_metadata.framearrivals[i]; 176 print_fps((debug_fps_metadata.period * float(1000000))/float(sum)); 177 } 178 } 179 else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) { 180 debug_fps_metadata.time_elapsed += ((float)diff/1000.0); 181 if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) { 182 float fps = (1000.0 * debug_fps_metadata.curr_frame)/ 183 (float)debug_fps_metadata.time_elapsed; 184 print_fps(fps); 185 } 186 } 187 return; 188 } 189 };//namespace qomutils 190 #endif 191