Merge "hwc: No idle fallback for single layers"
diff --git a/Android.mk b/Android.mk
index 772b66e..d8b168d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,5 @@
display-hals := libgralloc libgenlock libcopybit liblight
-display-hals += libhwcomposer liboverlay libqdutils libexternal libqservice
+display-hals += libhwcomposer liboverlay libqdutils libhdmi libqservice
display-hals += libmemtrack
ifeq ($(call is-vendor-board-platform,QCOM),true)
include $(call all-named-subdir-makefiles,$(display-hals))
diff --git a/common.mk b/common.mk
index 14d8ded..ae6c95a 100644
--- a/common.mk
+++ b/common.mk
@@ -4,7 +4,7 @@
common_includes += $(LOCAL_PATH)/../libcopybit
common_includes += $(LOCAL_PATH)/../libqdutils
common_includes += $(LOCAL_PATH)/../libhwcomposer
-common_includes += $(LOCAL_PATH)/../libexternal
+common_includes += $(LOCAL_PATH)/../libhdmi
common_includes += $(LOCAL_PATH)/../libqservice
ifeq ($(TARGET_USES_POST_PROCESSING),true)
diff --git a/libexternal/Android.mk b/libhdmi/Android.mk
similarity index 67%
rename from libexternal/Android.mk
rename to libhdmi/Android.mk
index 05e42d4..89ba4a9 100644
--- a/libexternal/Android.mk
+++ b/libhdmi/Android.mk
@@ -2,12 +2,12 @@
include $(LOCAL_PATH)/../common.mk
include $(CLEAR_VARS)
-LOCAL_MODULE := libexternal
+LOCAL_MODULE := libhdmi
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay libqdutils
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdexternal\"
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhdmi\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := external.cpp
+LOCAL_SRC_FILES := hdmi.cpp
include $(BUILD_SHARED_LIBRARY)
diff --git a/libexternal/external.cpp b/libhdmi/hdmi.cpp
similarity index 87%
rename from libexternal/external.cpp
rename to libhdmi/hdmi.cpp
index 28cf590..4fb7cfa 100644
--- a/libexternal/external.cpp
+++ b/libhdmi/hdmi.cpp
@@ -26,7 +26,7 @@
#include <sys/ioctl.h>
#include <cutils/properties.h>
#include "hwc_utils.h"
-#include "external.h"
+#include "hdmi.h"
#include "overlayUtils.h"
#include "overlay.h"
#include "qd_utils.h"
@@ -64,26 +64,37 @@
EDIDData(HDMI_VFRMT_720x480p60_16_9, 720, 480, 60, 8),
EDIDData(HDMI_VFRMT_720x576p50_4_3, 720, 576, 50, 9),
EDIDData(HDMI_VFRMT_720x576p50_16_9, 720, 576, 50, 10),
- EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 11),
- EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 12),
- EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 13),
- EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 14),
- EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 15),
- EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 16),
- EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 17),
- EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 18),
- EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 19),
- EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 20),
- EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 21),
- EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 22),
- EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 23),
- EDIDData(HDMI_VFRMT_4096x2160p24_16_9, 4096, 2160, 24, 24),
+ EDIDData(HDMI_VFRMT_800x600p60_4_3, 800, 600, 60, 11),
+ EDIDData(HDMI_VFRMT_848x480p60_16_9, 848, 480, 60, 12),
+ EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 13),
+ EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 14),
+ EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 15),
+ EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 16),
+ EDIDData(HDMI_VFRMT_1280x800p60_16_10, 1280, 800, 60, 17),
+ EDIDData(HDMI_VFRMT_1280x960p60_4_3, 1280, 960, 60, 18),
+ EDIDData(HDMI_VFRMT_1360x768p60_16_9, 1360, 768, 60, 19),
+ EDIDData(HDMI_VFRMT_1366x768p60_16_10, 1366, 768, 60, 20),
+ EDIDData(HDMI_VFRMT_1440x900p60_16_10, 1440, 900, 60, 21),
+ EDIDData(HDMI_VFRMT_1400x1050p60_4_3, 1400, 1050, 60, 22),
+ EDIDData(HDMI_VFRMT_1680x1050p60_16_10, 1680, 1050, 60, 23),
+ EDIDData(HDMI_VFRMT_1600x1200p60_4_3, 1600, 1200, 60, 24),
+ EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 25),
+ EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 26),
+ EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 27),
+ EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 28),
+ EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 29),
+ EDIDData(HDMI_VFRMT_1920x1200p60_16_10, 1920, 1200, 60, 30),
+ EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 31),
+ EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 32),
+ EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 33),
+ EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 34),
+ EDIDData(HDMI_VFRMT_4096x2160p24_16_9, 4096, 2160, 24, 35),
};
// Number of modes in gEDIDData
const int gEDIDCount = (sizeof(gEDIDData)/sizeof(gEDIDData)[0]);
-int ExternalDisplay::configure() {
+int HDMIDisplay::configure() {
if(!openFrameBuffer()) {
ALOGE("%s: Failed to open FB: %d", __FUNCTION__, mFbNum);
return -1;
@@ -113,12 +124,12 @@
return 0;
}
-void ExternalDisplay::getAttributes(uint32_t& width, uint32_t& height) {
+void HDMIDisplay::getAttributes(uint32_t& width, uint32_t& height) {
uint32_t fps = 0;
getAttrForMode(width, height, fps);
}
-int ExternalDisplay::teardown() {
+int HDMIDisplay::teardown() {
closeFrameBuffer();
resetInfo();
// unset system property
@@ -126,7 +137,7 @@
return 0;
}
-ExternalDisplay::ExternalDisplay():mFd(-1),
+HDMIDisplay::HDMIDisplay():mFd(-1),
mCurrentMode(-1), mModeCount(0), mPrimaryWidth(0), mPrimaryHeight(0),
mUnderscanSupported(false)
{
@@ -166,7 +177,7 @@
* to the sysfs node, so that the driver can get that information
* Used to show QCOM 8974 instead of Input 1 for example
*/
-void ExternalDisplay::setSPDInfo(const char* node, const char* property) {
+void HDMIDisplay::setSPDInfo(const char* node, const char* property) {
char info[PROPERTY_VALUE_MAX];
ssize_t err = -1;
int spdFile = openDeviceNode(node, O_RDWR);
@@ -189,12 +200,12 @@
}
}
-void ExternalDisplay::setHPD(uint32_t value) {
+void HDMIDisplay::setHPD(uint32_t value) {
ALOGD_IF(DEBUG,"HPD enabled=%d", value);
writeHPDOption(value);
}
-void ExternalDisplay::setActionSafeDimension(int w, int h) {
+void HDMIDisplay::setActionSafeDimension(int w, int h) {
ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
char actionsafeWidth[PROPERTY_VALUE_MAX];
char actionsafeHeight[PROPERTY_VALUE_MAX];
@@ -204,12 +215,12 @@
property_set("persist.sys.actionsafe.height", actionsafeHeight);
}
-int ExternalDisplay::getModeCount() const {
+int HDMIDisplay::getModeCount() const {
ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
return mModeCount;
}
-void ExternalDisplay::readCEUnderscanInfo()
+void HDMIDisplay::readCEUnderscanInfo()
{
int hdmiScanInfoFile = -1;
ssize_t len = -1;
@@ -258,8 +269,8 @@
if (ce_info_str) {
// ce_info contains the underscan information
- if (ce_info == EXT_SCAN_ALWAYS_UNDERSCANED ||
- ce_info == EXT_SCAN_BOTH_SUPPORTED)
+ if (ce_info == HDMI_SCAN_ALWAYS_UNDERSCANED ||
+ ce_info == HDMI_SCAN_BOTH_SUPPORTED)
// if TV supported underscan, then driver will always underscan
// hence no need to apply action safe rectangle
mUnderscanSupported = true;
@@ -273,7 +284,7 @@
return;
}
-ExternalDisplay::~ExternalDisplay()
+HDMIDisplay::~HDMIDisplay()
{
delete [] supported_video_mode_lut;
closeFrameBuffer();
@@ -309,7 +320,7 @@
info.upper_margin = mode->back_porch_v;
}
-int ExternalDisplay::parseResolution(char* edidStr)
+int HDMIDisplay::parseResolution(char* edidStr)
{
char delim = ',';
int count = 0;
@@ -330,7 +341,7 @@
return count;
}
-bool ExternalDisplay::readResolution()
+bool HDMIDisplay::readResolution()
{
ssize_t len = -1;
char edidStr[128] = {'\0'};
@@ -364,7 +375,7 @@
return (len > 0);
}
-bool ExternalDisplay::openFrameBuffer()
+bool HDMIDisplay::openFrameBuffer()
{
if (mFd == -1) {
char strDevPath[MAX_SYSFS_FILE_PATH];
@@ -376,7 +387,7 @@
return (mFd > 0);
}
-bool ExternalDisplay::closeFrameBuffer()
+bool HDMIDisplay::closeFrameBuffer()
{
int ret = 0;
if(mFd >= 0) {
@@ -387,7 +398,7 @@
}
// clears the vinfo, edid, best modes
-void ExternalDisplay::resetInfo()
+void HDMIDisplay::resetInfo()
{
memset(&mVInfo, 0, sizeof(mVInfo));
memset(mEDIDModes, 0, sizeof(mEDIDModes));
@@ -403,7 +414,7 @@
property_set("hw.underscan_supported", prop);
}
-int ExternalDisplay::getModeOrder(int mode)
+int HDMIDisplay::getModeOrder(int mode)
{
for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
if (gEDIDData[dataIndex].mMode == mode) {
@@ -415,7 +426,7 @@
}
/// Returns the user mode set(if any) using adb shell
-int ExternalDisplay::getUserMode() {
+int HDMIDisplay::getUserMode() {
/* Based on the property set the resolution */
char property_value[PROPERTY_VALUE_MAX];
property_get("hw.hdmi.resolution", property_value, "-1");
@@ -429,7 +440,7 @@
}
// Get the best mode for the current HD TV
-int ExternalDisplay::getBestMode() {
+int HDMIDisplay::getBestMode() {
int bestOrder = 0;
int bestMode = HDMI_VFRMT_640x480p60_4_3;
// for all the edid read, get the best mode
@@ -444,7 +455,7 @@
return bestMode;
}
-inline bool ExternalDisplay::isValidMode(int ID)
+inline bool HDMIDisplay::isValidMode(int ID)
{
bool valid = false;
for (int i = 0; i < mModeCount; i++) {
@@ -457,7 +468,7 @@
}
// returns true if the mode(ID) is interlaced mode format
-bool ExternalDisplay::isInterlacedMode(int ID) {
+bool HDMIDisplay::isInterlacedMode(int ID) {
bool interlaced = false;
switch(ID) {
case HDMI_VFRMT_1440x480i60_4_3:
@@ -476,7 +487,7 @@
// Does a put_vscreen info on the HDMI interface which will update
// the configuration (resolution, timing info) to match mCurrentMode
-void ExternalDisplay::activateDisplay()
+void HDMIDisplay::activateDisplay()
{
int ret = 0;
ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
@@ -526,7 +537,7 @@
}
}
-bool ExternalDisplay::writeHPDOption(int userOption) const
+bool HDMIDisplay::writeHPDOption(int userOption) const
{
bool ret = true;
if(mFbNum != -1) {
@@ -550,7 +561,7 @@
}
-void ExternalDisplay::setAttributes() {
+void HDMIDisplay::setAttributes() {
uint32_t fps = 0;
// Always set dpyAttr res to mVInfo res
getAttrForMode(mXres, mYres, fps);
@@ -619,7 +630,7 @@
ALOGD_IF(DEBUG, "%s xres=%d, yres=%d", __FUNCTION__, mXres, mYres);
}
-void ExternalDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
+void HDMIDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
uint32_t& fps) {
for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
if (gEDIDData[dataIndex].mMode == mCurrentMode) {
@@ -633,7 +644,7 @@
}
/* returns the fd related to the node specified*/
-int ExternalDisplay::openDeviceNode(const char* node, int fileMode) const {
+int HDMIDisplay::openDeviceNode(const char* node, int fileMode) const {
char sysFsFilePath[MAX_SYSFS_FILE_PATH];
memset(sysFsFilePath, 0, sizeof(sysFsFilePath));
snprintf(sysFsFilePath , sizeof(sysFsFilePath),
@@ -649,12 +660,12 @@
return fd;
}
-bool ExternalDisplay::isHDMIPrimaryDisplay() {
+bool HDMIDisplay::isHDMIPrimaryDisplay() {
int hdmiNode = qdutils::getHDMINode();
return (hdmiNode == HWC_DISPLAY_PRIMARY);
}
-int ExternalDisplay::getConnectedState() {
+int HDMIDisplay::getConnectedState() {
int ret = -1;
int mFbNum = qdutils::getHDMINode();
int connectedNode = openDeviceNode("connected", O_RDONLY);
@@ -679,7 +690,7 @@
return ret;
}
-void ExternalDisplay::setPrimaryAttributes(uint32_t primaryWidth,
+void HDMIDisplay::setPrimaryAttributes(uint32_t primaryWidth,
uint32_t primaryHeight) {
mPrimaryHeight = primaryHeight;
mPrimaryWidth = primaryWidth;
diff --git a/libexternal/external.h b/libhdmi/hdmi.h
similarity index 90%
rename from libexternal/external.h
rename to libhdmi/hdmi.h
index fa98de9..605d9be 100644
--- a/libexternal/external.h
+++ b/libhdmi/hdmi.h
@@ -18,8 +18,8 @@
* limitations under the License.
*/
-#ifndef HWC_EXTERNAL_DISPLAY_H
-#define HWC_EXTERNAL_DISPLAY_H
+#ifndef HWC_HDMI_DISPLAY_H
+#define HWC_HDMI_DISPLAY_H
#include <linux/fb.h>
@@ -28,11 +28,11 @@
namespace qhwc {
//Type of scanning of EDID(Video Capability Data Block)
-enum external_scansupport_type {
- EXT_SCAN_NOT_SUPPORTED = 0,
- EXT_SCAN_ALWAYS_OVERSCANED = 1,
- EXT_SCAN_ALWAYS_UNDERSCANED = 2,
- EXT_SCAN_BOTH_SUPPORTED = 3
+enum hdmi_scansupport_type {
+ HDMI_SCAN_NOT_SUPPORTED = 0,
+ HDMI_SCAN_ALWAYS_OVERSCANED = 1,
+ HDMI_SCAN_ALWAYS_UNDERSCANED = 2,
+ HDMI_SCAN_BOTH_SUPPORTED = 3
};
// Structure to store EDID related data
@@ -45,11 +45,11 @@
{ }
};
-class ExternalDisplay
+class HDMIDisplay
{
public:
- ExternalDisplay();
- ~ExternalDisplay();
+ HDMIDisplay();
+ ~HDMIDisplay();
void setHPD(uint32_t startEnd);
void setActionSafeDimension(int w, int h);
bool isCEUnderscanSupported() { return mUnderscanSupported; }
@@ -107,4 +107,4 @@
}; //qhwc
// ---------------------------------------------------------------------------
-#endif //HWC_EXTERNAL_DISPLAY_H
+#endif //HWC_HDMI_DISPLAY_H
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 8e3fc8e..df3e464 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -9,7 +9,7 @@
$(TOP)/external/skia/include/core \
$(TOP)/external/skia/include/images
LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay \
- libexternal libqdutils libhardware_legacy \
+ libhdmi libqdutils libhardware_legacy \
libdl libmemalloc libqservice libsync \
libbinder libmedia
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index ae1389d..288b2e0 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -34,7 +34,7 @@
#include "hwc_fbupdate.h"
#include "hwc_mdpcomp.h"
#include "hwc_dump_layers.h"
-#include "external.h"
+#include "hdmi.h"
#include "hwc_copybit.h"
#include "hwc_ad.h"
#include "profiler.h"
@@ -442,7 +442,7 @@
if(mode == HWC_POWER_MODE_NORMAL) {
// Enable HPD here, as during bootup POWER_MODE_NORMAL is set
// when SF is completely initialized
- ctx->mExtDisplay->setHPD(1);
+ ctx->mHDMIDisplay->setHPD(1);
}
ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index 679e6d6..7e96d97 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -34,7 +34,6 @@
#include <mdp_version.h>
#include "hwc_ad.h"
#include "hwc_utils.h"
-#include "external.h"
#define DEBUG 0
using namespace overlay;
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 7839139..43ae916 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -25,7 +25,6 @@
#include <overlayRotator.h>
#include "hwc_fbupdate.h"
#include "mdp_version.h"
-#include "external.h"
using namespace qdutils;
using namespace overlay;
@@ -514,12 +513,13 @@
based on an empirically derived value of panel height.
*/
- bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
+ const bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
qdutils::MDPVersion::getInstance().isSrcSplitAlways();
+ const uint32_t lSplit = getLeftSplit(ctx, mDpy);
+ const uint32_t cropWidth = sourceCrop.right - sourceCrop.left;
- if(((sourceCrop.right - sourceCrop.left) >
- (int)qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
- primarySplitAlways) {
+ if((cropWidth > qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
+ (primarySplitAlways and cropWidth > lSplit)) {
destR = ov.getPipe(pipeSpecs);
if(destR == ovutils::OV_INVALID) {
ALOGE("%s: No pipes available to configure fb for dpy %d's right"
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index f2cff45..bf764e6 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -19,7 +19,7 @@
#include <math.h>
#include "hwc_mdpcomp.h"
#include <sys/ioctl.h>
-#include "external.h"
+#include "hdmi.h"
#include "qdMetaData.h"
#include "mdp_version.h"
#include "hwc_fbupdate.h"
@@ -36,7 +36,7 @@
//==============MDPComp========================================================
-IdleInvalidator *MDPComp::idleInvalidator = NULL;
+IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
bool MDPComp::sIdleFallBack = false;
bool MDPComp::sHandleTimeout = false;
bool MDPComp::sDebugLogs = false;
@@ -110,7 +110,7 @@
return false;
}
- char property[PROPERTY_VALUE_MAX];
+ char property[PROPERTY_VALUE_MAX] = {0};
sEnabled = false;
if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
@@ -134,23 +134,10 @@
}
if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
- // Idle invalidation is not necessary on command mode panels
- long idle_timeout = DEFAULT_IDLE_TIME;
- if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
- if(atoi(property) != 0)
- idle_timeout = atoi(property);
- }
-
- //create Idle Invalidator only when not disabled through property
- if(idle_timeout != -1)
- idleInvalidator = IdleInvalidator::getInstance();
-
- if(idleInvalidator == NULL) {
- ALOGE("%s: failed to instantiate idleInvalidator object",
- __FUNCTION__);
- } else {
- idleInvalidator->init(timeout_handler, ctx,
- (unsigned int)idle_timeout);
+ sIdleInvalidator = IdleInvalidator::getInstance();
+ if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
+ delete sIdleInvalidator;
+ sIdleInvalidator = NULL;
}
}
@@ -206,6 +193,25 @@
ctx->proc->invalidate(ctx->proc);
}
+void MDPComp::setIdleTimeout(const uint32_t& timeout) {
+ enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
+
+ if(sIdleInvalidator) {
+ if(timeout <= ONE_REFRESH_PERIOD_MS) {
+ //If the specified timeout is < 1 draw cycle worth, "virtually"
+ //disable idle timeout. The ideal way for clients to disable
+ //timeout is to set it to 0
+ sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
+ ALOGI("Disabled idle timeout");
+ return;
+ }
+ sIdleInvalidator->setIdleTimeout(timeout);
+ ALOGI("Idle timeout set to %u", timeout);
+ } else {
+ ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
+ }
+}
+
void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
hwc_display_contents_1_t* list) {
LayerProp *layerProp = ctx->layerProp[mDpy];
@@ -358,7 +364,7 @@
* There also is a HW limilation in MDP, minimum block size is 2x2
* Fallback to GPU if height is less than 2.
*/
- if((crop_w < 5)||(crop_h < 5))
+ if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
return false;
if((w_scale > 1.0f) || (h_scale > 1.0f)) {
@@ -2057,7 +2063,7 @@
}
// Set the Handle timeout to true for MDP or MIXED composition.
- if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
+ if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
sHandleTimeout = true;
}
@@ -2312,7 +2318,7 @@
}
// Set the Handle timeout to true for MDP or MIXED composition.
- if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
+ if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
sHandleTimeout = true;
}
@@ -2471,7 +2477,8 @@
mdpHw.isSrcSplitAlways();
int lSplit = getLeftSplit(ctx, mDpy);
int dstWidth = dst.right - dst.left;
- int cropWidth = crop.right - crop.left;
+ int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
+ crop.right - crop.left;
//TODO Even if a 4k video is going to be rot-downscaled to dimensions under
//pipe line length, we are still using 2 pipes. This is fine just because
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index e43c4f4..268e9aa 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -25,7 +25,6 @@
#include <cutils/properties.h>
#include <overlay.h>
-#define DEFAULT_IDLE_TIME 70
#define MAX_PIPES_PER_MIXER 4
namespace overlay {
@@ -57,6 +56,7 @@
static void resetIdleFallBack() { sIdleFallBack = false; }
static bool isIdleFallback() { return sIdleFallBack; }
static void dynamicDebug(bool enable){ sDebugLogs = enable; }
+ static void setIdleTimeout(const uint32_t& timeout);
protected:
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -255,7 +255,7 @@
static bool sHandleTimeout;
static int sMaxPipesPerMixer;
static bool sSrcSplitEnabled;
- static IdleInvalidator *idleInvalidator;
+ static IdleInvalidator *sIdleInvalidator;
struct FrameInfo mCurrentFrame;
struct LayerCache mCachedFrame;
//Enable 4kx2k yuv layer split
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 8490058..6bde3d2 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -245,6 +245,13 @@
}
}
+static void setIdleTimeout(hwc_context_t* ctx, const Parcel* inParcel) {
+ uint32_t timeout = (uint32_t)inParcel->readInt32();
+ ALOGD("%s :%u ms", __FUNCTION__, timeout);
+ Locker::Autolock _sl(ctx->mDrawLock);
+ MDPComp::setIdleTimeout(timeout);
+}
+
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -290,6 +297,9 @@
case IQService::DYNAMIC_DEBUG:
toggleDynamicDebug(mHwcContext, inParcel);
break;
+ case IQService::SET_IDLE_TIMEOUT:
+ setIdleTimeout(mHwcContext, inParcel);
+ break;
default:
ret = NO_ERROR;
}
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 821bfa9..65e041b 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -30,7 +30,7 @@
#include "hwc_mdpcomp.h"
#include "hwc_copybit.h"
#include "comptype.h"
-#include "external.h"
+#include "hdmi.h"
#include "hwc_virtual.h"
#include "mdp_version.h"
using namespace overlay;
@@ -109,7 +109,7 @@
Locker::Autolock _l(ctx->mDrawLock);
destroyCompositionResources(ctx, dpy);
- ctx->mExtDisplay->teardown();
+ ctx->mHDMIDisplay->teardown();
resetDisplayInfo(ctx, dpy);
/* We need to send hotplug to SF only when we are disconnecting
@@ -163,8 +163,8 @@
"uevent thread", __FUNCTION__);
ctx->mWfdSyncLock.unlock();
}
- ctx->mExtDisplay->configure();
- ctx->mExtDisplay->activateDisplay();
+ ctx->mHDMIDisplay->configure();
+ ctx->mHDMIDisplay->activateDisplay();
Locker::Autolock _l(ctx->mDrawLock);
updateDisplayInfo(ctx, dpy);
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 44725de..7cf390e 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -37,12 +37,13 @@
#include "mdp_version.h"
#include "hwc_copybit.h"
#include "hwc_dump_layers.h"
-#include "external.h"
+#include "hdmi.h"
#include "hwc_qclient.h"
#include "QService.h"
#include "comptype.h"
#include "hwc_virtual.h"
#include "qd_utils.h"
+#include <sys/sysinfo.h>
using namespace qClient;
using namespace qService;
@@ -73,6 +74,11 @@
#endif
#endif
+#define PROP_DEFAULT_APPBUFFER "ro.sf.default_app_buffer"
+#define MAX_RAM_SIZE 512*1024*1024
+#define qHD_WIDTH 540
+
+
namespace qhwc {
//Std refresh rates for digital videos- 24p, 30p and 48p
@@ -112,21 +118,21 @@
}
}
-// Initialize external display attributes based on
-// external display class state
+// Initialize hdmi display attributes based on
+// hdmi display class state
void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
- ctx->dpyAttr[dpy].fd = ctx->mExtDisplay->getFd();
- ctx->dpyAttr[dpy].xres = ctx->mExtDisplay->getWidth();
- ctx->dpyAttr[dpy].yres = ctx->mExtDisplay->getHeight();
- ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mExtDisplay->getMDPScalingMode();
- ctx->dpyAttr[dpy].vsync_period = ctx->mExtDisplay->getVsyncPeriod();
+ ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
+ ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
+ ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
+ ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mHDMIDisplay->getMDPScalingMode();
+ ctx->dpyAttr[dpy].vsync_period = ctx->mHDMIDisplay->getVsyncPeriod();
ctx->mViewFrame[dpy].left = 0;
ctx->mViewFrame[dpy].top = 0;
ctx->mViewFrame[dpy].right = ctx->dpyAttr[dpy].xres;
ctx->mViewFrame[dpy].bottom = ctx->dpyAttr[dpy].yres;
}
-// Reset external display attributes and list stats structures
+// Reset hdmi display attributes and list stats structures
void resetDisplayInfo(hwc_context_t* ctx, int dpy) {
memset(&(ctx->dpyAttr[dpy]), 0, sizeof(ctx->dpyAttr[dpy]));
memset(&(ctx->listStats[dpy]), 0, sizeof(ctx->listStats[dpy]));
@@ -232,6 +238,25 @@
return 0;
}
+static void changeDefaultAppBufferCount() {
+ struct sysinfo info;
+ unsigned long int ramSize = 0;
+ if (!sysinfo(&info)) {
+ ramSize = info.totalram ;
+ }
+ int fb_fd = -1;
+ struct fb_var_screeninfo sInfo ={0};
+ fb_fd = open("/dev/graphics/fb0", O_RDONLY);
+ if (fb_fd >=0) {
+ ioctl(fb_fd, FBIOGET_VSCREENINFO, &sInfo);
+ close(fb_fd);
+ }
+ if ((ramSize && ramSize < MAX_RAM_SIZE) &&
+ (sInfo.xres && sInfo.xres <= qHD_WIDTH )) {
+ property_set(PROP_DEFAULT_APPBUFFER, "2");
+ }
+}
+
void initContext(hwc_context_t *ctx)
{
openFramebufferDevice(ctx);
@@ -243,6 +268,10 @@
ctx->mOverlay = overlay::Overlay::getInstance();
ctx->mRotMgr = RotMgr::getInstance();
+ //default_app_buffer for ferrum
+ if (ctx->mMDP.version == qdutils::MDP_V3_0_5) {
+ changeDefaultAppBufferCount();
+ }
// Initialize composition objects for the primary display
initCompositionResources(ctx, HWC_DISPLAY_PRIMARY);
@@ -260,12 +289,12 @@
HWC_DISPLAY_PRIMARY);
}
- ctx->mExtDisplay = new ExternalDisplay();
- // Send the primary resolution to the external display class
+ ctx->mHDMIDisplay = new HDMIDisplay();
+ // Send the primary resolution to the hdmi display class
// to be used for MDP scaling functionality
uint32_t priW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
uint32_t priH = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
- ctx->mExtDisplay->setPrimaryAttributes(priW, priH);
+ ctx->mHDMIDisplay->setPrimaryAttributes(priW, priH);
ctx->mHWCVirtual = new HWCVirtualVDS();
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
@@ -366,9 +395,9 @@
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
}
- if(ctx->mExtDisplay) {
- delete ctx->mExtDisplay;
- ctx->mExtDisplay = NULL;
+ if(ctx->mHDMIDisplay) {
+ delete ctx->mHDMIDisplay;
+ ctx->mHDMIDisplay = NULL;
}
for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
@@ -478,7 +507,7 @@
if(ctx->dpyAttr[dpy].mMDPScalingMode) {
// if MDP scaling mode is enabled for external, need to query
// the actual width and height, as that is the physical w & h
- ctx->mExtDisplay->getAttributes(fbWidth, fbHeight);
+ ctx->mHDMIDisplay->getAttributes(fbWidth, fbHeight);
}
@@ -610,7 +639,7 @@
if(ctx->dpyAttr[dpy].mMDPScalingMode) {
uint32_t extW = 0, extH = 0;
if(dpy == HWC_DISPLAY_EXTERNAL) {
- ctx->mExtDisplay->getAttributes(extW, extH);
+ ctx->mHDMIDisplay->getAttributes(extW, extH);
} else if(dpy == HWC_DISPLAY_VIRTUAL) {
extW = ctx->mHWCVirtual->getScalingWidth();
extH = ctx->mHWCVirtual->getScalingHeight();
@@ -696,7 +725,7 @@
float fbHeight = (float)ctx->dpyAttr[dpy].yres;
// query MDP configured attributes
if(dpy == HWC_DISPLAY_EXTERNAL) {
- ctx->mExtDisplay->getAttributes(extW, extH);
+ ctx->mHDMIDisplay->getAttributes(extW, extH);
} else if(dpy == HWC_DISPLAY_VIRTUAL) {
extW = ctx->mHWCVirtual->getScalingWidth();
extH = ctx->mHWCVirtual->getScalingHeight();
@@ -1114,7 +1143,7 @@
// Disable Actionsafe for non HDMI displays.
if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
qdutils::MDPVersion::getInstance().is8x74v2() ||
- ctx->mExtDisplay->isCEUnderscanSupported()) {
+ ctx->mHDMIDisplay->isCEUnderscanSupported()) {
return false;
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 041ca74..cae22f1 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -62,7 +62,7 @@
namespace qhwc {
//fwrd decl
class QueuedBufferStore;
-class ExternalDisplay;
+class HDMIDisplay;
class VirtualDisplay;
class IFBUpdate;
class IVideoOverlay;
@@ -545,8 +545,9 @@
//Primary and external FB updater
qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
- // External display related information
- qhwc::ExternalDisplay *mExtDisplay;
+ // HDMI display related object. Used to configure/teardown
+ // HDMI when it is connected as primary or external.
+ qhwc::HDMIDisplay *mHDMIDisplay;
qhwc::MDPInfo mMDP;
qhwc::VsyncState vstate;
qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 66988f7..07d1e4e 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -29,7 +29,6 @@
#include "hwc_utils.h"
#include "qd_utils.h"
#include "string.h"
-#include "external.h"
#include "overlay.h"
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
diff --git a/libqdutils/idle_invalidator.cpp b/libqdutils/idle_invalidator.cpp
index 86191e9..5850ce5 100644
--- a/libqdutils/idle_invalidator.cpp
+++ b/libqdutils/idle_invalidator.cpp
@@ -47,10 +47,13 @@
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
}
-int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data,
- unsigned int idleSleepTime) {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s idleSleepTime %d",
- __FUNCTION__, idleSleepTime);
+IdleInvalidator::~IdleInvalidator() {
+ if(mTimeoutEventFd >= 0) {
+ close(mTimeoutEventFd);
+ }
+}
+
+int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data) {
mHandler = reg_handler;
mHwcContext = user_data;
@@ -62,34 +65,47 @@
return -1;
}
- // Open a sysfs node to send the timeout value to driver.
- int fd = open(IDLE_TIME_PATH, O_WRONLY);
- if (fd < 0) {
- ALOGE ("%s:not able to open %s node %s",
- __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+ enum {DEFAULT_IDLE_TIME = 70}; //ms
+ if(not setIdleTimeout(DEFAULT_IDLE_TIME)) {
close(mTimeoutEventFd);
mTimeoutEventFd = -1;
return -1;
}
- char strSleepTime[64];
- snprintf(strSleepTime, sizeof(strSleepTime), "%d", idleSleepTime);
- // Notify driver about the timeout value
- ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
- if(len < -1) {
- ALOGE ("%s:not able to write into %s node %s",
- __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
- close(mTimeoutEventFd);
- mTimeoutEventFd = -1;
- close(fd);
- return -1;
- }
- close(fd);
//Triggers the threadLoop to run, if not already running.
run(threadName, android::PRIORITY_LOWEST);
return 0;
}
+bool IdleInvalidator::setIdleTimeout(const uint32_t& timeout) {
+ ALOGD_IF(II_DEBUG, "IdleInvalidator::%s timeout %d",
+ __FUNCTION__, timeout);
+
+ // Open a sysfs node to send the timeout value to driver.
+ int fd = open(IDLE_TIME_PATH, O_WRONLY);
+
+ if (fd < 0) {
+ ALOGE ("%s:Unable to open %s node %s",
+ __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+ return false;
+ }
+
+ char strSleepTime[64];
+ snprintf(strSleepTime, sizeof(strSleepTime), "%d", timeout);
+
+ // Notify driver about the timeout value
+ ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
+ if(len < -1) {
+ ALOGE ("%s:Unable to write into %s node %s",
+ __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+ close(fd);
+ return false;
+ }
+
+ close(fd);
+ return true;
+}
+
bool IdleInvalidator::threadLoop() {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
struct pollfd pFd;
diff --git a/libqdutils/idle_invalidator.h b/libqdutils/idle_invalidator.h
index a881c4b..52334a0 100644
--- a/libqdutils/idle_invalidator.h
+++ b/libqdutils/idle_invalidator.h
@@ -37,16 +37,18 @@
typedef void (*InvalidatorHandler)(void*);
class IdleInvalidator : public android::Thread {
+ IdleInvalidator();
void *mHwcContext;
int mTimeoutEventFd;
static InvalidatorHandler mHandler;
static android::sp<IdleInvalidator> sInstance;
- public:
- IdleInvalidator();
+public:
+ ~IdleInvalidator();
/* init timer obj */
- int init(InvalidatorHandler reg_handler, void* user_data, unsigned int
- idleSleepTime);
+ int init(InvalidatorHandler reg_handler, void* user_data);
+ bool setIdleTimeout(const uint32_t& timeout);
+
/*Overrides*/
virtual bool threadLoop();
virtual int readyToRun();
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index b0a8d7d..088f82b 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -411,6 +411,10 @@
}
+bool MDPVersion::hasMinCropWidthLimitation() const {
+ return mMdpRev <= MDSS_MDP_HW_REV_102;
+}
+
bool MDPVersion::supportsDecimation() {
return mFeatures & MDP_DECIMATION_EN;
}
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index d26c55c..3c7f6a3 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -138,6 +138,7 @@
uint32_t getMinFpsSupported() { return mPanelInfo.mMinFps; }
uint32_t getMaxFpsSupported() { return mPanelInfo.mMaxFps; }
uint32_t getMaxMixerWidth() const { return mMaxMixerWidth; }
+ bool hasMinCropWidthLimitation() const;
bool isSrcSplit() const;
bool isSrcSplitAlways() const;
bool isRGBScalarSupported() const;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 30c064e..3be20f1 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -53,6 +53,7 @@
SET_WFD_STATUS, // Set if wfd connection is on/off
SET_VIEW_FRAME, // Set view frame of display
DYNAMIC_DEBUG, // Enable more logging on the fly
+ SET_IDLE_TIMEOUT, // Set idle timeout for GPU fallback
COMMAND_LIST_END = 400,
};