Skip to content

Commit

Permalink
hwc: Rotate RGB layer using MDP Rotator
Browse files Browse the repository at this point in the history
1. Use MDP rotator to rotate RGB layers which are rendered by software
2. Restrict total number of rotator sessions to 4 for all displays
3. Disable RGB layer rotation for all MDP versions < MDP5

Change-Id: Ie93111082dff9a16b614e9768df5d8ce83ff9e25
  • Loading branch information
Ramkumar Radhakrishnan authored and Simon Wilson committed Jan 9, 2015
1 parent 370a4b1 commit 4a7fde2
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 31 deletions.
4 changes: 4 additions & 0 deletions msm8226/libgralloc/gpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ int gpu_context_t::gralloc_alloc_buffer(unsigned int size, int usage,
flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
}

if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
}

flags |= data.allocType;
uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
Expand Down
4 changes: 3 additions & 1 deletion msm8226/libgralloc/gralloc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ struct private_handle_t : public native_handle {
PRIV_FLAGS_ITU_R_709 = 0x00800000,
PRIV_FLAGS_SECURE_DISPLAY = 0x01000000,
// Buffer is rendered in Tile Format
PRIV_FLAGS_TILE_RENDERED = 0x02000000
PRIV_FLAGS_TILE_RENDERED = 0x02000000,
// Buffer rendered using CPU/SW renderer
PRIV_FLAGS_CPU_RENDERED = 0x04000000
};

