hardware/qcom/display: Add debug feature to display FPS for both bypass,fb

Change-Id: Ib4991200db9bc64c823c57ed1fba43f836142957
(cherry picked from commit cc57c2f34b936636e9c52dc43689d9386bcd0e35)

Conflicts:

	libgralloc/Android.mk
	libhwcomposer/Android.mk
	libqcomui/Android.mk
This commit is contained in:
Rajulu Ponnada
2012-01-19 22:53:50 -08:00
committed by Andrew Sutherland
parent 72aff33e3e
commit e17722b895
7 changed files with 237 additions and 194 deletions

4
libgralloc/Android.mk Executable file → Normal file
View File

@ -20,9 +20,11 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libutils libmemalloc
LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libutils libmemalloc libQcomUI
LOCAL_SHARED_LIBRARIES += libgenlock
LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock
LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
LOCAL_SRC_FILES := framebuffer.cpp \
gpu.cpp \
gralloc.cpp \

View File

@ -49,6 +49,8 @@
#include <cutils/properties.h>
#endif
#include <qcom_ui.h>
#define FB_DEBUG 0
#if defined(HDMI_DUAL_DISPLAY)
@ -79,50 +81,6 @@ static inline size_t ALIGN(size_t x, size_t align) {
char framebufferStateName[] = {'S', 'R', 'A'};
#ifdef DEBUG_CALC_FPS
#define MAX_FPS_CALC_PERIOD_IN_FRAMES 128
#define MAX_FRAMARRIVAL_STEPS 50
#define MAX_DEBUG_FPS_LEVEL 2
struct debug_fps_metadata_t {
/*fps calculation based on time or number of frames*/
enum DfmType {
DFM_FRAMES = 0,
DFM_TIME = 1,
};
DfmType type;
/* indicates how much time do we wait till we calculate FPS */
unsigned long time_period;
/*indicates how much time elapsed since we report fps*/
float time_elapsed;
/* indicates how many frames do we wait till we calculate FPS */
unsigned int period;
/* current frame, will go upto period, and then reset */
unsigned int curr_frame;
/* frame will arrive at a multiple of 16666 us at the display.
This indicates how many steps to consider for our calculations.
For example, if framearrival_steps = 10, then the frame that arrived
after 166660 us or more will be ignored.
*/
unsigned int framearrival_steps;
/* ignorethresh_us = framearrival_steps * 16666 */
nsecs_t ignorethresh_us;
/* used to calculate the actual frame arrival step, the times might not be
accurate
*/
unsigned int margin_us;
/* actual data storage */
nsecs_t framearrivals[MAX_FPS_CALC_PERIOD_IN_FRAMES];
nsecs_t accum_framearrivals[MAX_FRAMARRIVAL_STEPS];
};
#endif
/*****************************************************************************/
enum {
@ -144,11 +102,6 @@ struct fb_context_t {
static int neworientation;
#ifdef DEBUG_CALC_FPS
static debug_fps_metadata_t debug_fps_metadata;
static unsigned int debug_fps_level = 0;
#endif
/*****************************************************************************/
static void
@ -189,132 +142,6 @@ static int fb_setUpdateRect(struct framebuffer_device_t* dev,
return 0;
}
#ifdef DEBUG_CALC_FPS
static void populate_debug_fps_metadata(void)
{
char prop[PROPERTY_VALUE_MAX];
/*defaults calculation of fps to based on number of frames*/
property_get("debug.gr.calcfps.type", prop, "0");
debug_fps_metadata.type = (debug_fps_metadata_t::DfmType) atoi(prop);
/*defaults to 1000ms*/
property_get("debug.gr.calcfps.timeperiod", prop, "1000");
debug_fps_metadata.time_period = atoi(prop);
property_get("debug.gr.calcfps.period", prop, "10");
debug_fps_metadata.period = atoi(prop);
if (debug_fps_metadata.period > MAX_FPS_CALC_PERIOD_IN_FRAMES) {
debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES;
}
/* default ignorethresh_us: 500 milli seconds */
property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000");
debug_fps_metadata.ignorethresh_us = atoi(prop);
debug_fps_metadata.framearrival_steps =
(debug_fps_metadata.ignorethresh_us / 16666);
if (debug_fps_metadata.framearrival_steps > MAX_FRAMARRIVAL_STEPS) {
debug_fps_metadata.framearrival_steps = MAX_FRAMARRIVAL_STEPS;
debug_fps_metadata.ignorethresh_us =
debug_fps_metadata.framearrival_steps * 16666;
}
/* 2ms margin of error for the gettimeofday */
debug_fps_metadata.margin_us = 2000;
for (int i = 0; i < MAX_FRAMARRIVAL_STEPS; i++)
debug_fps_metadata.accum_framearrivals[i] = 0;
LOGE("period: %d", debug_fps_metadata.period);
LOGE("ignorethresh_us: %lld", debug_fps_metadata.ignorethresh_us);
}
static void print_fps(float fps)
{
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type)
LOGE("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
else
LOGE("FPS for last (%f ms, %d frames): %3.2f",
debug_fps_metadata.time_elapsed,
debug_fps_metadata.curr_frame, fps);
debug_fps_metadata.curr_frame = 0;
debug_fps_metadata.time_elapsed = 0.0;
if (debug_fps_level > 1) {
LOGE("Frame Arrival Distribution:");
for (unsigned int i = 0;
i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
i++) {
LOGE("%lld %lld %lld %lld %lld %lld",
debug_fps_metadata.accum_framearrivals[i*6],
debug_fps_metadata.accum_framearrivals[i*6+1],
debug_fps_metadata.accum_framearrivals[i*6+2],
debug_fps_metadata.accum_framearrivals[i*6+3],
debug_fps_metadata.accum_framearrivals[i*6+4],
debug_fps_metadata.accum_framearrivals[i*6+5]);
}
/* We are done with displaying, now clear the stats */
for (unsigned int i = 0;
i < debug_fps_metadata.framearrival_steps;
i++)
debug_fps_metadata.accum_framearrivals[i] = 0;
}
return;
}
static void calc_fps(nsecs_t currtime_us)
{
static nsecs_t oldtime_us = 0;
nsecs_t diff = currtime_us - oldtime_us;
oldtime_us = currtime_us;
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type &&
diff > debug_fps_metadata.ignorethresh_us) {
return;
}
if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame++] = diff;
}
if (debug_fps_level > 1) {
unsigned int currstep = (diff + debug_fps_metadata.margin_us) / 16666;
if (currstep < debug_fps_metadata.framearrival_steps) {
debug_fps_metadata.accum_framearrivals[currstep-1]++;
}
}
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) {
if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) {
/* time to calculate and display FPS */
nsecs_t sum = 0;
for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
sum += debug_fps_metadata.framearrivals[i];
print_fps((debug_fps_metadata.period * float(1000000))/float(sum));
}
}
else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
debug_fps_metadata.time_elapsed += ((float)diff/1000.0);
if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
float fps = (1000.0 * debug_fps_metadata.curr_frame)/
(float)debug_fps_metadata.time_elapsed;
print_fps(fps);
}
}
return;
}
#endif // DEBUG_CALC_FPS
static void *disp_loop(void *ptr)
{
struct qbuf_t nxtBuf;
@ -360,10 +187,7 @@ static void *disp_loop(void *ptr)
pthread_cond_signal(&m->bufferPostCond);
pthread_mutex_unlock(&m->bufferPostLock);
#endif
#ifdef DEBUG_CALC_FPS
if (debug_fps_level > 0) calc_fps(ns2us(systemTime()));
#endif
CALC_FPS();
if (cur_buf == -1) {
int nxtAvail = ((nxtBuf.idx + 1) % m->numBuffers);
@ -972,18 +796,7 @@ int mapFrameBufferLocked(struct private_module_t* module)
module->swapInterval = 1;
#endif
#ifdef DEBUG_CALC_FPS
char prop[PROPERTY_VALUE_MAX];
property_get("debug.gr.calcfps", prop, "0");
debug_fps_level = atoi(prop);
if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) {
LOGW("out of range value for debug.gr.calcfps, using 0");
debug_fps_level = 0;
}
LOGE("DEBUG_CALC_FPS: %d", debug_fps_level);
populate_debug_fps_metadata();
#endif
CALC_INIT();
module->currentIdx = -1;
pthread_cond_init(&(module->qpost), NULL);

4
libhwcomposer/Android.mk Executable file → Normal file
View File

@ -6,13 +6,13 @@ include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL libhardware libutils liboverlay
LOCAL_SHARED_LIBRARIES += libgenlock libui
LOCAL_SHARED_LIBRARIES += libgenlock libui libQcomUI
LOCAL_SRC_FILES := \
hwcomposer.cpp
LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\"
LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\" -DDEBUG_CALC_FPS
LOCAL_CFLAGS += -DQCOM_HARDWARE
LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc

5
libhwcomposer/hwcomposer.cpp Executable file → Normal file
View File

@ -1256,6 +1256,9 @@ static int hwc_set(hwc_composer_device_t *dev,
LOGE("eglSwapBuffers() failed in %s", __FUNCTION__);
}
}
else {
CALC_FPS();
}
#ifdef COMPOSITION_BYPASS
if(ctx->bypassState == BYPASS_OFF_PENDING) {
//Close channels only after fb content is displayed.
@ -1367,6 +1370,8 @@ static int hwc_module_initialize(struct private_hwc_module_t* hwcModule)
}
}
CALC_INIT();
return 0;
}

