qcom/display: Update HALs
- Update the display HAL from Code Aurora Forum
- Add updated overlay library
- Enable HWC with basic video going through overlay
- Cleanup some files
Change-Id: I65c687c51be458cee71213c79e03eeda962d9086
diff --git a/libqcomui/Android.mk b/libqcomui/Android.mk
index deb868c..d79929e 100644
--- a/libqcomui/Android.mk
+++ b/libqcomui/Android.mk
@@ -1,19 +1,19 @@
LOCAL_PATH := $(call my-dir)
+
+#Headers to export
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
- qcom_ui.cpp
+LOCAL_SRC_FILES := qcomutils/profiler.cpp \
+ qcomutils/IdleInvalidator.cpp
LOCAL_SHARED_LIBRARIES := \
libutils \
libcutils \
libui \
- libEGL
+ libEGL \
-LOCAL_C_INCLUDES := $(TOP)/hardware/qcom/display/libgralloc \
- $(TOP)/frameworks/native/services/surfaceflinger \
- $(TOP)/external/skia/include/core \
- $(TOP)/external/skia/include/images
+LOCAL_C_INCLUDES := hardware/qcom/display/libgralloc \
+ frameworks/base/services/surfaceflinger \
LOCAL_CFLAGS := -DLOG_TAG=\"libQcomUI\"
@@ -23,6 +23,10 @@
LOCAL_SHARED_LIBRARIES += libmemalloc
endif
+ifeq ($(TARGET_USES_MDP3), true)
+ LOCAL_CFLAGS += -DUSE_MDP3
+endif
+
LOCAL_CFLAGS += -DDEBUG_CALC_FPS
LOCAL_MODULE := libQcomUI
diff --git a/libqcomui/qcom_ui.cpp b/libqcomui/qcom_ui.cpp
index 9fdd562..d060439 100644
--- a/libqcomui/qcom_ui.cpp
+++ b/libqcomui/qcom_ui.cpp
@@ -30,86 +30,78 @@
#include <cutils/log.h>
#include <cutils/memory.h>
#include <qcom_ui.h>
+#include <utils/comptype.h>
#include <gralloc_priv.h>
#include <alloc_controller.h>
#include <memalloc.h>
#include <errno.h>
#include <EGL/eglext.h>
#include <sys/stat.h>
-#if 0
#include <SkBitmap.h>
#include <SkImageEncoder.h>
-#endif
#include <Transform.h>
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
using gralloc::IMemAlloc;
using gralloc::IonController;
using gralloc::alloc_data;
using android::sp;
-
-static int sCompositionType = -1;
-
namespace {
- static android::sp<gralloc::IAllocController> sAlloc = 0;
+static android::sp<gralloc::IAllocController> sAlloc = 0;
- int reallocate_memory(native_handle_t *buffer_handle, int mReqSize, int usage)
- {
- int ret = 0;
+int reallocate_memory(native_handle_t *buffer_handle, int mReqSize, int usage)
+{
+ int ret = 0;
#ifndef NON_QCOM_TARGET
- if (sAlloc == 0) {
- sAlloc = gralloc::IAllocController::getInstance(true);
- }
- if (sAlloc == 0) {
- ALOGE("sAlloc is still NULL");
- return -EINVAL;
- }
-
- // Dealloc the old memory
- private_handle_t *hnd = (private_handle_t *)buffer_handle;
- sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
- ret = memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
-
- if (ret) {
- ALOGE("%s: free_buffer failed", __FUNCTION__);
- return -1;
- }
-
- // Realloc new memory
- alloc_data data;
- data.base = 0;
- data.fd = -1;
- data.offset = 0;
- data.size = mReqSize;
- data.align = getpagesize();
- data.uncached = true;
- int allocFlags = usage;
-
- switch (hnd->format) {
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- case (HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED^HAL_PIXEL_FORMAT_INTERLACE): {
- data.align = 8192;
- } break;
- default: break;
- }
- ret = sAlloc->allocate(data, allocFlags, 0);
- if (ret == 0) {
- hnd->fd = data.fd;
- hnd->base = (int)data.base;
- hnd->offset = data.offset;
- hnd->size = data.size;
- } else {
- ALOGE("%s: allocate failed", __FUNCTION__);
- return -EINVAL;
- }
-#endif
- return ret;
+ if (sAlloc == 0) {
+ sAlloc = gralloc::IAllocController::getInstance(true);
}
+ if (sAlloc == 0) {
+ LOGE("sAlloc is still NULL");
+ return -EINVAL;
+ }
+
+ // Dealloc the old memory
+ private_handle_t *hnd = (private_handle_t *)buffer_handle;
+ sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
+ ret = memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
+
+ if (ret) {
+ LOGE("%s: free_buffer failed", __FUNCTION__);
+ return -1;
+ }
+
+ // Realloc new memory
+ alloc_data data;
+ data.base = 0;
+ data.fd = -1;
+ data.offset = 0;
+ data.size = mReqSize;
+ data.align = getpagesize();
+ data.uncached = true;
+ int allocFlags = usage;
+
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ case (HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED^HAL_PIXEL_FORMAT_INTERLACE): {
+ data.align = 8192;
+ } break;
+ default: break;
+ }
+ ret = sAlloc->allocate(data, allocFlags, 0);
+ if (ret == 0) {
+ hnd->fd = data.fd;
+ hnd->base = (int)data.base;
+ hnd->offset = data.offset;
+ hnd->size = data.size;
+ } else {
+ LOGE("%s: allocate failed", __FUNCTION__);
+ return -EINVAL;
+ }
+#endif
+ return ret;
+}
}; // ANONYNMOUS NAMESPACE
/*
@@ -128,8 +120,11 @@
case NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY:
num_args = 3;
break;
- default: ALOGE("%s: invalid operation(0x%x)", __FUNCTION__, operation);
+ case NATIVE_WINDOW_SET_PIXEL_ASPECT_RATIO:
+ num_args = 2;
break;
+ default: LOGE("%s: invalid operation(0x%x)", __FUNCTION__, operation);
+ break;
};
return num_args;
}
@@ -146,43 +141,20 @@
// We check the YV12 formats, since some Qcom specific formats
// could have the bits set.
return true;
+ } else if ((format == HAL_PIXEL_FORMAT_RGB_888) ||
+ (format == HAL_PIXEL_FORMAT_YCrCb_422_SP) ||
+ (format == HAL_PIXEL_FORMAT_YCbCr_422_SP)){
+ return false;
} else if (format & INTERLACE_MASK) {
// Interlaced content
return false;
} else if (format & S3D_FORMAT_MASK) {
// S3D Formats are not supported by the GPU
- return false;
+ return false;
}
return true;
}
-/* decide the texture target dynamically, based on the pixel format*/
-
-int decideTextureTarget(int pixel_format)
-{
-
- // Default the return value to GL_TEXTURE_EXTERAL_OES
- int retVal = GL_TEXTURE_EXTERNAL_OES;
-
- // Change texture target to TEXTURE_2D for RGB formats
- switch (pixel_format) {
-
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- case HAL_PIXEL_FORMAT_RGB_888:
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- case HAL_PIXEL_FORMAT_RGBA_5551:
- case HAL_PIXEL_FORMAT_RGBA_4444:
- retVal = GL_TEXTURE_2D;
- break;
- default:
- retVal = GL_TEXTURE_EXTERNAL_OES;
- break;
- }
- return retVal;
-}
-
/*
* Function to check if the allocated buffer is of the correct size.
* Reallocate the buffer with the correct size, if the size doesn't
@@ -203,7 +175,7 @@
// Validate the handle
if (private_handle_t::validate(buffer_handle)) {
- ALOGE("%s: handle is invalid", __FUNCTION__);
+ LOGE("%s: handle is invalid", __FUNCTION__);
return -EINVAL;
}
@@ -255,7 +227,7 @@
int updateBufferGeometry(sp<GraphicBuffer> buffer, const qBufGeometry updatedGeometry)
{
if (buffer == 0) {
- ALOGE("%s: graphic buffer is NULL", __FUNCTION__);
+ LOGE("%s: graphic buffer is NULL", __FUNCTION__);
return -EINVAL;
}
@@ -273,7 +245,7 @@
// Validate the handle
if (private_handle_t::validate(buffer->handle)) {
- ALOGE("%s: handle is invalid", __FUNCTION__);
+ LOGE("%s: handle is invalid", __FUNCTION__);
return -EINVAL;
}
buffer->width = updatedGeometry.width;
@@ -285,7 +257,7 @@
hnd->height = updatedGeometry.height;
hnd->format = updatedGeometry.format;
} else {
- ALOGE("%s: hnd is NULL", __FUNCTION__);
+ LOGE("%s: hnd is NULL", __FUNCTION__);
return -EINVAL;
}
@@ -293,14 +265,14 @@
}
/* Update the S3D format of this buffer.
-*
-* @param: buffer whosei S3D format needs to be updated.
-* @param: Updated buffer S3D format
-*/
+ *
+ * @param: buffer whosei S3D format needs to be updated.
+ * @param: Updated buffer S3D format
+ */
int updateBufferS3DFormat(sp<GraphicBuffer> buffer, const int s3dFormat)
{
if (buffer == 0) {
- ALOGE("%s: graphic buffer is NULL", __FUNCTION__);
+ LOGE("%s: graphic buffer is NULL", __FUNCTION__);
return -EINVAL;
}
@@ -331,7 +303,7 @@
else
currentFlags &= ~LAYER_ASYNCHRONOUS;
} break;
- default: ALOGE("%s: invalid attribute(0x%x)", __FUNCTION__, attribute);
+ default: LOGE("%s: invalid attribute(0x%x)", __FUNCTION__, attribute);
break;
}
return ret;
@@ -375,43 +347,12 @@
case HWC_USE_COPYBIT:
return true;
default:
- ALOGE("%s: invalid composition type(%d)", __FUNCTION__, compositionType);
+ LOGE("%s: invalid composition type(%d)", __FUNCTION__, compositionType);
return false;
};
}
/*
- * Get the current composition Type
- *
- * @return the compositon Type
- */
-int getCompositionType() {
- char property[PROPERTY_VALUE_MAX];
- int compositionType = 0;
- if (property_get("debug.sf.hw", property, NULL) > 0) {
- if(atoi(property) == 0) {
- compositionType = COMPOSITION_TYPE_CPU;
- } else { //debug.sf.hw = 1
- property_get("debug.composition.type", property, NULL);
- if (property == NULL) {
- compositionType = COMPOSITION_TYPE_GPU;
- } else if ((strncmp(property, "mdp", 3)) == 0) {
- compositionType = COMPOSITION_TYPE_MDP;
- } else if ((strncmp(property, "c2d", 3)) == 0) {
- compositionType = COMPOSITION_TYPE_C2D;
- } else if ((strncmp(property, "dyn", 3)) == 0) {
- compositionType = COMPOSITION_TYPE_DYN;
- } else {
- compositionType = COMPOSITION_TYPE_GPU;
- }
- }
- } else { //debug.sf.hw is not set. Use cpu composition
- compositionType = COMPOSITION_TYPE_CPU;
- }
- return compositionType;
-}
-
-/*
* Clear Region implementation for C2D/MDP versions.
*
* @param: region to be cleared
@@ -422,31 +363,27 @@
*/
int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur)
{
-#if 0 /* FIXME DIE */
int ret = 0;
+ int compositionType = QCCompositionType::getInstance().getCompositionType();
- if (-1 == sCompositionType) {
- sCompositionType = getCompositionType();
- }
-
- if ((COMPOSITION_TYPE_MDP != sCompositionType) &&
- (COMPOSITION_TYPE_C2D != sCompositionType) &&
- (COMPOSITION_TYPE_CPU != sCompositionType)) {
- // For non CPU/C2D/MDP composition, return an error, so that SF can use
+ if (compositionType & COMPOSITION_TYPE_GPU ||
+ (compositionType == COMPOSITION_TYPE_DYN|COMPOSITION_TYPE_C2D))
+ {
+ // For GPU or DYN comp. with C2D, return an error, so that SF can use
// the GPU to draw the wormhole.
return -1;
}
android_native_buffer_t *renderBuffer = (android_native_buffer_t *)
- eglGetRenderBufferANDROID(dpy, sur);
+ eglGetRenderBufferANDROID(dpy, sur);
if (!renderBuffer) {
- ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer",
- __FUNCTION__);
- return -1;
+ LOGE("%s: eglGetRenderBufferANDROID returned NULL buffer",
+ __FUNCTION__);
+ return -1;
}
private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
if(!fbHandle) {
- ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
+ LOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
return -1;
}
@@ -461,7 +398,7 @@
while (it != end) {
const Rect& r = *it++;
uint8_t* dst = (uint8_t*) fbHandle->base +
- (r.left + r.top*renderBuffer->stride)*bytesPerPixel;
+ (r.left + r.top*renderBuffer->stride)*bytesPerPixel;
int w = r.width()*bytesPerPixel;
int h = r.height();
do {
@@ -472,42 +409,45 @@
dst += stride;
} while(--h);
}
-#endif
return 0;
}
/*
* Handles the externalDisplay event
* HDMI has highest priority compared to WifiDisplay
- * Based on the current and the new display event, decides the
+ * Based on the current and the new display type, decides the
* external display to be enabled
*
- * @param: newEvent - new external event
- * @param: currEvent - currently enabled external event
- * @return: external display to be enabled
+ * @param: disp - external display type(wfd/hdmi)
+ * @param: value - external event(0/1)
+ * @param: currdispType - Current enabled external display Type
+ * @return: external display type to be enabled
*
*/
-external_display handleEventHDMI(external_display newState, external_display
- currState)
+external_display_type handleEventHDMI(external_display_type disp, int value,
+ external_display_type currDispType)
{
- external_display retState = currState;
- switch(newState) {
- case EXT_DISPLAY_HDMI:
- retState = EXT_DISPLAY_HDMI;
+ external_display_type retDispType = currDispType;
+ switch(disp) {
+ case EXT_TYPE_HDMI:
+ if(value)
+ retDispType = EXT_TYPE_HDMI;
+ else
+ retDispType = EXT_TYPE_NONE;
break;
- case EXT_DISPLAY_WIFI:
- if(currState != EXT_DISPLAY_HDMI) {
- retState = EXT_DISPLAY_WIFI;
+ case EXT_TYPE_WIFI:
+ if(currDispType != EXT_TYPE_HDMI) {
+ if(value)
+ retDispType = EXT_TYPE_WIFI;
+ else
+ retDispType = EXT_TYPE_NONE;
}
break;
- case EXT_DISPLAY_OFF:
- retState = EXT_DISPLAY_OFF;
- break;
default:
- ALOGE("handleEventHDMI: unknown Event");
+ LOGE("%s: Unknown External Display Type!!");
break;
}
- return retState;
+ return retDispType;
}
// Using global variables for layer dumping since "property_set("debug.sf.dump",
@@ -532,25 +472,25 @@
localtime_r(&timenow, &sfdump_time);
if ((property_get("debug.sf.dump.png", sfdump_propstr, NULL) > 0) &&
- (strncmp(sfdump_propstr, sfdump_propstr_persist_png,
- PROPERTY_VALUE_MAX - 1))) {
+ (strncmp(sfdump_propstr, sfdump_propstr_persist_png,
+ PROPERTY_VALUE_MAX - 1))) {
// Strings exist & not equal implies it has changed, so trigger a dump
strncpy(sfdump_propstr_persist_png, sfdump_propstr,
- PROPERTY_VALUE_MAX - 1);
+ PROPERTY_VALUE_MAX - 1);
sfdump_countlimit_png = atoi(sfdump_propstr);
sfdump_countlimit_png = (sfdump_countlimit_png < 0) ? 0:
- (sfdump_countlimit_png >= LONG_MAX) ? (LONG_MAX - 1):
- sfdump_countlimit_png;
+ (sfdump_countlimit_png >= LONG_MAX) ? (LONG_MAX - 1):
+ sfdump_countlimit_png;
if (sfdump_countlimit_png) {
sprintf(sfdumpdir_png,"/data/sfdump.png%04d%02d%02d.%02d%02d%02d",
- sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
- sfdump_time.tm_mday, sfdump_time.tm_hour,
- sfdump_time.tm_min, sfdump_time.tm_sec);
+ sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
+ sfdump_time.tm_mday, sfdump_time.tm_hour,
+ sfdump_time.tm_min, sfdump_time.tm_sec);
if (0 == mkdir(sfdumpdir_png, 0777))
sfdump_counter_png = 0;
else
- ALOGE("sfdump: Error: %s. Failed to create sfdump directory"
- ": %s", strerror(errno), sfdumpdir_png);
+ LOGE("sfdump: Error: %s. Failed to create sfdump directory"
+ ": %s", strerror(errno), sfdumpdir_png);
}
}
@@ -558,25 +498,25 @@
sfdump_counter_png++;
if ((property_get("debug.sf.dump", sfdump_propstr, NULL) > 0) &&
- (strncmp(sfdump_propstr, sfdump_propstr_persist_raw,
- PROPERTY_VALUE_MAX - 1))) {
+ (strncmp(sfdump_propstr, sfdump_propstr_persist_raw,
+ PROPERTY_VALUE_MAX - 1))) {
// Strings exist & not equal implies it has changed, so trigger a dump
strncpy(sfdump_propstr_persist_raw, sfdump_propstr,
- PROPERTY_VALUE_MAX - 1);
+ PROPERTY_VALUE_MAX - 1);
sfdump_countlimit_raw = atoi(sfdump_propstr);
sfdump_countlimit_raw = (sfdump_countlimit_raw < 0) ? 0:
- (sfdump_countlimit_raw >= LONG_MAX) ? (LONG_MAX - 1):
- sfdump_countlimit_raw;
+ (sfdump_countlimit_raw >= LONG_MAX) ? (LONG_MAX - 1):
+ sfdump_countlimit_raw;
if (sfdump_countlimit_raw) {
sprintf(sfdumpdir_raw,"/data/sfdump.raw%04d%02d%02d.%02d%02d%02d",
- sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
- sfdump_time.tm_mday, sfdump_time.tm_hour,
- sfdump_time.tm_min, sfdump_time.tm_sec);
+ sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
+ sfdump_time.tm_mday, sfdump_time.tm_hour,
+ sfdump_time.tm_min, sfdump_time.tm_sec);
if (0 == mkdir(sfdumpdir_raw, 0777))
sfdump_counter_raw = 0;
else
- ALOGE("sfdump: Error: %s. Failed to create sfdump directory"
- ": %s", strerror(errno), sfdumpdir_raw);
+ LOGE("sfdump: Error: %s. Failed to create sfdump directory"
+ ": %s", strerror(errno), sfdumpdir_raw);
}
}
@@ -593,85 +533,85 @@
return;
switch(format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- strcpy(pixelformatstr, "RGBA_8888");
- break;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- strcpy(pixelformatstr, "RGBX_8888");
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- strcpy(pixelformatstr, "RGB_888");
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- strcpy(pixelformatstr, "RGB_565");
- break;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- strcpy(pixelformatstr, "BGRA_8888");
- break;
- case HAL_PIXEL_FORMAT_RGBA_5551:
- strcpy(pixelformatstr, "RGBA_5551");
- break;
- case HAL_PIXEL_FORMAT_RGBA_4444:
- strcpy(pixelformatstr, "RGBA_4444");
- break;
- case HAL_PIXEL_FORMAT_YV12:
- strcpy(pixelformatstr, "YV12");
- break;
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- strcpy(pixelformatstr, "YCbCr_422_SP_NV16");
- break;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- strcpy(pixelformatstr, "YCrCb_420_SP_NV21");
- break;
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- strcpy(pixelformatstr, "YCbCr_422_I_YUY2");
- break;
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- strcpy(pixelformatstr, "NV12_ENCODEABLE");
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- strcpy(pixelformatstr, "YCbCr_420_SP_TILED_TILE_4x2");
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- strcpy(pixelformatstr, "YCbCr_420_SP");
- break;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
- strcpy(pixelformatstr, "YCrCb_420_SP_ADRENO");
- break;
- case HAL_PIXEL_FORMAT_YCrCb_422_SP:
- strcpy(pixelformatstr, "YCrCb_422_SP");
- break;
- case HAL_PIXEL_FORMAT_R_8:
- strcpy(pixelformatstr, "R_8");
- break;
- case HAL_PIXEL_FORMAT_RG_88:
- strcpy(pixelformatstr, "RG_88");
- break;
- case HAL_PIXEL_FORMAT_INTERLACE:
- strcpy(pixelformatstr, "INTERLACE");
- break;
- default:
- sprintf(pixelformatstr, "Unknown0x%X", format);
- break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ strcpy(pixelformatstr, "RGBA_8888");
+ break;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ strcpy(pixelformatstr, "RGBX_8888");
+ break;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ strcpy(pixelformatstr, "RGB_888");
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ strcpy(pixelformatstr, "RGB_565");
+ break;
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ strcpy(pixelformatstr, "BGRA_8888");
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ strcpy(pixelformatstr, "RGBA_5551");
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ strcpy(pixelformatstr, "RGBA_4444");
+ break;
+ case HAL_PIXEL_FORMAT_YV12:
+ strcpy(pixelformatstr, "YV12");
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ strcpy(pixelformatstr, "YCbCr_422_SP_NV16");
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ strcpy(pixelformatstr, "YCrCb_420_SP_NV21");
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ strcpy(pixelformatstr, "YCbCr_422_I_YUY2");
+ break;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ strcpy(pixelformatstr, "NV12_ENCODEABLE");
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ strcpy(pixelformatstr, "YCbCr_420_SP_TILED_TILE_4x2");
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ strcpy(pixelformatstr, "YCbCr_420_SP");
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ strcpy(pixelformatstr, "YCrCb_420_SP_ADRENO");
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ strcpy(pixelformatstr, "YCrCb_422_SP");
+ break;
+ case HAL_PIXEL_FORMAT_R_8:
+ strcpy(pixelformatstr, "R_8");
+ break;
+ case HAL_PIXEL_FORMAT_RG_88:
+ strcpy(pixelformatstr, "RG_88");
+ break;
+ case HAL_PIXEL_FORMAT_INTERLACE:
+ strcpy(pixelformatstr, "INTERLACE");
+ break;
+ default:
+ sprintf(pixelformatstr, "Unknown0x%X", format);
+ break;
}
}
void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
- hwc_layer_t hwLayers[])
+ hwc_layer_t hwLayers[])
{
char dumplogstr_png[128] = "";
char dumplogstr_raw[128] = "";
if (sfdump_counter_png <= sfdump_countlimit_png) {
sprintf(dumplogstr_png, "[png-dump-frame: %03d of %03d] ",
- sfdump_counter_png, sfdump_countlimit_png);
+ sfdump_counter_png, sfdump_countlimit_png);
}
if (sfdump_counter_raw <= sfdump_countlimit_raw) {
sprintf(dumplogstr_raw, "[raw-dump-frame: %03d of %03d]",
- sfdump_counter_raw, sfdump_countlimit_raw);
+ sfdump_counter_raw, sfdump_countlimit_raw);
}
if (NULL == hwLayers) {
- ALOGE("sfdump: Error.%s%sLayer[%d] No hwLayers to dump.",
- dumplogstr_raw, dumplogstr_png, layerIndex);
+ LOGE("sfdump: Error.%s%sLayer[%d] No hwLayers to dump.",
+ dumplogstr_raw, dumplogstr_png, layerIndex);
return;
}
hwc_layer *layer = &hwLayers[layerIndex];
@@ -679,263 +619,245 @@
hwc_rect_t displayFrame = layer->displayFrame;
private_handle_t *hnd = (private_handle_t *)layer->handle;
char pixelformatstr[32] = "None";
+ uint32_t transform = layer->transform & FINAL_TRANSFORM_MASK;
if (hnd)
getHalPixelFormatStr(hnd->format, pixelformatstr);
-#if 0
- ALOGE("sfdump: %s%s[%s]-Composition, Layer[%d] SrcBuff[%dx%d] "
- "SrcCrop[%dl, %dt, %dr, %db] "
- "DispFrame[%dl, %dt, %dr, %db] Composition-type = %s, Format = %s, "
- "Orientation = %s, Flags = %s%s%s%s%s%s%s%s%s%s",
- dumplogstr_raw, dumplogstr_png,
- (moduleCompositionType == COMPOSITION_TYPE_GPU)? "GPU":
- (moduleCompositionType == COMPOSITION_TYPE_MDP)? "MDP":
- (moduleCompositionType == COMPOSITION_TYPE_C2D)? "C2D":
- (moduleCompositionType == COMPOSITION_TYPE_CPU)? "CPU":
- (moduleCompositionType == COMPOSITION_TYPE_DYN)? "DYN": "???",
- layerIndex,
- (hnd)? hnd->width : -1, (hnd)? hnd->height : -1,
- sourceCrop.left, sourceCrop.top,
- sourceCrop.right, sourceCrop.bottom,
- displayFrame.left, displayFrame.top,
- displayFrame.right, displayFrame.bottom,
- (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer (OpenGL ES)":
- (layer->compositionType == HWC_OVERLAY)? "Overlay":
- (layer->compositionType == HWC_USE_COPYBIT)? "Copybit": "???",
- pixelformatstr,
- (layer->transform == Transform::ROT_0)? "ROT_0":
- (layer->transform == Transform::FLIP_H)? "FLIP_H":
- (layer->transform == Transform::FLIP_V)? "FLIP_V":
- (layer->transform == Transform::ROT_90)? "ROT_90":
- (layer->transform == Transform::ROT_180)? "ROT_180":
- (layer->transform == Transform::ROT_270)? "ROT_270":
- (layer->transform == Transform::ROT_INVALID)? "ROT_INVALID":"???",
- (layer->flags == 0)? "[None]":"",
- (layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"",
- (layer->flags & HWC_LAYER_NOT_UPDATING)? "[Layer not updating]":"",
- (layer->flags & HWC_USE_ORIGINAL_RESOLUTION)? "[Original Resolution]":"",
- (layer->flags & HWC_DO_NOT_USE_OVERLAY)? "[Do not use Overlay]":"",
- (layer->flags & HWC_COMP_BYPASS)? "[Bypass]":"",
- (layer->flags & HWC_BYPASS_RESERVE_0)? "[Bypass Reserve 0]":"",
- (layer->flags & HWC_BYPASS_RESERVE_1)? "[Bypass Reserve 1]":"",
- (listFlags & HWC_GEOMETRY_CHANGED)? "[List: Geometry Changed]":"",
- (listFlags & HWC_SKIP_COMPOSITION)? "[List: Skip Composition]":"");
-#endif
- if (NULL == hnd) {
- ALOGE("sfdump: %s%sLayer[%d] private-handle is invalid.",
- dumplogstr_raw, dumplogstr_png, layerIndex);
- return;
- }
- if ((sfdump_counter_png <= sfdump_countlimit_png) && hnd->base) {
-#if 0
- bool bResult = false;
- char sfdumpfile_name[256];
- SkBitmap *tempSkBmp = new SkBitmap();
- SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
- sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d.png", sfdumpdir_png,
- sfdump_counter_png, layerIndex);
+ LOGE("sfdump: %s%s[%s]-Composition, Layer[%d] SrcBuff[%dx%d] "
+ "SrcCrop[%dl, %dt, %dr, %db] "
+ "DispFrame[%dl, %dt, %dr, %db] Composition-type = %s, Format = %s, "
+ "Orientation = %s, Flags = %s%s%s%s%s%s%s%s%s%s",
+ dumplogstr_raw, dumplogstr_png,
+ (moduleCompositionType == COMPOSITION_TYPE_GPU)? "GPU":
+ (moduleCompositionType == COMPOSITION_TYPE_MDP)? "MDP":
+ (moduleCompositionType == COMPOSITION_TYPE_C2D)? "C2D":
+ (moduleCompositionType == COMPOSITION_TYPE_CPU)? "CPU":
+ (moduleCompositionType == COMPOSITION_TYPE_DYN)? "DYN": "???",
+ layerIndex,
+ (hnd)? hnd->width : -1, (hnd)? hnd->height : -1,
+ sourceCrop.left, sourceCrop.top,
+ sourceCrop.right, sourceCrop.bottom,
+ displayFrame.left, displayFrame.top,
+ displayFrame.right, displayFrame.bottom,
+ (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer (OpenGL ES)":
+ (layer->compositionType == HWC_OVERLAY)? "Overlay":
+ (layer->compositionType == HWC_USE_COPYBIT)? "Copybit": "???",
+ pixelformatstr,
+ (transform == Transform::ROT_0)? "ROT_0":
+ (transform == Transform::FLIP_H)? "FLIP_H":
+ (transform == Transform::FLIP_V)? "FLIP_V":
+ (transform == Transform::ROT_90)? "ROT_90":
+ (transform == Transform::ROT_180)? "ROT_180":
+ (transform == Transform::ROT_270)? "ROT_270":
+ (transform == Transform::ROT_INVALID)? "ROT_INVALID":"???",
+ (layer->flags == 0)? "[None]":"",
+ (layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"",
+ (layer->flags & HWC_LAYER_NOT_UPDATING)? "[Layer not updating]":"",
+ (layer->flags & HWC_COMP_BYPASS)? "[Bypass]":"",
+ (layer->flags & HWC_BYPASS_RESERVE_0)? "[Bypass Reserve 0]":"",
+ (layer->flags & HWC_BYPASS_RESERVE_1)? "[Bypass Reserve 1]":"",
+ (listFlags & HWC_GEOMETRY_CHANGED)? "[List: Geometry Changed]":"",
+ (listFlags & HWC_SKIP_COMPOSITION)? "[List: Skip Composition]":"");
- switch (hnd->format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- tempSkBmpConfig = SkBitmap::kARGB_8888_Config;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_RGBA_5551:
- case HAL_PIXEL_FORMAT_RGBA_4444:
- tempSkBmpConfig = SkBitmap::kRGB_565_Config;
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- default:
- tempSkBmpConfig = SkBitmap::kNo_Config;
- break;
- }
- if (SkBitmap::kNo_Config != tempSkBmpConfig) {
- tempSkBmp->setConfig(tempSkBmpConfig, hnd->width, hnd->height);
- tempSkBmp->setPixels((void*)hnd->base);
- bResult = SkImageEncoder::EncodeFile(sfdumpfile_name,
- *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
- ALOGE("sfdump: %sDumped Layer[%d] to %s: %s", dumplogstr_png,
- layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
- }
- else {
- ALOGE("sfdump: %sSkipping Layer[%d] dump: Unsupported layer "
- "format %s for png encoder.", dumplogstr_png, layerIndex,
- pixelformatstr);
- }
- delete tempSkBmp; // Calls SkBitmap::freePixels() internally.
-#endif
- }
-
- if ((sfdump_counter_raw <= sfdump_countlimit_raw) && hnd->base) {
- char sfdumpfile_name[256];
- bool bResult = false;
- sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d_%dx%d_%s.raw",
- sfdumpdir_raw,
- sfdump_counter_raw, layerIndex, hnd->width, hnd->height,
- pixelformatstr);
- FILE* fp = fopen(sfdumpfile_name, "w+");
- if (fp != NULL) {
- bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
- fclose(fp);
- }
- ALOGE("sfdump: %s Dumped Layer[%d] to %s: %s", dumplogstr_raw,
- layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
- }
-}
-
-#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) {
- ALOGW("out of range value for debug.gr.calcfps, using 0");
- debug_fps_level = 0;
- }
-
- ALOGE("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;
-
- ALOGE("period: %d", debug_fps_metadata.period);
- ALOGE("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)
- ALOGE("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
- else
- ALOGE("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) {
- ALOGE("Frame Arrival Distribution:");
- for (unsigned int i = 0;
- i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
- i++) {
- ALOGE("%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) {
+ if (NULL == hnd) {
+ LOGE("sfdump: %s%sLayer[%d] private-handle is invalid.",
+ dumplogstr_raw, dumplogstr_png, layerIndex);
return;
}
- if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
- debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff;
- }
+ if ((sfdump_counter_png <= sfdump_countlimit_png) && hnd->base) {
+ bool bResult = false;
+ char sfdumpfile_name[256];
+ SkBitmap *tempSkBmp = new SkBitmap();
+ SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
+ sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d.png", sfdumpdir_png,
+ sfdump_counter_png, layerIndex);
- 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]++;
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ tempSkBmpConfig = SkBitmap::kARGB_8888_Config;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ tempSkBmpConfig = SkBitmap::kRGB_565_Config;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ default:
+ tempSkBmpConfig = SkBitmap::kNo_Config;
+ break;
}
+ if (SkBitmap::kNo_Config != tempSkBmpConfig) {
+ tempSkBmp->setConfig(tempSkBmpConfig, hnd->width, hnd->height);
+ tempSkBmp->setPixels((void*)hnd->base);
+ bResult = SkImageEncoder::EncodeFile(sfdumpfile_name,
+ *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
+ LOGE("sfdump: %sDumped Layer[%d] to %s: %s", dumplogstr_png,
+ layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
+ }
+ else {
+ LOGE("sfdump: %sSkipping Layer[%d] dump: Unsupported layer "
+ "format %s for png encoder.", dumplogstr_png, layerIndex,
+ pixelformatstr);
+ }
+ delete tempSkBmp; // Calls SkBitmap::freePixels() internally.
}
- 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));
+ if ((sfdump_counter_raw <= sfdump_countlimit_raw) && hnd->base) {
+ char sfdumpfile_name[256];
+ bool bResult = false;
+ sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d_%dx%d_%s.raw",
+ sfdumpdir_raw,
+ sfdump_counter_raw, layerIndex, hnd->width, hnd->height,
+ pixelformatstr);
+ FILE* fp = fopen(sfdumpfile_name, "w+");
+ if (fp != NULL) {
+ bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
+ fclose(fp);
}
+ LOGE("sfdump: %s Dumped Layer[%d] to %s: %s", dumplogstr_raw,
+ layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
}
- 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
+
+bool needsAspectRatio (int wRatio, int hRatio) {
+ return ((wRatio != DEFAULT_WIDTH_RATIO) || (hRatio != DEFAULT_HEIGHT_RATIO));
+}
+
+void applyPixelAspectRatio (int wRatio, int hRatio, int orientation, int maxWidth,
+ int maxHeight, Rect& visibleRect, GLfloat mVertices[][2]) {
+
+ if ((wRatio == 0) || (hRatio == 0))
+ return;
+
+ float wDelta = 0;
+ float hDelta = 0;
+ float aspectRatio;
+ float displayRatio;
+ float new_width, new_height;
+ float old_width = abs(visibleRect.right - visibleRect.left);
+ float old_height = abs(visibleRect.bottom - visibleRect.top);
+
+ if (orientation == Transform::ROT_INVALID) {
+ // During animation, no defined orientation, rely on mTransformedBounds
+ if (old_width >= old_height)
+ orientation = Transform::ROT_0;
+ else
+ orientation = Transform::ROT_90;
+ }
+
+ switch (orientation) {
+
+ case Transform::ROT_0:
+ case Transform::ROT_180:
+
+ // Calculated Aspect Ratio = Original Aspect Ratio x Pixel Aspect Ratio
+ aspectRatio = (old_width * wRatio) / (old_height * hRatio);
+ displayRatio = (float)maxWidth / (float)maxHeight;
+
+ if (aspectRatio >= displayRatio) {
+ new_height = old_width / aspectRatio;
+ if (new_height > maxHeight) {
+ new_height = maxHeight;
+ new_width = new_height * aspectRatio;
+ wDelta = (new_width - old_width) / 2;
+ }
+ hDelta = (new_height - old_height) / 2;
+ } else {
+ new_width = old_height * aspectRatio;
+ if (new_width > maxWidth) {
+ new_width = maxWidth;
+ new_height = new_width / aspectRatio;
+ hDelta = (new_height - old_height) / 2;
+ }
+ wDelta = (new_width - old_width) / 2;
+ }
+
+ if (hDelta != 0) {
+ visibleRect.top -= hDelta;
+ visibleRect.bottom += hDelta;
+
+ // Set mVertices for GPU fallback (During rotation)
+ if (orientation == Transform::ROT_0) {
+ mVertices[1][1] = mVertices[2][1] = visibleRect.top;
+ mVertices[0][1] = mVertices[3][1] = visibleRect.bottom;
+ } else {
+ mVertices[0][1] = mVertices[3][1] = visibleRect.top;
+ mVertices[1][1] = mVertices[2][1] = visibleRect.bottom;
+ }
+ }
+
+ if (wDelta != 0) {
+ visibleRect.left -= wDelta;
+ visibleRect.right += wDelta;
+
+ // Set mVertices for GPU fallback (During rotation)
+ mVertices[0][0] = mVertices[1][0] = visibleRect.left;
+ mVertices[2][0] = mVertices[3][0] = visibleRect.right;
+ }
+ break;
+
+ case Transform::ROT_90:
+ case Transform::ROT_270:
+
+ // Calculated Aspect Ratio = Original Aspect Ratio x Pixel Aspect Ratio
+ aspectRatio = (old_height * wRatio) / (old_width * hRatio);
+ displayRatio = (float)maxHeight / (float)maxWidth;
+
+ if (aspectRatio >= displayRatio) {
+ new_height = old_width * aspectRatio;
+ if (new_height > maxHeight) {
+ new_height = maxHeight;
+ new_width = new_height / aspectRatio;
+ wDelta = (new_width - old_width) / 2;
+ }
+ hDelta = (new_height - old_height) / 2;
+ } else {
+ new_width = old_height / aspectRatio;
+ if (new_width > maxWidth) {
+ new_width = maxWidth;
+ new_height = new_width * aspectRatio;
+ hDelta = (new_height - old_height) / 2;
+ }
+ wDelta = (new_width - old_width) / 2;
+ }
+
+ if (hDelta != 0) {
+ visibleRect.top -= hDelta;
+ visibleRect.bottom += hDelta;
+
+ // Set mVertices for GPU fallback (During rotation)
+ if (orientation == Transform::ROT_90) {
+ mVertices[2][1] = mVertices[3][1] = visibleRect.top;
+ mVertices[0][1] = mVertices[1][1] = visibleRect.bottom;
+ } else {
+ mVertices[0][1] = mVertices[1][1] = visibleRect.top;
+ mVertices[2][1] = mVertices[3][1] = visibleRect.bottom;
+ }
+ }
+
+ if (wDelta != 0) {
+ visibleRect.left -= wDelta;
+ visibleRect.right += wDelta;
+
+ // Set mVertices for GPU fallback (During rotation)
+ if (orientation == Transform::ROT_90) {
+ mVertices[1][0] = mVertices[2][0] = visibleRect.left;
+ mVertices[0][0] = mVertices[3][0] = visibleRect.right;
+ } else {
+ mVertices[0][0] = mVertices[3][0] = visibleRect.left;
+ mVertices[1][0] = mVertices[2][0] = visibleRect.right;
+ }
+ }
+ break;
+
+ default: // Handled above.
+ break;
+
+ }
+}
+
+
diff --git a/libqcomui/qcom_ui.h b/libqcomui/qcom_ui.h
index 88462cc..89974bd 100644
--- a/libqcomui/qcom_ui.h
+++ b/libqcomui/qcom_ui.h
@@ -33,18 +33,19 @@
#include <cutils/native_handle.h>
#include <ui/GraphicBuffer.h>
#include <hardware/hwcomposer.h>
-#include <hardware/hwcomposer_defs.h>
#include <ui/Region.h>
#include <EGL/egl.h>
+#include <GLES/gl.h>
#include <utils/Singleton.h>
#include <cutils/properties.h>
-#include "../libgralloc/gralloc_priv.h"
using namespace android;
using android::sp;
using android::GraphicBuffer;
#define HWC_BYPASS_INDEX_MASK 0x00000030
+#define DEFAULT_WIDTH_RATIO 1
+#define DEFAULT_HEIGHT_RATIO 1
/*
* Qcom specific Native Window perform operations
@@ -53,15 +54,7 @@
NATIVE_WINDOW_SET_BUFFERS_SIZE = 0x10000000,
NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY = 0x20000000,
NATIVE_WINDOW_SET_S3D_FORMAT = 0x40000000,
-};
-
-// Enum containing the supported composition types
-enum {
- COMPOSITION_TYPE_GPU = 0,
- COMPOSITION_TYPE_MDP = 0x1,
- COMPOSITION_TYPE_C2D = 0x2,
- COMPOSITION_TYPE_CPU = 0x4,
- COMPOSITION_TYPE_DYN = 0x8
+ NATIVE_WINDOW_SET_PIXEL_ASPECT_RATIO = 0x80000000,
};
/*
@@ -81,16 +74,21 @@
};
/*
+ * Layer Transformation - refers to Layer::setGeometry()
+ */
+#define SHIFT_SRC_TRANSFORM 4
+#define SRC_TRANSFORM_MASK 0x00F0
+#define FINAL_TRANSFORM_MASK 0x000F
+
+/*
* Flags set by the layer and sent to HWC
*/
enum {
HWC_LAYER_NOT_UPDATING = 0x00000002,
HWC_LAYER_ASYNCHRONOUS = 0x00000004,
- HWC_USE_ORIGINAL_RESOLUTION = 0x10000000,
- HWC_DO_NOT_USE_OVERLAY = 0x20000000,
- HWC_COMP_BYPASS = 0x40000000,
- HWC_USE_EXT_ONLY = 0x80000000, //Layer displayed on external only
- HWC_USE_EXT_BLOCK = 0x01000000, //Layer displayed on external only
+ HWC_COMP_BYPASS = 0x10000000,
+ HWC_USE_EXT_ONLY = 0x20000000, //Layer displayed on external only
+ HWC_USE_EXT_BLOCK = 0x40000000, //Layer displayed on external only
HWC_BYPASS_RESERVE_0 = 0x00000010,
HWC_BYPASS_RESERVE_1 = 0x00000020,
};
@@ -101,10 +99,41 @@
HWC_USE_COPYBIT // This layer is to be handled by copybit
};
-enum external_display {
- EXT_DISPLAY_OFF,
- EXT_DISPLAY_HDMI,
- EXT_DISPLAY_WIFI
+enum external_display_type {
+ EXT_TYPE_NONE,
+ EXT_TYPE_HDMI,
+ EXT_TYPE_WIFI
+};
+
+/* Events to the Display HAL perform function
+ As of now used for external display related such as
+ connect, disconnect, orientation, video started etc.,
+ */
+enum {
+ EVENT_EXTERNAL_DISPLAY, // External display on/off Event
+ EVENT_VIDEO_OVERLAY, // Video Overlay start/stop Event
+ EVENT_ORIENTATION_CHANGE, // Orientation Change Event
+ EVENT_OVERLAY_STATE_CHANGE, // Overlay State Change Event
+ EVENT_OPEN_SECURE_START, // Start of secure session setup config by stagefright
+ EVENT_OPEN_SECURE_END, // End of secure session setup config by stagefright
+ EVENT_CLOSE_SECURE_START, // Start of secure session teardown config
+ EVENT_CLOSE_SECURE_END, // End of secure session teardown config
+ EVENT_RESET_POSTBUFFER, // Reset post framebuffer mutex
+ EVENT_WAIT_POSTBUFFER, // Wait until post framebuffer returns
+};
+
+// Video information sent to framebuffer HAl
+// used for handling UI mirroring.
+enum {
+ VIDEO_OVERLAY_ENDED = 0,
+ VIDEO_2D_OVERLAY_STARTED,
+ VIDEO_3D_OVERLAY_STARTED
+};
+
+// Information about overlay state change
+enum {
+ OVERLAY_STATE_CHANGE_START = 0,
+ OVERLAY_STATE_CHANGE_END
};
/*
@@ -115,86 +144,18 @@
int height;
int format;
void set(int w, int h, int f) {
- width = w;
- height = h;
- format = f;
+ width = w;
+ height = h;
+ format = f;
}
};
-#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
-
#if 0
class QCBaseLayer
{
-// int mS3DFormat;
+ // int mS3DFormat;
int32_t mComposeS3DFormat;
-public:
+ public:
QCBaseLayer()
{
mComposeS3DFormat = 0;
@@ -203,10 +164,10 @@
eS3D_SIDE_BY_SIDE = 0x10000,
eS3D_TOP_BOTTOM = 0x20000
};
-/*
- virtual status_t setStereoscopic3DFormat(int format) { mS3DFormat = format; return 0; }
- virtual int getStereoscopic3DFormat() const { return mS3DFormat; }
- */
+ /*
+ virtual status_t setStereoscopic3DFormat(int format) { mS3DFormat = format; return 0; }
+ virtual int getStereoscopic3DFormat() const { return mS3DFormat; }
+ */
void setS3DComposeFormat (int32_t hints)
{
if (hints & HWC_HINT_DRAW_S3D_SIDE_BY_SIDE)
@@ -242,21 +203,6 @@
*/
bool isGPUSupportedFormat(int format);
-/*
- * Adreno is not optimized for GL_TEXTURE_EXTERNAL_OES
- * texure target. DO NOT choose TEXTURE_EXTERNAL_OES
- * target for RGB formats.
- *
- * Based on the pixel format, decide the texture target.
- *
- * @param : pixel format to check
- *
- * @return : GL_TEXTURE_2D for RGB formats, and
- * GL_TEXTURE_EXTERNAL_OES for YUV formats.
- *
-*/
-
-int decideTextureTarget (const int pixel_format);
/*
* Gets the number of arguments required for this operation.
@@ -277,8 +223,8 @@
* @return True if a memory reallocation is required.
*/
bool needNewBuffer(const qBufGeometry currentGeometry,
- const qBufGeometry requiredGeometry,
- const qBufGeometry updatedGeometry);
+ const qBufGeometry requiredGeometry,
+ const qBufGeometry updatedGeometry);
/*
* Update the geometry of this buffer without reallocation.
@@ -327,13 +273,6 @@
bool isUpdatingFB(HWCCompositionType compositionType);
/*
- * Get the current composition Type
- *
- * @return the compositon Type
- */
-int getCompositionType();
-
-/*
* Clear region implementation for C2D/MDP versions.
*
* @param: region to be cleared
@@ -355,9 +294,8 @@
* @return: external display to be enabled
*
*/
-external_display handleEventHDMI(external_display newEvent, external_display
- currEvent);
-
+external_display_type handleEventHDMI(external_display_type disp, int value,
+ external_display_type currDispType);
/*
* Checks if layers need to be dumped based on system property "debug.sf.dump"
* for raw dumps and "debug.sf.dump.png" for png dumps.
@@ -389,6 +327,10 @@
*
*/
void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
- hwc_layer_t hwLayers[]);
+ hwc_layer_t hwLayers[]);
+
+bool needsAspectRatio (int wRatio, int hRatio);
+void applyPixelAspectRatio (int wRatio, int hRatio, int orientation, int fbWidth,
+ int fbHeight, Rect& visibleRect, GLfloat vertices[][2]);
#endif // INCLUDE_LIBQCOM_UI
diff --git a/libqcomui/qcomutils/IdleInvalidator.cpp b/libqcomui/qcomutils/IdleInvalidator.cpp
new file mode 100755
index 0000000..0b98e11
--- /dev/null
+++ b/libqcomui/qcomutils/IdleInvalidator.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "IdleInvalidator.h"
+#include <unistd.h>
+
+#define II_DEBUG 1
+
+static const char *threadName = "Invalidator";
+InvalidatorHandler IdleInvalidator::mHandler = NULL;
+android::sp<IdleInvalidator> IdleInvalidator::sInstance(0);
+
+IdleInvalidator::IdleInvalidator(): Thread(false), mHwcContext(0),
+ mSleepAgain(false), mSleepTime(0) {
+ ALOGE_IF(II_DEBUG, "shs %s", __func__);
+ }
+
+int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data,
+ unsigned int idleSleepTime) {
+ ALOGE_IF(II_DEBUG, "shs %s", __func__);
+
+ /* store registered handler */
+ mHandler = reg_handler;
+ mHwcContext = user_data;
+ mSleepTime = idleSleepTime; //Time in millis
+ return 0;
+}
+
+bool IdleInvalidator::threadLoop() {
+ ALOGE_IF(II_DEBUG, "shs %s", __func__);
+ usleep(mSleepTime * 1000);
+ if(mSleepAgain) {
+ //We need to sleep again!
+ mSleepAgain = false;
+ return true;
+ }
+
+ mHandler((void*)mHwcContext);
+ return false;
+}
+
+int IdleInvalidator::readyToRun() {
+ ALOGE_IF(II_DEBUG, "shs %s", __func__);
+ return 0; /*NO_ERROR*/
+}
+
+void IdleInvalidator::onFirstRef() {
+ ALOGE_IF(II_DEBUG, "shs %s", __func__);
+}
+
+void IdleInvalidator::markForSleep() {
+ mSleepAgain = true;
+ //Triggers the threadLoop to run, if not already running.
+ run(threadName, android::PRIORITY_AUDIO);
+}
+
+IdleInvalidator *IdleInvalidator::getInstance() {
+ ALOGE_IF(II_DEBUG, "shs %s", __func__);
+ if(sInstance.get() == NULL)
+ sInstance = new IdleInvalidator();
+ return sInstance.get();
+}
diff --git a/libqcomui/qcomutils/IdleInvalidator.h b/libqcomui/qcomutils/IdleInvalidator.h
new file mode 100755
index 0000000..930cd35
--- /dev/null
+++ b/libqcomui/qcomutils/IdleInvalidator.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_IDLEINVALIDATOR
+#define INCLUDE_IDLEINVALIDATOR
+
+#include <cutils/log.h>
+#include <utils/threads.h>
+
+typedef void (*InvalidatorHandler)(void*);
+
+class IdleInvalidator : public android::Thread {
+ void *mHwcContext;
+ bool mSleepAgain;
+ unsigned int mSleepTime;
+ static InvalidatorHandler mHandler;
+ static android::sp<IdleInvalidator> sInstance;
+
+ public:
+ IdleInvalidator();
+ /* init timer obj */
+ int init(InvalidatorHandler reg_handler, void* user_data, unsigned int
+ idleSleepTime);
+ void markForSleep();
+ /*Overrides*/
+ virtual bool threadLoop();
+ virtual int readyToRun();
+ virtual void onFirstRef();
+ static IdleInvalidator *getInstance();
+};
+
+#endif // INCLUDE_IDLEINVALIDATOR
diff --git a/libqcomui/qcomutils/comptype.h b/libqcomui/qcomutils/comptype.h
new file mode 100644
index 0000000..603e143
--- /dev/null
+++ b/libqcomui/qcomutils/comptype.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_LIBQCOM_COMPTYPES
+#define INCLUDE_LIBQCOM_COMPTYPES
+
+#include <stdint.h>
+#include <utils/Singleton.h>
+#include <cutils/properties.h>
+
+using namespace android;
+
+// Enum containing the supported composition types
+enum {
+ COMPOSITION_TYPE_GPU = 0,
+ COMPOSITION_TYPE_MDP = 0x1,
+ COMPOSITION_TYPE_C2D = 0x2,
+ COMPOSITION_TYPE_CPU = 0x4,
+ COMPOSITION_TYPE_DYN = 0x8
+};
+
+/* This class caches the composition type
+ */
+class QCCompositionType : public Singleton <QCCompositionType>
+{
+ public:
+ QCCompositionType();
+ ~QCCompositionType() { }
+ int getCompositionType() {return mCompositionType;}
+ private:
+ int mCompositionType;
+
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(QCCompositionType);
+inline QCCompositionType::QCCompositionType()
+{
+ char property[PROPERTY_VALUE_MAX];
+ mCompositionType = 0;
+ if (property_get("debug.sf.hw", property, NULL) > 0) {
+ if(atoi(property) == 0) {
+ mCompositionType = COMPOSITION_TYPE_CPU;
+ } else { //debug.sf.hw = 1
+ property_get("debug.composition.type", property, NULL);
+ if (property == NULL) {
+ mCompositionType = COMPOSITION_TYPE_GPU;
+ } else if ((strncmp(property, "mdp", 3)) == 0) {
+ mCompositionType = COMPOSITION_TYPE_MDP;
+ } else if ((strncmp(property, "c2d", 3)) == 0) {
+ mCompositionType = COMPOSITION_TYPE_C2D;
+ } else if ((strncmp(property, "dyn", 3)) == 0) {
+#ifdef USE_MDP3
+ mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_MDP;
+#else
+ mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_C2D;
+#endif
+ } else {
+ mCompositionType = COMPOSITION_TYPE_GPU;
+ }
+ }
+ } else { //debug.sf.hw is not set. Use cpu composition
+ mCompositionType = COMPOSITION_TYPE_CPU;
+ }
+
+}
+#endif //INCLUDE_LIBQCOM_COMPTYPES
diff --git a/libqcomui/qcomutils/profiler.cpp b/libqcomui/qcomutils/profiler.cpp
new file mode 100755
index 0000000..73854bc
--- /dev/null
+++ b/libqcomui/qcomutils/profiler.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "profiler.h"
+
+#ifdef DEBUG_CALC_FPS
+
+#define LOG_TAG "CALCFPS"
+#define LOG_NDDEBUG 0
+
+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) {
+ ALOGW("out of range value for debug.gr.calcfps, using 0");
+ debug_fps_level = 0;
+ }
+
+ ALOGD("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;
+
+ ALOGD("period: %d", debug_fps_metadata.period);
+ ALOGD("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)
+ ALOGD("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
+ else
+ ALOGD("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) {
+ ALOGD("Frame Arrival Distribution:");
+ for (unsigned int i = 0;
+ i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
+ i++) {
+ ALOGD("%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
diff --git a/libqcomui/qcomutils/profiler.h b/libqcomui/qcomutils/profiler.h
new file mode 100755
index 0000000..394f490
--- /dev/null
+++ b/libqcomui/qcomutils/profiler.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_PROFILER
+#define INCLUDE_PROFILER
+
+#include <stdio.h>
+#include <utils/Singleton.h>
+#include <cutils/properties.h>
+#include <cutils/log.h>
+using namespace android;
+
+#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
+
+#endif // INCLUDE_PROFILER