Merge "hwc: Add a new check for DMA state change"
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 421f531..da18c7b 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -584,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/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index b13166d..4167ae2 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -296,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.
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/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 baeb1b9..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;
@@ -2069,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;
@@ -2125,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;
@@ -2357,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;
@@ -2377,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;
@@ -2624,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 6a74625..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;
@@ -1672,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 330d22d..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,6 +464,12 @@
return (hnd && (private_handle_t::PRIV_FLAGS_SECURE_BUFFER & 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 isTileRendered(const private_handle_t* hnd) {
return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
}
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.h b/liboverlay/overlayUtils.h
index ff6d4ef..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
};
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index e3d3131..f8729a5 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -101,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.
@@ -303,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]);
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