View File

@ -19,6 +19,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES := $(TOP)/hardware/qcom/display/libgralloc \
LOCAL_CFLAGS := -DLOG_TAG=\"libQcomUI\"
LOCAL_CFLAGS += -DQCOM_HARDWARE
LOCAL_CFLAGS += -DDEBUG_CALC_FPS
LOCAL_MODULE := libQcomUI
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

View File

@ -477,3 +477,156 @@ int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur)
return 0;
}
#ifdef DEBUG_CALC_FPS
ANDROID_SINGLETON_STATIC_INSTANCE(CalcFps) ;
CalcFps::CalcFps() {
debug_fps_level = 0;
Init();
}
CalcFps::~CalcFps() {
}
void CalcFps::Init() {
char prop[PROPERTY_VALUE_MAX];
property_get("debug.gr.calcfps", prop, "0");
debug_fps_level = atoi(prop);
if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) {
LOGW("out of range value for debug.gr.calcfps, using 0");
debug_fps_level = 0;
}
LOGE("DEBUG_CALC_FPS: %d", debug_fps_level);
populate_debug_fps_metadata();
}
void CalcFps::Fps() {
if (debug_fps_level > 0)
calc_fps(ns2us(systemTime()));
}
void CalcFps::populate_debug_fps_metadata(void)
{
char prop[PROPERTY_VALUE_MAX];
/*defaults calculation of fps to based on number of frames*/
property_get("debug.gr.calcfps.type", prop, "0");
debug_fps_metadata.type = (debug_fps_metadata_t::DfmType) atoi(prop);
/*defaults to 1000ms*/
property_get("debug.gr.calcfps.timeperiod", prop, "1000");
debug_fps_metadata.time_period = atoi(prop);
property_get("debug.gr.calcfps.period", prop, "10");
debug_fps_metadata.period = atoi(prop);
if (debug_fps_metadata.period > MAX_FPS_CALC_PERIOD_IN_FRAMES) {
debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES;
}
/* default ignorethresh_us: 500 milli seconds */
property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000");
debug_fps_metadata.ignorethresh_us = atoi(prop);
debug_fps_metadata.framearrival_steps =
(debug_fps_metadata.ignorethresh_us / 16666);
if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) {
debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS;
debug_fps_metadata.ignorethresh_us =
debug_fps_metadata.framearrival_steps * 16666;
}
/* 2ms margin of error for the gettimeofday */
debug_fps_metadata.margin_us = 2000;
for (unsigned int i = 0; i < MAX_FRAMEARRIVAL_STEPS; i++)
debug_fps_metadata.accum_framearrivals[i] = 0;
LOGE("period: %d", debug_fps_metadata.period);
LOGE("ignorethresh_us: %lld", debug_fps_metadata.ignorethresh_us);
}
void CalcFps::print_fps(float fps)
{
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type)
LOGE("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
else
LOGE("FPS for last (%f ms, %d frames): %3.2f",
debug_fps_metadata.time_elapsed,
debug_fps_metadata.curr_frame, fps);
debug_fps_metadata.curr_frame = 0;
debug_fps_metadata.time_elapsed = 0.0;
if (debug_fps_level > 1) {
LOGE("Frame Arrival Distribution:");
for (unsigned int i = 0;
i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
i++) {
LOGE("%lld %lld %lld %lld %lld %lld",
debug_fps_metadata.accum_framearrivals[i*6],
debug_fps_metadata.accum_framearrivals[i*6+1],
debug_fps_metadata.accum_framearrivals[i*6+2],
debug_fps_metadata.accum_framearrivals[i*6+3],
debug_fps_metadata.accum_framearrivals[i*6+4],
debug_fps_metadata.accum_framearrivals[i*6+5]);
}
/* We are done with displaying, now clear the stats */
for (unsigned int i = 0;
i < debug_fps_metadata.framearrival_steps;
i++)
debug_fps_metadata.accum_framearrivals[i] = 0;
}
return;
}
void CalcFps::calc_fps(nsecs_t currtime_us)
{
static nsecs_t oldtime_us = 0;
nsecs_t diff = currtime_us - oldtime_us;
oldtime_us = currtime_us;
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type &&
diff > debug_fps_metadata.ignorethresh_us) {
return;
}
if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff;
}
debug_fps_metadata.curr_frame++;
if (debug_fps_level > 1) {
unsigned int currstep = (diff + debug_fps_metadata.margin_us) / 16666;
if (currstep < debug_fps_metadata.framearrival_steps) {
debug_fps_metadata.accum_framearrivals[currstep-1]++;
}
}
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) {
if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) {
/* time to calculate and display FPS */
nsecs_t sum = 0;
for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
sum += debug_fps_metadata.framearrivals[i];
print_fps((debug_fps_metadata.period * float(1000000))/float(sum));
}
}
else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
debug_fps_metadata.time_elapsed += ((float)diff/1000.0);
if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
float fps = (1000.0 * debug_fps_metadata.curr_frame)/
(float)debug_fps_metadata.time_elapsed;
print_fps(fps);
}
}
return;
}
#endif

