hwc: Add support for color mode switching
Add a ColorMode class to HWC to manage color modes and expose them as display attributes to SurfaceFlinger Change-Id: I1010096120db6aec61163a84390527f5a0a3645e
This commit is contained in:
parent
72579d94ed
commit
6109f69d57
|
@ -17,7 +17,8 @@ ifeq ($(TARGET_USES_QCOM_BSP),true)
|
|||
LOCAL_SHARED_LIBRARIES += libskia
|
||||
endif #TARGET_USES_QCOM_BSP
|
||||
|
||||
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
|
||||
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\" \
|
||||
-std=c++11
|
||||
#Enable Dynamic FPS if PHASE_OFFSET is not set
|
||||
ifeq ($(VSYNC_EVENT_PHASE_OFFSET_NS),)
|
||||
LOCAL_CFLAGS += -DDYNAMIC_FPS
|
||||
|
|
|
@ -772,8 +772,15 @@ int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
|
|||
if (hotPluggable) {
|
||||
ctx->mHDMIDisplay->getDisplayConfigs(configs, numConfigs);
|
||||
} else {
|
||||
configs[0] = 0;
|
||||
*numConfigs = 1;
|
||||
if(ctx->mColorMode->getNumModes() > 0) {
|
||||
*numConfigs = ctx->mColorMode->getNumModes();
|
||||
for (size_t i = 0; i < *numConfigs; i++)
|
||||
configs[i] = (uint32_t) i;
|
||||
|
||||
} else {
|
||||
configs[0] = 0;
|
||||
*numConfigs = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HWC_DISPLAY_EXTERNAL:
|
||||
|
@ -801,22 +808,6 @@ int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
//From HWComposer
|
||||
static const uint32_t DISPLAY_ATTRIBUTES[] = {
|
||||
HWC_DISPLAY_VSYNC_PERIOD,
|
||||
HWC_DISPLAY_WIDTH,
|
||||
HWC_DISPLAY_HEIGHT,
|
||||
HWC_DISPLAY_DPI_X,
|
||||
HWC_DISPLAY_DPI_Y,
|
||||
#ifdef QCOM_BSP
|
||||
HWC_DISPLAY_SECURE,
|
||||
#endif
|
||||
HWC_DISPLAY_NO_ATTRIBUTE,
|
||||
};
|
||||
|
||||
const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
|
||||
sizeof(DISPLAY_ATTRIBUTES)[0]);
|
||||
|
||||
uint32_t xres = 0, yres = 0, refresh = 0;
|
||||
int ret = 0;
|
||||
if (hotPluggable) {
|
||||
|
@ -828,7 +819,7 @@ int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
|
|||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
|
||||
for (size_t i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
|
||||
switch (attributes[i]) {
|
||||
case HWC_DISPLAY_VSYNC_PERIOD:
|
||||
values[i] =
|
||||
|
@ -857,11 +848,9 @@ int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
|
|||
case HWC_DISPLAY_DPI_Y:
|
||||
values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
|
||||
break;
|
||||
#ifdef QCOM_BSP
|
||||
case HWC_DISPLAY_SECURE:
|
||||
values[i] = (int32_t) (ctx->dpyAttr[disp].secure);
|
||||
case HWC_DISPLAY_COLOR_TRANSFORM:
|
||||
values[i] = ctx->mColorMode->getModeForIndex(config);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ALOGE("Unknown display attribute %d",
|
||||
attributes[i]);
|
||||
|
@ -914,7 +903,9 @@ int hwc_getActiveConfig(struct hwc_composer_device_1* dev, int disp)
|
|||
|
||||
// For use cases when primary panel is the default interface we only have
|
||||
// the default config (0th index)
|
||||
if (!hotPluggable) {
|
||||
if (!hotPluggable && HWC_DISPLAY_PRIMARY) {
|
||||
return ctx->mColorMode->getActiveModeIndex();
|
||||
} else if (isVirtualDisplay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -934,10 +925,12 @@ int hwc_setActiveConfig(struct hwc_composer_device_1* dev, int disp, int index)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
// For use cases when primary panel is the default interface we only have
|
||||
// the default config (0th index)
|
||||
if (!hotPluggable) {
|
||||
// Primary and virtual supports only the default config (0th index)
|
||||
// For use cases when primary panel is the default interface we only switch
|
||||
// color modes
|
||||
if(!hotPluggable && disp == HWC_DISPLAY_PRIMARY) {
|
||||
return ctx->mColorMode->applyModeByIndex(index);
|
||||
} else if (isVirtualDisplay) {
|
||||
// virtual supports only the default config (0th index)
|
||||
return (index == 0) ? index : -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -340,25 +340,11 @@ static void toggleScreenUpdate(hwc_context_t* ctx, uint32_t on) {
|
|||
}
|
||||
|
||||
static void applyModeById(hwc_context_t* ctx, int32_t modeId) {
|
||||
int (*applyMode)(int, int) = NULL;
|
||||
void *modeHandle = NULL;
|
||||
|
||||
modeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
|
||||
if (modeHandle) {
|
||||
*(void **)&applyMode = dlsym(modeHandle, "applyModeById");
|
||||
if (applyMode) {
|
||||
int err = applyMode(modeId, HWC_DISPLAY_PRIMARY);
|
||||
if (err)
|
||||
ALOGD("%s: Not able to apply mode: %d", __FUNCTION__, modeId);
|
||||
else
|
||||
ctx->proc->invalidate(ctx->proc);
|
||||
} else {
|
||||
ALOGE("%s: No symbol applyModeById found", __FUNCTION__);
|
||||
}
|
||||
dlclose(modeHandle);
|
||||
} else {
|
||||
ALOGE("%s: Not able to load libmm-qdcm.so", __FUNCTION__);
|
||||
}
|
||||
int err = ctx->mColorMode->applyModeByID(modeId);
|
||||
if (err)
|
||||
ALOGD("%s: Not able to apply mode: %d", __FUNCTION__, modeId);
|
||||
else
|
||||
ctx->proc->invalidate(ctx->proc);
|
||||
}
|
||||
|
||||
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
|
||||
|
|
|
@ -418,6 +418,8 @@ void initContext(hwc_context_t *ctx)
|
|||
|
||||
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
|
||||
ctx->mHPDEnabled = false;
|
||||
ctx->mColorMode = new ColorMode();
|
||||
ctx->mColorMode->init();
|
||||
ALOGI("Initializing Qualcomm Hardware Composer");
|
||||
ALOGI("MDP version: %d", ctx->mMDP.version);
|
||||
}
|
||||
|
@ -472,7 +474,11 @@ void closeContext(hwc_context_t *ctx)
|
|||
ctx->mAD = NULL;
|
||||
}
|
||||
|
||||
|
||||
if(ctx->mColorMode) {
|
||||
ctx->mColorMode->destroy();
|
||||
delete ctx->mColorMode;
|
||||
ctx->mColorMode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//Helper to roundoff the refreshrates
|
||||
|
@ -2505,8 +2511,6 @@ bool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
|
|||
void processBootAnimCompleted(hwc_context_t *ctx) {
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
int boot_finished = 0, ret = -1;
|
||||
int (*applyMode)(int) = NULL;
|
||||
void *modeHandle = NULL;
|
||||
|
||||
// Reading property set on boot finish in SF
|
||||
property_get("service.bootanim.exit", value, "0");
|
||||
|
@ -2514,21 +2518,9 @@ void processBootAnimCompleted(hwc_context_t *ctx) {
|
|||
if (!boot_finished)
|
||||
return;
|
||||
|
||||
modeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
|
||||
if (modeHandle) {
|
||||
*(void **)&applyMode = dlsym(modeHandle, "applyDefaults");
|
||||
if (applyMode) {
|
||||
ret = applyMode(HWC_DISPLAY_PRIMARY);
|
||||
if (ret)
|
||||
ALOGD("%s: Not able to apply default mode", __FUNCTION__);
|
||||
} else {
|
||||
ALOGE("%s: No symbol applyDefaults found", __FUNCTION__);
|
||||
}
|
||||
dlclose(modeHandle);
|
||||
} else {
|
||||
ALOGE("%s: Not able to load libmm-qdcm.so", __FUNCTION__);
|
||||
}
|
||||
|
||||
ret = ctx->mColorMode->applyDefaultMode();
|
||||
if (ret)
|
||||
ALOGD("%s: Not able to apply default mode", __FUNCTION__);
|
||||
ctx->mBootAnimCompleted = true;
|
||||
}
|
||||
|
||||
|
@ -2851,4 +2843,104 @@ void handle_offline(hwc_context_t* ctx, int dpy) {
|
|||
}
|
||||
}
|
||||
|
||||
void ColorMode::init() {
|
||||
//Map symbols from libmm-qdcm and get list of modes
|
||||
mModeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
|
||||
if (mModeHandle) {
|
||||
*(void **)& fnApplyDefaultMode = dlsym(mModeHandle, "applyDefaults");
|
||||
*(void **)& fnApplyModeById = dlsym(mModeHandle, "applyModeById");
|
||||
*(void **)& fnGetNumModes = dlsym(mModeHandle, "getNumDisplayModes");
|
||||
*(void **)& fnGetModeList = dlsym(mModeHandle, "getDisplayModeIdList");
|
||||
*(void **)& fnSetDefaultMode = dlsym(mModeHandle, "setDefaultMode");
|
||||
} else {
|
||||
ALOGW("Unable to load libmm-qdcm");
|
||||
}
|
||||
|
||||
if(fnGetNumModes) {
|
||||
mNumModes = fnGetNumModes(HWC_DISPLAY_PRIMARY);
|
||||
if(mNumModes > MAX_NUM_COLOR_MODES) {
|
||||
ALOGE("Number of modes is above the limit: %d", mNumModes);
|
||||
mNumModes = 0;
|
||||
return;
|
||||
}
|
||||
if(fnGetModeList) {
|
||||
fnGetModeList(mModeList, &mCurMode, HWC_DISPLAY_PRIMARY);
|
||||
mCurModeIndex = getIndexForMode(mCurMode);
|
||||
ALOGI("ColorMode: current mode: %d current mode index: %d number of modes: %d",
|
||||
mCurMode, mCurModeIndex, mNumModes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Legacy API
|
||||
int ColorMode::applyDefaultMode() {
|
||||
if(fnApplyDefaultMode) {
|
||||
return fnApplyDefaultMode(HWC_DISPLAY_PRIMARY);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ColorMode::applyModeByID(int modeID) {
|
||||
if(fnApplyModeById) {
|
||||
int ret = fnApplyModeById(modeID, HWC_DISPLAY_PRIMARY);
|
||||
if (!ret)
|
||||
ret = setDefaultMode(modeID);
|
||||
return ret;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
//This API is called from setActiveConfig
|
||||
//The value here must be set as default
|
||||
int ColorMode::applyModeByIndex(int index) {
|
||||
int ret = 0;
|
||||
int mode = getModeForIndex(index);
|
||||
if(mode < 0) {
|
||||
ALOGE("Invalid mode for index: %d", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
ALOGD("%s: Applying mode index: %d modeID: %d", __FUNCTION__, index, mode);
|
||||
ret = applyModeByID(mode);
|
||||
if(!ret) {
|
||||
mCurModeIndex = index;
|
||||
setDefaultMode(mode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ColorMode::setDefaultMode(int modeID) {
|
||||
if(fnSetDefaultMode) {
|
||||
ALOGD("Setting default color mode to %d", modeID);
|
||||
return fnSetDefaultMode(modeID, HWC_DISPLAY_PRIMARY);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ColorMode::getModeForIndex(int index) {
|
||||
if(index < mNumModes) {
|
||||
return mModeList[index];
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ColorMode::getIndexForMode(int mode) {
|
||||
if(mModeList) {
|
||||
for(int32_t i = 0; i < mNumModes; i++)
|
||||
if(mModeList[i] == mode)
|
||||
return i;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void ColorMode::destroy() {
|
||||
if(mModeHandle) {
|
||||
dlclose(mModeHandle);
|
||||
mModeHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
};//namespace qhwc
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define STR(f) #f;
|
||||
// Max number of PTOR layers handled
|
||||
#define MAX_PTOR_LAYERS 2
|
||||
#define MAX_NUM_COLOR_MODES 32
|
||||
|
||||
//Fwrd decls
|
||||
struct hwc_context_t;
|
||||
|
@ -229,6 +230,36 @@ private:
|
|||
uint32_t mCount;
|
||||
};
|
||||
|
||||
//ColorModes for primary displays
|
||||
class ColorMode {
|
||||
public:
|
||||
void init();
|
||||
void destroy();
|
||||
int32_t getNumModes() { return mNumModes; }
|
||||
const int32_t* getModeList() { return mModeList; }
|
||||
int32_t getModeForIndex(int32_t index);
|
||||
int32_t getIndexForMode(int32_t mode);
|
||||
int applyDefaultMode();
|
||||
int applyModeByID(int modeID);
|
||||
int applyModeByIndex(int index);
|
||||
int setDefaultMode(int modeID);
|
||||
int getActiveModeIndex() { return mCurModeIndex; }
|
||||
private:
|
||||
int32_t (*fnGetNumModes)(int /*dispID*/);
|
||||
int32_t (*fnGetModeList)(int32_t* /*mModeList*/, int32_t* /*current default*/,
|
||||
int32_t /*dispID*/);
|
||||
int (*fnApplyDefaultMode)(int /*dispID*/);
|
||||
int (*fnApplyModeById)(int /*modeID*/, int /*dispID*/);
|
||||
int (*fnSetDefaultMode)(int /*modeID*/, int /*dispID*/);
|
||||
|
||||
void* mModeHandle = NULL;
|
||||
int32_t mModeList[MAX_NUM_COLOR_MODES];
|
||||
int32_t mNumModes = 0;
|
||||
int32_t mCurModeIndex = 0;
|
||||
int32_t mCurMode = 0;
|
||||
|
||||
};
|
||||
|
||||
inline uint32_t LayerRotMap::getCount() const {
|
||||
return mCount;
|
||||
}
|
||||
|
@ -650,6 +681,8 @@ struct hwc_context_t {
|
|||
bool mHPDEnabled;
|
||||
//Used to notify that boot has completed
|
||||
bool mBootAnimCompleted;
|
||||
//Manages color modes
|
||||
qhwc::ColorMode *mColorMode;
|
||||
};
|
||||
|
||||
namespace qhwc {
|
||||
|
|
Loading…
Reference in New Issue