// file-descriptors
Expand Down
6 changes: 3 additions & 3 deletions msm8226/libhwcomposer/hwc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ static void setDMAState(hwc_context_t *ctx, int numDisplays,
hwc_layer_1_t const* layer = &list->hwLayers[layerIndex];
private_handle_t *hnd = (private_handle_t *)layer->handle;

/* If a video layer requires rotation, set the DMA state
/* If a layer requires rotation, set the DMA state
* to BLOCK_MODE */

if (UNLIKELY(isYuvBuffer(hnd)) && canUseRotator(ctx, dpy) &&
(layer->transform & HWC_TRANSFORM_ROT_90)) {
if (canUseRotator(ctx, dpy) &&
has90Transform(layer) && isRotationDoable(ctx, hnd)) {
if(not ctx->mOverlay->isDMAMultiplexingSupported()) {
if(ctx->mOverlay->isPipeTypeAttached(
overlay::utils::OV_MDP_PIPE_DMA))
Expand Down
2 changes: 1 addition & 1 deletion msm8226/libhwcomposer/hwc_fbupdate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ bool FBUpdateNonSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *lis
transform, orient);
//Store the displayFrame, will be used in getDisplayViewFrame
ctx->dpyAttr[mDpy].mDstRect = displayFrame;
setMdpFlags(layer, mdpFlags, 0, transform);
setMdpFlags(ctx, layer, mdpFlags, 0, transform);
// For External use rotator if there is a rotation value set
ret = preRotateExtDisplay(ctx, layer, info,
sourceCrop, mdpFlags, rotFlags);
Expand Down
36 changes: 28 additions & 8 deletions msm8226/libhwcomposer/hwc_mdpcomp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,

bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
private_handle_t *hnd = (private_handle_t *)layer->handle;
if((not isYuvBuffer(hnd) and has90Transform(layer)) or
if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
(not isValidDimension(ctx,layer))
//More conditions here, SKIP, sRGB+Blend etc
) {
Expand Down Expand Up @@ -617,8 +617,9 @@ void MDPCompSplit::generateROI(hwc_context_t *ctx,

for(int index = 0; index < numAppLayers; index++ ) {
hwc_layer_1_t* layer = &list->hwLayers[index];
private_handle_t *hnd = (private_handle_t *)layer->handle;
if ((mCachedFrame.hnd[index] != layer->handle) ||
isYuvBuffer((private_handle_t *)layer->handle)) {
isYuvBuffer(hnd)) {
hwc_rect_t dst = layer->displayFrame;
hwc_rect_t updatingRect = dst;

Expand Down Expand Up @@ -715,7 +716,7 @@ bool MDPComp::tryFullFrame(hwc_context_t *ctx,
hwc_layer_1_t* layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;

if(isYuvBuffer(hnd) && has90Transform(layer)) {
if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
if(!canUseRotator(ctx, mDpy)) {
ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
__FUNCTION__, mDpy);
Expand Down Expand Up @@ -1158,7 +1159,7 @@ bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
return false;
}

if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
return false;
}
Expand Down Expand Up @@ -1421,7 +1422,7 @@ bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
hwc_display_contents_1_t* list) {

//Capability checks
if(!resourceCheck()) {
if(!resourceCheck(ctx, list)) {
ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
return false;
}
Expand Down Expand Up @@ -1495,12 +1496,31 @@ bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
return true;
}

bool MDPComp::resourceCheck() {
bool MDPComp::resourceCheck(hwc_context_t* ctx,
hwc_display_contents_1_t* list) {
const bool fbUsed = mCurrentFrame.fbCount;
if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
return false;
}
// Init rotCount to number of rotate sessions used by other displays
int rotCount = ctx->mRotMgr->getNumActiveSessions();
// Count the number of rotator sessions required for current display
for (int index = 0; index < mCurrentFrame.layerCount; index++) {
if(!mCurrentFrame.isFBComposed[index]) {
hwc_layer_1_t* layer = &list->hwLayers[index];
private_handle_t *hnd = (private_handle_t *)layer->handle;
if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
rotCount++;
}
}
}
// if number of layers to rotate exceeds max rotator sessions, bail out.
if(rotCount > RotMgr::MAX_ROT_SESS) {
ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
__FUNCTION__, mDpy);
return false;
}
return true;
}

Expand Down Expand Up @@ -2256,14 +2276,14 @@ int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
}

eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
setMdpFlags(layer, mdpFlags, 0, transform);
setMdpFlags(ctx, layer, mdpFlags, 0, transform);

if(lDest != OV_INVALID && rDest != OV_INVALID) {
//Enable overfetch
setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
}

if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
(*rot) = ctx->mRotMgr->getNext();
if((*rot) == NULL) return -1;
ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Expand Down
2 changes: 1 addition & 1 deletion msm8226/libhwcomposer/hwc_mdpcomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class MDPComp {
hwc_display_contents_1_t* list);
void reset(hwc_context_t *ctx);
bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
bool resourceCheck();
bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
hwc_display_contents_1_t* list);
/* checks for conditions to enable partial udpate */
Expand Down
59 changes: 44 additions & 15 deletions msm8226/libhwcomposer/hwc_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,32 @@ bool isSecureModePolicy(int mdpVersion) {
return false;
}

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;
}
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
// for the MDP versions below MDP5
if((isCPURendered(hnd) && isRotatorSupportedFormat(hnd) &&
!ctx->mMDP.version < qdutils::MDSS_V5)
|| isYuvBuffer(hnd)) {
return true;
}
return false;
}

// returns true if Action safe dimensions are set and target supports Actionsafe
bool isActionSafePresent(hwc_context_t *ctx, int dpy) {
// if external supports underscan, do nothing
Expand Down Expand Up @@ -1419,7 +1445,7 @@ int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
return ret;
}

void setMdpFlags(hwc_layer_1_t *layer,
void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
ovutils::eMdpFlags &mdpFlags,
int rotDownscale, int transform) {
private_handle_t *hnd = (private_handle_t *)layer->handle;
Expand All @@ -1440,11 +1466,6 @@ void setMdpFlags(hwc_layer_1_t *layer,
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_DEINTERLACE);
}
//Pre-rotation will be used using rotator.
if(transform & HWC_TRANSFORM_ROT_90) {
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SOURCE_ROTATED_90);
}
}

if(isSecureDisplayBuffer(hnd)) {
Expand All @@ -1454,6 +1475,12 @@ void setMdpFlags(hwc_layer_1_t *layer,
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION);
}

//Pre-rotation will be used using rotator.
if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SOURCE_ROTATED_90);
}
//No 90 component and no rot-downscale then flips done by MDP
//If we use rot then it might as well do flips
if(!(transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) {
Expand Down Expand Up @@ -1646,14 +1673,15 @@ int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
}
}

setMdpFlags(layer, mdpFlags, downscale, transform);
setMdpFlags(ctx, layer, mdpFlags, downscale, transform);

