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 #define __STDC_FORMAT_MACROS 1
32 #include <inttypes.h>
33
34 #include "profiler.h"
35
36 #ifdef DEBUG_CALC_FPS
37
38
39 ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::CalcFps) ;
40
41 namespace qdutils {
42
CalcFps()43 CalcFps::CalcFps() {
44 debug_fps_level = 0;
45 Init();
46 }
47
~CalcFps()48 CalcFps::~CalcFps() {
49 }
50
Init()51 void CalcFps::Init() {
52 char prop[PROPERTY_VALUE_MAX];
53 property_get("debug.gr.calcfps", prop, "0");
54 debug_fps_level = atoi(prop);
55 if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) {
56 ALOGW("out of range value for debug.gr.calcfps, using 0");
57 debug_fps_level = 0;
58 }
59
60 ALOGD("DEBUG_CALC_FPS: %d", debug_fps_level);
61 populate_debug_fps_metadata();
62 }
63
Fps()64 void CalcFps::Fps() {
65 if (debug_fps_level > 0)
66 calc_fps(ns2us(systemTime()));
67 }
68
populate_debug_fps_metadata(void)69 void CalcFps::populate_debug_fps_metadata(void)
70 {
71 char prop[PROPERTY_VALUE_MAX];
72
73 /*defaults calculation of fps to based on number of frames*/
74 property_get("debug.gr.calcfps.type", prop, "0");
75 debug_fps_metadata.type = (debug_fps_metadata_t::DfmType) atoi(prop);
76
77 /*defaults to 1000ms*/
78 property_get("debug.gr.calcfps.timeperiod", prop, "1000");
79 debug_fps_metadata.time_period = atoi(prop);
80
81 property_get("debug.gr.calcfps.period", prop, "10");
82 debug_fps_metadata.period = atoi(prop);
83
84 if (debug_fps_metadata.period > MAX_FPS_CALC_PERIOD_IN_FRAMES) {
85 debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES;
86 }
87
88 /* default ignorethresh_us: 500 milli seconds */
89 property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000");
90 debug_fps_metadata.ignorethresh_us = atoi(prop);
91
92 debug_fps_metadata.framearrival_steps =
93 (unsigned int)(debug_fps_metadata.ignorethresh_us / 16666);
94
95 if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) {
96 debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS;
97 debug_fps_metadata.ignorethresh_us =
98 debug_fps_metadata.framearrival_steps * 16666;
99 }
100
101 /* 2ms margin of error for the gettimeofday */
102 debug_fps_metadata.margin_us = 2000;
103
104 for (unsigned int i = 0; i < MAX_FRAMEARRIVAL_STEPS; i++)
105 debug_fps_metadata.accum_framearrivals[i] = 0;
106
107 debug_fps_metadata.curr_frame = 0;
108
109 ALOGD("period: %u", debug_fps_metadata.period);
110 ALOGD("ignorethresh_us: %" PRId64, debug_fps_metadata.ignorethresh_us);
111 }
112
print_fps(float fps)113 void CalcFps::print_fps(float fps)
114 {
115 if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type)
116 ALOGD("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
117 else
118 ALOGD("FPS for last (%f ms, %d frames): %3.2f",
119 debug_fps_metadata.time_elapsed,
120 debug_fps_metadata.curr_frame, fps);
121
122 debug_fps_metadata.curr_frame = 0;
123 debug_fps_metadata.time_elapsed = 0.0;
124
125 if (debug_fps_level > 1) {
126 ALOGD("Frame Arrival Distribution:");
127 for (unsigned int i = 0;
128 i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
129 i++) {
130 ALOGD("%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64,
131 debug_fps_metadata.accum_framearrivals[i*6],
132 debug_fps_metadata.accum_framearrivals[i*6+1],
133 debug_fps_metadata.accum_framearrivals[i*6+2],
134 debug_fps_metadata.accum_framearrivals[i*6+3],
135 debug_fps_metadata.accum_framearrivals[i*6+4],
136 debug_fps_metadata.accum_framearrivals[i*6+5]);
137 }
138
139 /* We are done with displaying, now clear the stats */
140 for (unsigned int i = 0;
141 i < debug_fps_metadata.framearrival_steps;
142 i++)
143 debug_fps_metadata.accum_framearrivals[i] = 0;
144 }
145 return;
146 }
147
calc_fps(nsecs_t currtime_us)148 void CalcFps::calc_fps(nsecs_t currtime_us)
149 {
150 static nsecs_t oldtime_us = 0;
151
152 nsecs_t diff = currtime_us - oldtime_us;
153
154 oldtime_us = currtime_us;
155
156 if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type &&
157 diff > debug_fps_metadata.ignorethresh_us) {
158 return;
159 }
160
161 if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
162 debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff;
163 }
164
165 debug_fps_metadata.curr_frame++;
166
167 if (debug_fps_level > 1) {
168 unsigned int currstep =
169 (unsigned int)(diff + debug_fps_metadata.margin_us) / 16666;
170
171 if (currstep < debug_fps_metadata.framearrival_steps) {
172 debug_fps_metadata.accum_framearrivals[currstep-1]++;
173 }
174 }
175
176 if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) {
177 if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) {
178 /* time to calculate and display FPS */
179 nsecs_t sum = 0;
180 for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
181 sum += debug_fps_metadata.framearrivals[i];
182 print_fps(float(float(debug_fps_metadata.period * 1000000) /
183 (float)sum));
184 }
185 }
186 else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
187 debug_fps_metadata.time_elapsed += (float)((float)diff/1000.0);
188 if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
189 float fps = float(1000.0 * debug_fps_metadata.curr_frame/
190 debug_fps_metadata.time_elapsed);
191 print_fps(fps);
192 }
193 }
194 return;
195 }
196 };//namespace qomutils
197 #endif
198