hwc: Add support for plane alpha
HWC 1.2 API passes down the plane alpha and the blending operation to apply. Pass this information to the MDP. Change-Id: I7fbd17345d9157aa654e4b1031ac3e26adf87f37
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
e36a9c2f1a
commit
522ce66a3e
@@ -751,7 +751,7 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
|
||||
|
||||
//Setup HWC methods
|
||||
dev->device.common.tag = HARDWARE_DEVICE_TAG;
|
||||
dev->device.common.version = HWC_DEVICE_API_VERSION_1_1;
|
||||
dev->device.common.version = HWC_DEVICE_API_VERSION_1_2;
|
||||
dev->device.common.module = const_cast<hw_module_t*>(module);
|
||||
dev->device.common.close = hwc_device_close;
|
||||
dev->device.prepare = hwc_prepare;
|
||||
|
||||
@@ -171,7 +171,10 @@ bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
|
||||
orient = ovutils::OVERLAY_TRANSFORM_0;
|
||||
transform = 0;
|
||||
ovutils::PipeArgs parg(mdpFlags, info, zOrder, isFg,
|
||||
static_cast<ovutils::eRotFlags>(rotFlags));
|
||||
static_cast<ovutils::eRotFlags>(rotFlags),
|
||||
ovutils::DEFAULT_PLANE_ALPHA,
|
||||
(ovutils::eBlending)
|
||||
getBlending(layer->blending));
|
||||
ret = true;
|
||||
if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
|
||||
NULL, mDest) < 0) {
|
||||
@@ -268,11 +271,16 @@ bool FBUpdateHighRes::configure(hwc_context_t *ctx,
|
||||
|
||||
ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
|
||||
|
||||
//XXX: FB layer plane alpha is currently sent as zero from
|
||||
//surfaceflinger
|
||||
ovutils::PipeArgs pargL(mdpFlagsL,
|
||||
info,
|
||||
zOrder,
|
||||
ovutils::IS_FG_OFF,
|
||||
ovutils::ROT_FLAGS_NONE);
|
||||
ovutils::ROT_FLAGS_NONE,
|
||||
ovutils::DEFAULT_PLANE_ALPHA,
|
||||
(ovutils::eBlending)
|
||||
getBlending(layer->blending));
|
||||
ov.setSource(pargL, destL);
|
||||
|
||||
ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
|
||||
@@ -281,7 +289,10 @@ bool FBUpdateHighRes::configure(hwc_context_t *ctx,
|
||||
info,
|
||||
zOrder,
|
||||
ovutils::IS_FG_OFF,
|
||||
ovutils::ROT_FLAGS_NONE);
|
||||
ovutils::ROT_FLAGS_NONE,
|
||||
ovutils::DEFAULT_PLANE_ALPHA,
|
||||
(ovutils::eBlending)
|
||||
getBlending(layer->blending));
|
||||
ov.setSource(pargR, destR);
|
||||
|
||||
hwc_rect_t sourceCrop = layer->sourceCrop;
|
||||
|
||||
@@ -545,6 +545,18 @@ bool isSecureModePolicy(int mdpVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getBlending(int blending) {
|
||||
switch(blending) {
|
||||
case HWC_BLENDING_NONE:
|
||||
return overlay::utils::OVERLAY_BLENDING_OPAQUE;
|
||||
case HWC_BLENDING_PREMULT:
|
||||
return overlay::utils::OVERLAY_BLENDING_PREMULT;
|
||||
case HWC_BLENDING_COVERAGE :
|
||||
default:
|
||||
return overlay::utils::OVERLAY_BLENDING_COVERAGE;
|
||||
}
|
||||
}
|
||||
|
||||
//Crops source buffer against destination and FB boundaries
|
||||
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
|
||||
const hwc_rect_t& scissor, int orient) {
|
||||
@@ -1035,7 +1047,10 @@ int configureLowRes(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
||||
//For the mdp, since either we are pre-rotating or MDP does flips
|
||||
orient = OVERLAY_TRANSFORM_0;
|
||||
transform = 0;
|
||||
PipeArgs parg(mdpFlags, whf, z, isFg, static_cast<eRotFlags>(rotFlags));
|
||||
PipeArgs parg(mdpFlags, whf, z, isFg,
|
||||
static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
|
||||
(ovutils::eBlending) getBlending(layer->blending));
|
||||
|
||||
if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
|
||||
ALOGE("%s: commit failed for low res panel", __FUNCTION__);
|
||||
return -1;
|
||||
@@ -1164,7 +1179,9 @@ int configureHighRes(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
||||
//configure left mixer
|
||||
if(lDest != OV_INVALID) {
|
||||
PipeArgs pargL(mdpFlagsL, whf, z, isFg,
|
||||
static_cast<eRotFlags>(rotFlags));
|
||||
static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
|
||||
(ovutils::eBlending) getBlending(layer->blending));
|
||||
|
||||
if(configMdp(ctx->mOverlay, pargL, orient,
|
||||
tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
|
||||
ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
|
||||
@@ -1175,7 +1192,9 @@ int configureHighRes(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
||||
//configure right mixer
|
||||
if(rDest != OV_INVALID) {
|
||||
PipeArgs pargR(mdpFlagsR, whf, z, isFg,
|
||||
static_cast<eRotFlags>(rotFlags));
|
||||
static_cast<eRotFlags>(rotFlags),
|
||||
layer->planeAlpha,
|
||||
(ovutils::eBlending) getBlending(layer->blending));
|
||||
tmp_dstR.right = tmp_dstR.right - lSplit;
|
||||
tmp_dstR.left = tmp_dstR.left - lSplit;
|
||||
if(configMdp(ctx->mOverlay, pargR, orient,
|
||||
|
||||
@@ -170,6 +170,7 @@ bool isExternalActive(hwc_context_t* ctx);
|
||||
bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer, const int& dpy);
|
||||
bool isAlphaPresent(hwc_layer_1_t const* layer);
|
||||
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
|
||||
int getBlending(int blending);
|
||||
|
||||
//Helper function to dump logs
|
||||
void dumpsys_log(android::String8& buf, const char* fmt, ...);
|
||||
@@ -275,8 +276,7 @@ void init_uevent_thread(hwc_context_t* ctx);
|
||||
void init_vsync_thread(hwc_context_t* ctx);
|
||||
|
||||
inline void getLayerResolution(const hwc_layer_1_t* layer,
|
||||
int& width, int& height)
|
||||
{
|
||||
int& width, int& height) {
|
||||
hwc_rect_t displayFrame = layer->displayFrame;
|
||||
width = displayFrame.right - displayFrame.left;
|
||||
height = displayFrame.bottom - displayFrame.top;
|
||||
|
||||
@@ -94,13 +94,14 @@ void MdpCtrl::setSource(const utils::PipeArgs& args) {
|
||||
setSrcWhf(args.whf);
|
||||
|
||||
//TODO These are hardcoded. Can be moved out of setSource.
|
||||
mOVInfo.alpha = 0xff;
|
||||
mOVInfo.transp_mask = 0xffffffff;
|
||||
|
||||
//TODO These calls should ideally be a part of setPipeParams API
|
||||
setFlags(args.mdpFlags);
|
||||
setZ(args.zorder);
|
||||
setIsFg(args.isFg);
|
||||
setPlaneAlpha(args.planeAlpha);
|
||||
setBlending(args.blending);
|
||||
}
|
||||
|
||||
void MdpCtrl::setCrop(const utils::Dim& d) {
|
||||
|
||||
@@ -101,6 +101,11 @@ private:
|
||||
void setIsFg(utils::eIsFg isFg);
|
||||
/* return a copy of src whf*/
|
||||
utils::Whf getSrcWhf() const;
|
||||
/* set plane alpha */
|
||||
void setPlaneAlpha(int planeAlpha);
|
||||
/* set blending method */
|
||||
void setBlending(overlay::utils::eBlending blending);
|
||||
|
||||
/* set src whf */
|
||||
void setSrcWhf(const utils::Whf& whf);
|
||||
/* set src/dst rect dim */
|
||||
@@ -241,6 +246,24 @@ inline void MdpCtrl::setDownscale(int dscale) {
|
||||
mDownscale = dscale;
|
||||
}
|
||||
|
||||
inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
|
||||
mOVInfo.alpha = planeAlpha;
|
||||
}
|
||||
|
||||
inline void MdpCtrl::setBlending(overlay::utils::eBlending blending) {
|
||||
switch((int) blending) {
|
||||
case utils::OVERLAY_BLENDING_OPAQUE:
|
||||
mOVInfo.blend_op = BLEND_OP_OPAQUE;
|
||||
break;
|
||||
case utils::OVERLAY_BLENDING_PREMULT:
|
||||
mOVInfo.blend_op = BLEND_OP_PREMULTIPLIED;
|
||||
break;
|
||||
case utils::OVERLAY_BLENDING_COVERAGE:
|
||||
default:
|
||||
mOVInfo.blend_op = BLEND_OP_COVERAGE;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool MdpCtrl::ovChanged() const {
|
||||
#ifdef USES_POST_PROCESSING
|
||||
// Some pp params are stored as pointer address,
|
||||
|
||||
@@ -212,6 +212,8 @@ struct Whf {
|
||||
|
||||
enum { MAX_PATH_LEN = 256 };
|
||||
|
||||
enum { DEFAULT_PLANE_ALPHA = 0xFF };
|
||||
|
||||
/**
|
||||
* Rotator flags: not to be confused with orientation flags.
|
||||
* Usually, you want to open the rotator to make sure it is
|
||||
@@ -329,21 +331,36 @@ enum eTransform {
|
||||
OVERLAY_TRANSFORM_INV = 0x80
|
||||
};
|
||||
|
||||
enum eBlending {
|
||||
OVERLAY_BLENDING_UNDEFINED = 0x0,
|
||||
/* No blending */
|
||||
OVERLAY_BLENDING_OPAQUE,
|
||||
/* src.rgb + dst.rgb*(1-src_alpha) */
|
||||
OVERLAY_BLENDING_PREMULT,
|
||||
/* src.rgb * src_alpha + dst.rgb (1 - src_alpha) */
|
||||
OVERLAY_BLENDING_COVERAGE,
|
||||
};
|
||||
|
||||
// Used to consolidate pipe params
|
||||
struct PipeArgs {
|
||||
PipeArgs() : mdpFlags(OV_MDP_FLAGS_NONE),
|
||||
zorder(Z_SYSTEM_ALLOC),
|
||||
isFg(IS_FG_OFF),
|
||||
rotFlags(ROT_FLAGS_NONE){
|
||||
rotFlags(ROT_FLAGS_NONE),
|
||||
planeAlpha(DEFAULT_PLANE_ALPHA),
|
||||
blending(OVERLAY_BLENDING_COVERAGE){
|
||||
}
|
||||
|
||||
PipeArgs(eMdpFlags f, Whf _whf,
|
||||
eZorder z, eIsFg fg, eRotFlags r) :
|
||||
eZorder z, eIsFg fg, eRotFlags r,
|
||||
int pA = DEFAULT_PLANE_ALPHA, eBlending b = OVERLAY_BLENDING_COVERAGE) :
|
||||
mdpFlags(f),
|
||||
whf(_whf),
|
||||
zorder(z),
|
||||
isFg(fg),
|
||||
rotFlags(r) {
|
||||
rotFlags(r),
|
||||
planeAlpha(pA),
|
||||
blending(b){
|
||||
}
|
||||
|
||||
eMdpFlags mdpFlags; // for mdp_overlay flags
|
||||
@@ -351,6 +368,8 @@ struct PipeArgs {
|
||||
eZorder zorder; // stage number
|
||||
eIsFg isFg; // control alpha & transp
|
||||
eRotFlags rotFlags;
|
||||
int planeAlpha;
|
||||
eBlending blending;
|
||||
};
|
||||
|
||||
// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time
|
||||
|
||||
Reference in New Issue
Block a user