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