Merge "qdutils : Retain the system property for default idle time."
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 2302d64..da18c7b 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -126,6 +126,8 @@
static int get_format(int format) {
switch (format) {
case HAL_PIXEL_FORMAT_RGB_565: return MDP_RGB_565;
+ case HAL_PIXEL_FORMAT_RGBA_5551: return MDP_RGBA_5551;
+ case HAL_PIXEL_FORMAT_RGBA_4444: return MDP_RGBA_4444;
case HAL_PIXEL_FORMAT_RGBX_8888: return MDP_RGBX_8888;
case HAL_PIXEL_FORMAT_BGRX_8888: return MDP_BGRX_8888;
case HAL_PIXEL_FORMAT_RGB_888: return MDP_RGB_888;
@@ -440,6 +442,8 @@
// we don't support plane alpha with RGBA formats
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
src->format);
return -EINVAL;
@@ -580,7 +584,6 @@
struct blitReq list1;
memset((char *)&list1 , 0 ,sizeof (struct blitReq) );
list1.count = 1;
- int rel_fen_fd = -1;
int my_tmp_get_fence = -1;
list1.sync.acq_fen_fd = ctx->acqFence;
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index dbb89f0..9a6de9b 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -48,6 +48,8 @@
COPYBIT_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888,
COPYBIT_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565,
COPYBIT_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888,
+ COPYBIT_FORMAT_RGBA_5551 = HAL_PIXEL_FORMAT_RGBA_5551,
+ COPYBIT_FORMAT_RGBA_4444 = HAL_PIXEL_FORMAT_RGBA_4444,
COPYBIT_FORMAT_YCbCr_422_SP = 0x10,
COPYBIT_FORMAT_YCrCb_420_SP = 0x11,
};
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 7841bb7..23daa27 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -265,6 +265,8 @@
case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB |
C2D_FORMAT_SWAP_RB;
case HAL_PIXEL_FORMAT_BGRA_8888: return C2D_COLOR_FORMAT_8888_ARGB;
+ case HAL_PIXEL_FORMAT_RGBA_5551: return C2D_COLOR_FORMAT_5551_RGBA;
+ case HAL_PIXEL_FORMAT_RGBA_4444: return C2D_COLOR_FORMAT_4444_RGBA;
case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV12;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV21;
@@ -403,7 +405,9 @@
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_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444: {
return COPYBIT_SUCCESS;
}
default:
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index c361095..4167ae2 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -141,6 +141,8 @@
bpp = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
bpp = 2;
break;
default: break;
@@ -294,6 +296,7 @@
// for targets/OEMs which do not need HW level protection
// do not set ion secure flag & MM heap. Fallback to IOMMU heap.
ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+ data.allocType |= private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER;
}
} else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
//MM Heap is exclusively a secure heap.
@@ -400,6 +403,8 @@
size = alignedw * alignedh * 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
case HAL_PIXEL_FORMAT_RAW_SENSOR:
size = alignedw * alignedh * 2;
break;
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 75b8349..d64914e 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -193,6 +193,8 @@
PRIV_FLAGS_NOT_MAPPED = 0x00001000,
// Display on external only
PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000,
+ // Set by HWC for protected non secure buffers
+ PRIV_FLAGS_PROTECTED_BUFFER = 0x00004000,
PRIV_FLAGS_VIDEO_ENCODER = 0x00010000,
PRIV_FLAGS_CAMERA_WRITE = 0x00020000,
PRIV_FLAGS_CAMERA_READ = 0x00040000,
diff --git a/libhdmi/hdmi.cpp b/libhdmi/hdmi.cpp
index 4fb7cfa..1aee664 100644
--- a/libhdmi/hdmi.cpp
+++ b/libhdmi/hdmi.cpp
@@ -101,15 +101,16 @@
}
readCEUnderscanInfo();
readResolution();
- // TODO: Move this to activate
/* Used for changing the resolution
- * getUserMode will get the preferred
- * mode set thru adb shell */
- mCurrentMode = getUserMode();
- if (mCurrentMode == -1) {
+ * getUserConfig will get the preferred
+ * config index set thru adb shell */
+ mActiveConfig = getUserConfig();
+ if (mActiveConfig == -1) {
//Get the best mode and set
- mCurrentMode = getBestMode();
+ mActiveConfig = getBestConfig();
}
+ // Set the mode corresponding to the active index
+ mCurrentMode = mEDIDModes[mActiveConfig];
setAttributes();
// set system property
property_set("hw.hdmiON", "1");
@@ -121,6 +122,14 @@
&& !strcmp(value, "true")) {
mMDPDownscaleEnabled = true;
}
+
+ // XXX: A debug property can be used to enable resolution change for
+ // testing purposes: debug.hwc.enable_resolution_change
+ mEnableResolutionChange = false;
+ if(property_get("debug.hwc.enable_resolution_change", value, "false")
+ && !strcmp(value, "true")) {
+ mEnableResolutionChange = true;
+ }
return 0;
}
@@ -425,8 +434,8 @@
return -1;
}
-/// Returns the user mode set(if any) using adb shell
-int HDMIDisplay::getUserMode() {
+/// Returns the index of the user mode set(if any) using adb shell
+int HDMIDisplay::getUserConfig() {
/* Based on the property set the resolution */
char property_value[PROPERTY_VALUE_MAX];
property_get("hw.hdmi.resolution", property_value, "-1");
@@ -434,15 +443,16 @@
// We dont support interlaced modes
if(isValidMode(mode) && !isInterlacedMode(mode)) {
ALOGD_IF(DEBUG, "%s: setting the HDMI mode = %d", __FUNCTION__, mode);
- return mode;
+ return getModeIndex(mode);
}
return -1;
}
-// Get the best mode for the current HD TV
-int HDMIDisplay::getBestMode() {
+// Get the index of the best mode for the current HD TV
+int HDMIDisplay::getBestConfig() {
int bestOrder = 0;
int bestMode = HDMI_VFRMT_640x480p60_4_3;
+ int bestModeIndex = -1;
// for all the edid read, get the best mode
for(int i = 0; i < mModeCount; i++) {
int mode = mEDIDModes[i];
@@ -450,9 +460,19 @@
if (order > bestOrder) {
bestOrder = order;
bestMode = mode;
+ bestModeIndex = i;
}
}
- return bestMode;
+ // If we fail to read from EDID when HDMI is connected, then
+ // mModeCount will be 0 and bestModeIndex will be invalid.
+ // In this case, we populate the mEDIDModes structure with
+ // a default mode at index 0.
+ if (bestModeIndex == -1) {
+ bestModeIndex = 0;
+ mModeCount = 1;
+ mEDIDModes[bestModeIndex] = bestMode;
+ }
+ return bestModeIndex;
}
inline bool HDMIDisplay::isValidMode(int ID)
@@ -696,4 +716,79 @@
mPrimaryWidth = primaryWidth;
}
+int HDMIDisplay::setActiveConfig(int newConfig) {
+ if(newConfig < 0 || newConfig > mModeCount) {
+ ALOGE("%s Invalid configuration %d", __FUNCTION__, newConfig);
+ return -EINVAL;
+ }
+
+ // XXX: Currently, we only support a change in frame rate.
+ // We need to validate the new config before proceeding.
+ if (!isValidConfigChange(newConfig)) {
+ ALOGE("%s Invalid configuration %d", __FUNCTION__, newConfig);
+ return -EINVAL;
+ }
+
+ mCurrentMode = mEDIDModes[newConfig];
+ mActiveConfig = newConfig;
+ activateDisplay();
+ ALOGD("%s config(%d) mode(%d)", __FUNCTION__, mActiveConfig, mCurrentMode);
+ return 0;
+}
+
+// returns false if the xres or yres of the new config do
+// not match the current config
+bool HDMIDisplay::isValidConfigChange(int newConfig) {
+ int newMode = mEDIDModes[newConfig];
+ uint32_t width = 0, height = 0, refresh = 0;
+ getAttrForConfig(newConfig, width, height, refresh);
+ return ((mXres == width) && (mYres == height)) || mEnableResolutionChange;
+}
+
+int HDMIDisplay::getModeIndex(int mode) {
+ int modeIndex = -1;
+ for(int i = 0; i < mModeCount; i++) {
+ if(mode == mEDIDModes[i]) {
+ modeIndex = i;
+ break;
+ }
+ }
+ return modeIndex;
+}
+
+int HDMIDisplay::getAttrForConfig(int config, uint32_t& xres,
+ uint32_t& yres, uint32_t& refresh) const {
+ if(config < 0 || config > mModeCount) {
+ ALOGE("%s Invalid configuration %d", __FUNCTION__, config);
+ return -EINVAL;
+ }
+ int mode = mEDIDModes[config];
+ uint32_t fps = 0;
+ // Retrieve the mode attributes from gEDIDData
+ for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
+ if (gEDIDData[dataIndex].mMode == mode) {
+ xres = gEDIDData[dataIndex].mWidth;
+ yres = gEDIDData[dataIndex].mHeight;
+ fps = gEDIDData[dataIndex].mFps;
+ }
+ }
+ refresh = (uint32_t) 1000000000l / fps;
+ ALOGD_IF(DEBUG, "%s xres(%d) yres(%d) fps(%d) refresh(%d)", __FUNCTION__,
+ xres, yres, fps, refresh);
+ return 0;
+}
+
+int HDMIDisplay::getDisplayConfigs(uint32_t* configs,
+ size_t* numConfigs) const {
+ if (*numConfigs <= 0) {
+ ALOGE("%s Invalid number of configs (%d)", __FUNCTION__, *numConfigs);
+ return -EINVAL;
+ }
+ *numConfigs = mModeCount;
+ for (int configIndex = 0; configIndex < mModeCount; configIndex++) {
+ configs[configIndex] = (uint32_t)configIndex;
+ }
+ return 0;
+}
+
};
diff --git a/libhdmi/hdmi.h b/libhdmi/hdmi.h
index 605d9be..d262a63 100644
--- a/libhdmi/hdmi.h
+++ b/libhdmi/hdmi.h
@@ -68,6 +68,11 @@
/* when HDMI is an EXTERNAL display, PRIMARY display attributes are needed
for scaling mode */
void setPrimaryAttributes(uint32_t primaryWidth, uint32_t primaryHeight);
+ int getActiveConfig() const { return mActiveConfig; };
+ int setActiveConfig(int newConfig);
+ int getAttrForConfig(int config, uint32_t& xres,
+ uint32_t& yres, uint32_t& refresh) const;
+ int getDisplayConfigs(uint32_t* configs, size_t* numConfigs) const;
private:
int getModeCount() const;
@@ -80,17 +85,26 @@
bool writeHPDOption(int userOption) const;
bool isValidMode(int mode);
int getModeOrder(int mode);
- int getUserMode();
- int getBestMode();
+ int getUserConfig();
+ int getBestConfig();
bool isInterlacedMode(int mode);
void resetInfo();
void setAttributes();
void getAttrForMode(uint32_t& width, uint32_t& height, uint32_t& fps);
int openDeviceNode(const char* node, int fileMode) const;
+ int getModeIndex(int mode);
+ bool isValidConfigChange(int newConfig);
int mFd;
int mFbNum;
+ // mCurrentMode is the HDMI video format that corresponds to the mEDIDMode
+ // entry referenced by mActiveConfig
int mCurrentMode;
+ // mActiveConfig is the index correponding to the currently active mode for
+ // the HDMI display. It basically indexes the mEDIDMode array
+ int mActiveConfig;
+ // mEDIDModes contains a list of HDMI video formats (modes) supported by the
+ // HDMI display
int mEDIDModes[64];
int mModeCount;
fb_var_screeninfo mVInfo;
@@ -102,6 +116,7 @@
// Downscale feature switch, set via system property
// sys.hwc.mdp_downscale_enabled
bool mMDPDownscaleEnabled;
+ bool mEnableResolutionChange;
int mDisplayId;
};
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index b5ba073..0a7f940 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -113,11 +113,12 @@
}
}
-/* Based on certain conditions, isPaddingRound will be set
+/* Based on certain conditions, isDMAStateChanging will be set
* to make this function self-contained */
static void setDMAState(hwc_context_t *ctx, int numDisplays,
hwc_display_contents_1_t** displays) {
+ ctx->isDMAStateChanging = false;
if(ctx->mRotMgr->getNumActiveSessions() == 0)
Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
@@ -142,7 +143,7 @@
dpy)) {
if(ctx->mOverlay->isPipeTypeAttached(
overlay::utils::OV_MDP_PIPE_DMA))
- ctx->isPaddingRound = true;
+ ctx->isDMAStateChanging = true;
}
Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
}
@@ -160,7 +161,7 @@
if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
if(ctx->mOverlay->isPipeTypeAttached(
overlay::utils::OV_MDP_PIPE_DMA)) {
- ctx->isPaddingRound = true;
+ ctx->isDMAStateChanging = true;
}
Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
}
@@ -187,6 +188,12 @@
}
}
+static bool isHotPluggable(hwc_context_t *ctx, int dpy) {
+ return ((dpy == HWC_DISPLAY_EXTERNAL) ||
+ ((dpy == HWC_DISPLAY_PRIMARY) &&
+ ctx->mHDMIDisplay->isHDMIPrimaryDisplay()));
+}
+
static void reset(hwc_context_t *ctx, int numDisplays,
hwc_display_contents_1_t** displays) {
@@ -735,40 +742,54 @@
int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
uint32_t* configs, size_t* numConfigs) {
- int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
- //Currently we allow only 1 config, reported as config id # 0
- //This config is passed in to getDisplayAttributes. Ignored for now.
+
+ Locker::Autolock _l(ctx->mDrawLock);
+ bool hotPluggable = isHotPluggable(ctx, disp);
+ bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL);
+ // If hotpluggable or virtual displays are inactive return error
+ if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) {
+ ALOGE("%s display (%d) is inactive", __FUNCTION__, disp);
+ return -EINVAL;
+ }
+
+ if (*numConfigs <= 0) {
+ ALOGE("%s Invalid number of configs (%d)", __FUNCTION__, *numConfigs);
+ return -EINVAL;
+ }
+
switch(disp) {
case HWC_DISPLAY_PRIMARY:
- if(*numConfigs > 0) {
+ if (hotPluggable) {
+ ctx->mHDMIDisplay->getDisplayConfigs(configs, numConfigs);
+ } else {
configs[0] = 0;
*numConfigs = 1;
}
- ret = 0; //NO_ERROR
break;
case HWC_DISPLAY_EXTERNAL:
+ ctx->mHDMIDisplay->getDisplayConfigs(configs, numConfigs);
+ break;
case HWC_DISPLAY_VIRTUAL:
- ret = -1; //Not connected
- if(ctx->dpyAttr[disp].connected) {
- ret = 0; //NO_ERROR
- if(*numConfigs > 0) {
- configs[0] = 0;
- *numConfigs = 1;
- }
- }
+ configs[0] = 0;
+ *numConfigs = 1;
break;
}
- return ret;
+ return 0;
}
int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
- uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
+ uint32_t config, const uint32_t* attributes, int32_t* values) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
- //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
- if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
- return -1;
+
+ Locker::Autolock _l(ctx->mDrawLock);
+ bool hotPluggable = isHotPluggable(ctx, disp);
+ bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL);
+ // If hotpluggable or virtual displays are inactive return error
+ if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) {
+ ALOGE("%s display (%d) is inactive", __FUNCTION__, disp);
+ return -EINVAL;
}
//From HWComposer
@@ -784,16 +805,27 @@
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) {
+ ret = ctx->mHDMIDisplay->getAttrForConfig(config, xres, yres, refresh);
+ if(ret < 0) {
+ ALOGE("%s Error getting attributes for config %d", config);
+ return ret;
+ }
+ }
+
for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
switch (attributes[i]) {
case HWC_DISPLAY_VSYNC_PERIOD:
- values[i] = ctx->dpyAttr[disp].vsync_period;
+ values[i] =
+ hotPluggable ? refresh : ctx->dpyAttr[disp].vsync_period;
break;
case HWC_DISPLAY_WIDTH:
if (ctx->dpyAttr[disp].customFBSize)
values[i] = ctx->dpyAttr[disp].xres_new;
else
- values[i] = ctx->dpyAttr[disp].xres;
+ values[i] = hotPluggable ? xres : ctx->dpyAttr[disp].xres;
ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
values[i]);
@@ -802,7 +834,7 @@
if (ctx->dpyAttr[disp].customFBSize)
values[i] = ctx->dpyAttr[disp].yres_new;
else
- values[i] = ctx->dpyAttr[disp].yres;
+ values[i] = hotPluggable ? yres : ctx->dpyAttr[disp].yres;
ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
values[i]);
break;
@@ -849,15 +881,49 @@
strlcpy(buff, aBuf.string(), buff_len);
}
-int hwc_getActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/) {
- //Supports only the default config (0th index) for now
- return 0;
+int hwc_getActiveConfig(struct hwc_composer_device_1* dev, int disp)
+{
+ hwc_context_t* ctx = (hwc_context_t*)(dev);
+
+ Locker::Autolock _l(ctx->mDrawLock);
+ bool hotPluggable = isHotPluggable(ctx, disp);
+ bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL);
+ // If hotpluggable or virtual displays are inactive return error
+ if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) {
+ ALOGE("%s display (%d) is inactive", __FUNCTION__, disp);
+ return -EINVAL;
+ }
+
+ // For use cases when primary panel is the default interface we only have
+ // the default config (0th index)
+ if (!hotPluggable) {
+ return 0;
+ }
+
+ return ctx->mHDMIDisplay->getActiveConfig();
}
-int hwc_setActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/,
- int index) {
- //Supports only the default config (0th index) for now
- return (index == 0) ? index : -EINVAL;
+int hwc_setActiveConfig(struct hwc_composer_device_1* dev, int disp, int index)
+{
+ hwc_context_t* ctx = (hwc_context_t*)(dev);
+
+ Locker::Autolock _l(ctx->mDrawLock);
+ bool hotPluggable = isHotPluggable(ctx, disp);
+ bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL);
+ // If hotpluggable or virtual displays are inactive return error
+ if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) {
+ ALOGE("%s display (%d) is inactive", __FUNCTION__, disp);
+ 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)
+ return (index == 0) ? index : -EINVAL;
+ }
+
+ return ctx->mHDMIDisplay->setActiveConfig(index);
}
static int hwc_device_close(struct hw_device_t *dev)
diff --git a/libhwcomposer/hwc_dump_layers.cpp b/libhwcomposer/hwc_dump_layers.cpp
index 0a92def..e717c26 100644
--- a/libhwcomposer/hwc_dump_layers.cpp
+++ b/libhwcomposer/hwc_dump_layers.cpp
@@ -331,6 +331,8 @@
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:
@@ -394,6 +396,12 @@
case HAL_PIXEL_FORMAT_BGRA_8888:
strlcpy(pixFormatStr, "BGRA_8888", sizeof(pixFormatStr));
break;
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ strlcpy(pixFormatStr, "RGBA_5551", sizeof(pixFormatStr));
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ strlcpy(pixFormatStr, "RGBA_4444", sizeof(pixFormatStr));
+ break;
case HAL_PIXEL_FORMAT_YV12:
strlcpy(pixFormatStr, "YV12", sizeof(pixFormatStr));
break;
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 43ae916..3e16072 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -157,6 +157,8 @@
}
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
+ ovutils::setMdpFlags(mdpFlags,
+ ovutils::OV_MDP_SMP_FORCE_ALLOC);
ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
@@ -280,6 +282,8 @@
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
+ ovutils::setMdpFlags(mdpFlags,
+ ovutils::OV_MDP_SMP_FORCE_ALLOC);
ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
ovutils::eTransform orient =
static_cast<ovutils::eTransform>(layer->transform);
@@ -442,6 +446,8 @@
mTileEnabled));
ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
+ ovutils::setMdpFlags(mdpFlags,
+ ovutils::OV_MDP_SMP_FORCE_ALLOC);
ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
ovutils::PipeArgs parg(mdpFlags,
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 2904e6f..56d86ec 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -43,7 +43,7 @@
bool MDPComp::sEnabled = false;
bool MDPComp::sEnableMixedMode = true;
int MDPComp::sSimulationFlags = 0;
-int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
+int MDPComp::sMaxPipesPerMixer = 0;
bool MDPComp::sEnableYUVsplit = false;
bool MDPComp::sSrcSplitEnabled = false;
bool MDPComp::enablePartialUpdateForMDP3 = false;
@@ -127,11 +127,15 @@
sEnableMixedMode = false;
}
- sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
- if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
+ qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
+
+ /* MDSS_MDP_STAGE_UNUSED and MDSS_MDP_STAGE_BASE are not available for MDP
+ * composition. */
+ sMaxPipesPerMixer = (int)mdpVersion.getBlendStages() - 2;
+ if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
int val = atoi(property);
if(val >= 0)
- sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
+ sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
}
if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
@@ -213,6 +217,16 @@
ctx->proc->invalidate(ctx->proc);
}
+void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
+ qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
+ uint32_t maxSupported = (int)mdpVersion.getBlendStages() - 2;
+ if(value > maxSupported) {
+ ALOGW("%s: Input exceeds max value supported. Setting to"
+ "max value: %d", __FUNCTION__, maxSupported);
+ }
+ sMaxPipesPerMixer = min(value, maxSupported);
+}
+
void MDPComp::setIdleTimeout(const uint32_t& timeout) {
enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
@@ -268,7 +282,7 @@
}
void MDPComp::FrameInfo::reset(const int& numLayers) {
- for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
+ for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
if(mdpToLayer[i].pipeInfo) {
delete mdpToLayer[i].pipeInfo;
mdpToLayer[i].pipeInfo = NULL;
@@ -466,7 +480,15 @@
__FUNCTION__,mDpy);
ret = false;
}
+ } else if (ctx->isDMAStateChanging) {
+ // Bail out if a padding round has been invoked in order to switch DMA
+ // state to block mode. We need this to cater for the case when a layer
+ // requires rotation in the current frame.
+ ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
+ __FUNCTION__);
+ return false;
}
+
return ret;
}
@@ -2061,7 +2083,7 @@
PipeLayerPair& PipeLayerPair) {
MdpPipeInfoNonSplit& mdp_info =
*(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
- eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
+ eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
eDest dest = mdp_info.index;
@@ -2117,7 +2139,7 @@
MdpYUVPipeInfo& mdp_info =
*(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
- eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
+ eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
eDest lDest = mdp_info.lIndex;
eDest rDest = mdp_info.rIndex;
@@ -2349,7 +2371,7 @@
MdpYUVPipeInfo& mdp_info =
*(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
- eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
+ eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
eDest lDest = mdp_info.lIndex;
eDest rDest = mdp_info.rIndex;
@@ -2369,7 +2391,7 @@
MdpPipeInfoSplit& mdp_info =
*(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
- eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
+ eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
eDest lDest = mdp_info.lIndex;
eDest rDest = mdp_info.rIndex;
@@ -2616,7 +2638,7 @@
calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
int downscale = getRotDownscale(ctx, layer);
- eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
+ eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
if(lDest != OV_INVALID && rDest != OV_INVALID) {
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 4634fbc..7fa6674 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -25,8 +25,6 @@
#include <cutils/properties.h>
#include <overlay.h>
-#define MAX_PIPES_PER_MIXER 4
-
namespace overlay {
class Rotator;
};
@@ -57,6 +55,7 @@
static bool isIdleFallback() { return sIdleFallBack; }
static void dynamicDebug(bool enable){ sDebugLogs = enable; }
static void setIdleTimeout(const uint32_t& timeout);
+ static void setMaxPipesPerMixer(const uint32_t value);
protected:
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -104,7 +103,7 @@
/* maps mdp list to layer list */
int mdpCount;
- struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
+ struct PipeLayerPair mdpToLayer[MAX_NUM_BLEND_STAGES];
/* layer composing on FB? */
int fbCount;
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index fd0a36c..0af8090 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -184,7 +184,7 @@
handle_resume(ctx, dpy);
}
} else {
- ALOGE("%s: Invalid dpy", __FUNCTION__, dpy);
+ ALOGE("%s: Invalid dpy %d", __FUNCTION__, dpy);
return;
}
}
@@ -244,6 +244,13 @@
MDPComp::setIdleTimeout(timeout);
}
+static void setMaxPipesPerMixer(hwc_context_t* ctx, const Parcel* inParcel) {
+ uint32_t value = (uint32_t)inParcel->readInt32();
+ ALOGD("%s : setting MaxPipesPerMixer: %d ", __FUNCTION__, value);
+ Locker::Autolock _sl(ctx->mDrawLock);
+ MDPComp::setMaxPipesPerMixer(value);
+}
+
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -289,6 +296,9 @@
case IQService::SET_IDLE_TIMEOUT:
setIdleTimeout(mHwcContext, inParcel);
break;
+ case IQService::SET_MAX_PIPES_PER_MIXER:
+ setMaxPipesPerMixer(mHwcContext, inParcel);
+ break;
default:
ret = NO_ERROR;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 3eec011..b091ae2 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -856,6 +856,9 @@
src_w = sourceCrop.right - sourceCrop.left;
src_h = sourceCrop.bottom - sourceCrop.top;
+ if(layer->transform & HWC_TRANSFORM_ROT_90)
+ swap(src_w, src_h);
+
if(((src_w != dst_w) || (src_h != dst_h)))
return true;
@@ -1151,22 +1154,26 @@
bool isRotatorSupportedFormat(private_handle_t *hnd) {
// Following rotator src formats are supported by mdp driver
// TODO: Add more formats in future, if mdp driver adds support
- switch(hnd->format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_RGB_888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return true;
- default:
- return false;
+ if(hnd != NULL) {
+ switch(hnd->format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGB_888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return true;
+ default:
+ return false;
+ }
}
return false;
}
bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd) {
- // Rotate layers, if it is YUV type or rendered by CPU and not
+ // Rotate layers, if it is not secure display buffer and not
// for the MDP versions below MDP5
- if((isCPURendered(hnd) && isRotatorSupportedFormat(hnd) &&
+ if((!isSecureDisplayBuffer(hnd) && isRotatorSupportedFormat(hnd) &&
!ctx->mMDP.version < qdutils::MDSS_V5)
|| isYuvBuffer(hnd)) {
return true;
@@ -1668,6 +1675,13 @@
if(isSecureBuffer(hnd)) {
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+ ovutils::setMdpFlags(mdpFlags,
+ ovutils::OV_MDP_SMP_FORCE_ALLOC);
+ }
+
+ if(isProtectedBuffer(hnd)) {
+ ovutils::setMdpFlags(mdpFlags,
+ ovutils::OV_MDP_SMP_FORCE_ALLOC);
}
if(isSecureDisplayBuffer(hnd)) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index b3d7047..96d1e58 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -41,6 +41,7 @@
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
#define MAX_NUM_APP_LAYERS 32
+#define MAX_NUM_BLEND_STAGES 16
#define MIN_DISPLAY_XRES 200
#define MIN_DISPLAY_YRES 200
#define HWC_WFDDISPSYNC_LOG 0
@@ -463,12 +464,14 @@
return (hnd && (private_handle_t::PRIV_FLAGS_SECURE_BUFFER & hnd->flags));
}
-static inline bool isTileRendered(const private_handle_t* hnd) {
- return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
+// Returns true if the buffer is protected
+static inline bool isProtectedBuffer(const private_handle_t* hnd) {
+ return (hnd && (private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER & hnd->flags));
}
-static inline bool isCPURendered(const private_handle_t* hnd) {
- return (hnd && (private_handle_t::PRIV_FLAGS_CPU_RENDERED & hnd->flags));
+
+static inline bool isTileRendered(const private_handle_t* hnd) {
+ return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
}
//Return true if buffer is marked locked
@@ -601,6 +604,8 @@
mutable Locker mDrawLock;
//Drawing round when we use GPU
bool isPaddingRound;
+ // Used to mark composition cycle when DMA state change is required
+ bool isDMAStateChanging;
// External Orientation
int mExtOrientation;
//Flags the transition of a video session
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 7b97c6c..722916a 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -88,9 +88,10 @@
thermalLevel = strtoull(data + strlen("thermal_level="), NULL, 0);
}
- if (thermalLevel >= MAX_THERMAL_LEVEL)
+ if (thermalLevel >= MAX_THERMAL_LEVEL) {
+ ALOGD("%s: dpy:%d thermal_level=%"PRIu64"",__FUNCTION__,dpy,thermalLevel);
ctx->mThermalBurstMode = true;
- else
+ } else
ctx->mThermalBurstMode = false;
}
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 96c057f..3a96b71 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -279,8 +279,29 @@
uint8_t pipe2Prio = mPipeBook[(int)pipe2Index].mPipe->getPriority();
if(pipe1Prio > pipe2Prio)
return -1;
- if(pipe1Prio < pipe2Prio)
+ else if(pipe1Prio < pipe2Prio)
return 1;
+ else {
+ // If we are here, Source Split is enabled and both pipes are
+ // new requests. In this case left type should be of higher prio
+ // than right type
+ utils::eMdpPipeType leftType = PipeBook::getPipeType(pipe1Index);
+ utils::eMdpPipeType rightType = PipeBook::getPipeType(pipe2Index);
+
+ if(leftType == rightType) {
+ //Safe. Onus on driver to assign correct pipes within same type
+ return 1;
+ } else if(leftType == OV_MDP_PIPE_DMA or rightType == OV_MDP_PIPE_VG) {
+ //If we are here, right is definitely a higher prio type.
+ //This check takes advantage of having only 3 types and avoids 3
+ //different failure combination checks.
+ return -1;
+ } else {
+ //Types are correct priority-wise
+ return 1;
+ }
+ }
+
return 0;
}
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index cbd52ae..32b2013 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -93,6 +93,10 @@
return MDP_RGB_888;
case HAL_PIXEL_FORMAT_RGB_565:
return MDP_RGB_565;
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ return MDP_RGBA_5551;
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ return MDP_RGBA_4444;
case HAL_PIXEL_FORMAT_BGRA_8888:
return MDP_BGRA_8888;
case HAL_PIXEL_FORMAT_BGRX_8888:
@@ -126,9 +130,6 @@
return MDP_Y_CBCR_H2V2_VENUS;
default:
//Unsupported by MDP
- //---graphics.h--------
- //HAL_PIXEL_FORMAT_RGBA_5551
- //HAL_PIXEL_FORMAT_RGBA_4444
//---gralloc_priv.h-----
//HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x7FA30C01
//HAL_PIXEL_FORMAT_R_8 = 0x10D
@@ -180,6 +181,10 @@
return HAL_PIXEL_FORMAT_RGB_888;
case MDP_RGB_565:
return HAL_PIXEL_FORMAT_RGB_565;
+ case MDP_RGBA_5551:
+ return HAL_PIXEL_FORMAT_RGBA_5551;
+ case MDP_RGBA_4444:
+ return HAL_PIXEL_FORMAT_RGBA_4444;
case MDP_BGRA_8888:
return HAL_PIXEL_FORMAT_BGRA_8888;
case MDP_Y_CR_CB_GH2V2:
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 2b8e303..54ee0fd 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -223,7 +223,6 @@
OV_MDP_SECURE_OVERLAY_SESSION = MDP_SECURE_OVERLAY_SESSION,
OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION = MDP_SECURE_DISPLAY_OVERLAY_SESSION,
OV_MDP_SOURCE_ROTATED_90 = MDP_SOURCE_ROTATED_90,
- OV_MDP_BACKEND_COMPOSITION = MDP_BACKEND_COMPOSITION,
OV_MDP_BLEND_FG_PREMULT = MDP_BLEND_FG_PREMULT,
OV_MDP_FLIP_H = MDP_FLIP_LR,
OV_MDP_FLIP_V = MDP_FLIP_UD,
@@ -232,6 +231,7 @@
OV_MDSS_MDP_BWC_EN = MDP_BWC_EN,
OV_MDSS_MDP_DUAL_PIPE = MDSS_MDP_DUAL_PIPE,
OV_MDP_SOLID_FILL = MDP_SOLID_FILL,
+ OV_MDP_SMP_FORCE_ALLOC = MDP_SMP_FORCE_ALLOC,
};
enum eZorder {
@@ -239,6 +239,9 @@
ZORDER_1,
ZORDER_2,
ZORDER_3,
+ ZORDER_4,
+ ZORDER_5,
+ ZORDER_6,
Z_SYSTEM_ALLOC = 0xFFFF
};
@@ -432,6 +435,8 @@
case MDP_BGRA_8888:
case MDP_RGBX_8888:
case MDP_RGB_565:
+ case MDP_RGBA_4444:
+ case MDP_RGBA_5551:
return true;
default:
return false;
@@ -443,6 +448,8 @@
#define STR(f) #f;
static const char* formats[MDP_IMGTYPE_LIMIT + 1] = {0};
formats[MDP_RGB_565] = STR(MDP_RGB_565);
+ formats[MDP_RGBA_5551] = STR(MDP_RGBA_5551);
+ formats[MDP_RGBA_4444] = STR(MDP_RGBA_4444);
formats[MDP_XRGB_8888] = STR(MDP_XRGB_8888);
formats[MDP_Y_CBCR_H2V2] = STR(MDP_Y_CBCR_H2V2);
formats[MDP_Y_CBCR_H2V2_ADRENO] = STR(MDP_Y_CBCR_H2V2_ADRENO);
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index 088f82b..f8729a5 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -57,7 +57,7 @@
#define MDSS_MDP_HW_REV_103 0x10030000 //8084
#endif
#ifndef MDSS_MDP_HW_REV_104
-#define MDSS_MDP_HW_REV_104 0x10040000 //Next version
+#define MDSS_MDP_HW_REV_104 0x10040000 //Unused
#endif
#ifndef MDSS_MDP_HW_REV_105
#define MDSS_MDP_HW_REV_105 0x10050000 //8994
@@ -66,13 +66,16 @@
#define MDSS_MDP_HW_REV_106 0x10060000 //8x16
#endif
#ifndef MDSS_MDP_HW_REV_107
-#define MDSS_MDP_HW_REV_107 0x10070000 //Next version
+#define MDSS_MDP_HW_REV_107 0x10070000 //Unused
#endif
#ifndef MDSS_MDP_HW_REV_108
#define MDSS_MDP_HW_REV_108 0x10080000 //8x39 & 8x36
#endif
#ifndef MDSS_MDP_HW_REV_109
-#define MDSS_MDP_HW_REV_109 0x10090000 //Next version
+#define MDSS_MDP_HW_REV_109 0x10090000 //8994 v2
+#endif
+#ifndef MDSS_MDP_HW_REV_110
+#define MDSS_MDP_HW_REV_110 0x100a0000 //Next version
#endif
#ifndef MDSS_MDP_HW_REV_200
#define MDSS_MDP_HW_REV_200 0x20000000 //8092
@@ -98,6 +101,7 @@
mSourceSplitAlways = false;
mRGBHasNoScalar = false;
mRotDownscale = false;
+ mBlendStages = 6; //min no. of stages supported by MDP.
// this is the default limit of mixer unless driver reports it.
// For resolutions beyond this, we use dual/split overlay pipes.
@@ -300,6 +304,10 @@
else if(!strncmp(tokens[0], "dma_pipes", strlen("dma_pipes"))) {
mDMAPipes = (uint8_t)atoi(tokens[1]);
}
+ else if(!strncmp(tokens[0], "blending_stages",
+ strlen("blending_stages"))) {
+ mBlendStages = (uint8_t)atoi(tokens[1]);
+ }
else if(!strncmp(tokens[0], "max_downscale_ratio",
strlen("max_downscale_ratio"))) {
mMDPDownscale = atoi(tokens[1]);
@@ -470,8 +478,10 @@
}
bool MDPVersion::is8994() {
- return (mMdpRev >= MDSS_MDP_HW_REV_105 and
- mMdpRev < MDSS_MDP_HW_REV_106);
+ return ((mMdpRev >= MDSS_MDP_HW_REV_105 and
+ mMdpRev < MDSS_MDP_HW_REV_106) or
+ (mMdpRev >= MDSS_MDP_HW_REV_109 and
+ mMdpRev < MDSS_MDP_HW_REV_110));
}
bool MDPVersion::is8x16() {
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 3c7f6a3..dcde240 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -116,6 +116,7 @@
uint8_t getRGBPipes() { return mRGBPipes; }
uint8_t getVGPipes() { return mVGPipes; }
uint8_t getDMAPipes() { return mDMAPipes; }
+ uint8_t getBlendStages() { return mBlendStages; }
bool supportsDecimation();
uint32_t getMaxMDPDownscale();
uint32_t getMaxMDPUpscale();
@@ -163,6 +164,7 @@
uint8_t mRGBPipes;
uint8_t mVGPipes;
uint8_t mDMAPipes;
+ uint8_t mBlendStages;
uint32_t mFeatures;
uint32_t mMDPDownscale;
uint32_t mMDPUpscale;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 87d51fc..6f2f0e3 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -50,7 +50,7 @@
SET_HSIC_DATA, // Set HSIC on dspp
GET_DISPLAY_VISIBLE_REGION, // Get the visibleRegion for dpy
SET_SECONDARY_DISPLAY_STATUS, // Sets secondary display status
- UNUSED_SLOT, // XXX: Unsed - New one can go here
+ SET_MAX_PIPES_PER_MIXER, // Set max pipes per mixer for MDPComp
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