View File

@ -35,6 +35,7 @@
#include <hardware/hwcomposer.h>
#include <ui/Region.h>
#include <EGL/egl.h>
#include <utils/Singleton.h>
using namespace android;
using android::sp;
@ -101,6 +102,74 @@ struct qBufGeometry {
}
};
#ifndef DEBUG_CALC_FPS
#define CALC_FPS() ((void)0)
#define CALC_INIT() ((void)0)
#else
#define CALC_FPS() CalcFps::getInstance().Fps()
#define CALC_INIT() CalcFps::getInstance().Init()
class CalcFps : public Singleton<CalcFps> {
public:
CalcFps();
~CalcFps();
void Init();
void Fps();
private:
static const unsigned int MAX_FPS_CALC_PERIOD_IN_FRAMES = 128;
static const unsigned int MAX_FRAMEARRIVAL_STEPS = 50;
static const unsigned int MAX_DEBUG_FPS_LEVEL = 2;
struct debug_fps_metadata_t {
/*fps calculation based on time or number of frames*/
enum DfmType {
DFM_FRAMES = 0,
DFM_TIME = 1,
};
DfmType type;
/* indicates how much time do we wait till we calculate FPS */
unsigned long time_period;
/*indicates how much time elapsed since we report fps*/
float time_elapsed;
/* indicates how many frames do we wait till we calculate FPS */
unsigned int period;
/* current frame, will go upto period, and then reset */
unsigned int curr_frame;
/* frame will arrive at a multiple of 16666 us at the display.
This indicates how many steps to consider for our calculations.
For example, if framearrival_steps = 10, then the frame that arrived
after 166660 us or more will be ignored.
*/
unsigned int framearrival_steps;
/* ignorethresh_us = framearrival_steps * 16666 */
nsecs_t ignorethresh_us;
/* used to calculate the actual frame arrival step, the times might not be
accurate
*/
unsigned int margin_us;
/* actual data storage */
nsecs_t framearrivals[MAX_FPS_CALC_PERIOD_IN_FRAMES];
nsecs_t accum_framearrivals[MAX_FRAMEARRIVAL_STEPS];
};
private:
void populate_debug_fps_metadata(void);
void print_fps(float fps);
void calc_fps(nsecs_t currtime_us);
private:
debug_fps_metadata_t debug_fps_metadata;
unsigned int debug_fps_level;
};
#endif
/*
* Function to check if the allocated buffer is of the correct size.
* Reallocate the buffer with the correct size, if the size doesn't