if(isYuvBuffer(hnd) && //if 90 component or downscale, use rot
((transform & HWC_TRANSFORM_ROT_90) || downscale)) {
//if 90 component or downscale, use rot
if((has90Transform(layer) && isRotationDoable(ctx, hnd)) || downscale) {
*rot = ctx->mRotMgr->getNext();
if(*rot == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
if(!dpy)
// BWC is not tested for other formats So enable it only for YUV format
if(!dpy && isYuvBuffer(hnd))
BwcPM::setBwc(crop, dst, transform, mdpFlags);
//Configure rotator for pre-rotation
if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Expand Down Expand Up @@ -1743,7 +1771,7 @@ int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
ActionSafe, and extorientation features. */
calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);

setMdpFlags(layer, mdpFlagsL, 0, transform);
setMdpFlags(ctx, layer, mdpFlagsL, 0, transform);

if(lDest != OV_INVALID && rDest != OV_INVALID) {
//Enable overfetch
Expand All @@ -1757,7 +1785,7 @@ int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
whf.format = wb->getOutputFormat();
}

if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
(*rot) = ctx->mRotMgr->getNext();
if((*rot) == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
Expand Down Expand Up @@ -1885,14 +1913,15 @@ int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
ActionSafe, and extorientation features. */
calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);

setMdpFlags(layer, mdpFlagsL, 0, transform);
setMdpFlags(ctx, layer, mdpFlagsL, 0, transform);
trimLayer(ctx, dpy, transform, crop, dst);

if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
(*rot) = ctx->mRotMgr->getNext();
if((*rot) == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
if(!dpy)
// BWC is not tested for other formats So enable it only for YUV format
if(!dpy && isYuvBuffer(hnd))
BwcPM::setBwc(crop, dst, transform, mdpFlagsL);
//Configure rotator for pre-rotation
if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
Expand Down
12 changes: 10 additions & 2 deletions msm8226/libhwcomposer/hwc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ void getNonWormholeRegion(hwc_display_contents_1_t* list,
hwc_rect_t& nwr);
bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
bool isSecureModePolicy(int mdpVersion);
// Returns true, if the input layer format is supported by rotator
bool isRotatorSupportedFormat(private_handle_t *hnd);
//Returns true, if the layer is YUV or the layer has been rendered by CPU
bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd);
bool isExternalActive(hwc_context_t* ctx);
bool isAlphaScaled(hwc_layer_1_t const* layer);
bool needsScaling(hwc_layer_1_t const* layer);
Expand Down Expand Up @@ -315,7 +319,7 @@ int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
int fd);

//Sets appropriate mdp flags for a layer.
void setMdpFlags(hwc_layer_1_t *layer,
void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
ovutils::eMdpFlags &mdpFlags,
int rotDownscale, int transform);

Expand Down Expand Up @@ -400,6 +404,10 @@ static inline bool isTileRendered(const private_handle_t* hnd) {
return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
}

static inline bool isCPURendered(const private_handle_t* hnd) {
return (hnd && (private_handle_t::PRIV_FLAGS_CPU_RENDERED & hnd->flags));
}

//Return true if buffer is marked locked
static inline bool isBufferLocked(const private_handle_t* hnd) {
return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
Expand Down Expand Up @@ -577,7 +585,7 @@ static inline bool isYuvPresent (hwc_context_t *ctx, int dpy) {
return ctx->listStats[dpy].yuvCount;
}

static inline bool has90Transform(hwc_layer_1_t *layer) {
static inline bool has90Transform(hwc_layer_1_t const* layer) {
return ((layer->transform & HWC_TRANSFORM_ROT_90) &&
!(layer->flags & HWC_COLOR_FILL));
}
Expand Down
3 changes: 3 additions & 0 deletions msm8226/liboverlay/overlayRotator.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ class MdssRot : public Rotator {
// Holder of rotator objects. Manages lifetimes
class RotMgr {
public:
//Virtually we can support as many rotator sessions as possible, However
// more number of rotator sessions leads to performance issues, so
// restricting the max rotator session to 4
enum { MAX_ROT_SESS = 4 };

~RotMgr();
Expand Down

0 comments on commit 4a7fde2

Please sign in to comment.