Example #1
0
void MdpCtrl::updateSource(RotatorBase* r,
        const utils::PipeArgs& args,
        const utils::ScreenInfo& info) {
    utils::Whf whf(args.whf);
    mOVInfo.src.width  = whf.w;
    mOVInfo.src.height = whf.h;
    mOVInfo.src_rect.x = 0;
    mOVInfo.src_rect.y = 0;
    mOVInfo.dst_rect.x = 0;
    mOVInfo.dst_rect.y = 0;
    mOVInfo.dst_rect.w = whf.w;
    mOVInfo.dst_rect.h = whf.h;
    mOVInfo.src.format = whf.format;

    if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
        (whf.format == MDP_Y_CBCR_H2V2_TILE)) {
        // passing by value, setInfo fills it and return by val
        mOVInfo = r->setInfo(args, mOVInfo);
    } else {
        mOVInfo.src_rect.w = whf.w;
        mOVInfo.src_rect.h = whf.h;
    }

    if (whf.w > info.mFBWidth)
        mOVInfo.dst_rect.w = info.mFBWidth;
    if (whf.h > info.mFBHeight)
        mOVInfo.dst_rect.h = info.mFBHeight;
    mSize = whf.size;
}
void MdpRot::setSource(const overlay::utils::Whf& awhf) {
    utils::Whf whf(awhf);
    mRotImgInfo.src.format = whf.format;

    mRotImgInfo.src.width = whf.w;
    mRotImgInfo.src.height = whf.h;

    mRotImgInfo.src_rect.w = whf.w;
    mRotImgInfo.src_rect.h = whf.h;

    mRotImgInfo.dst.width = whf.w;
    mRotImgInfo.dst.height = whf.h;
}
void MdssRot::setSource(const overlay::utils::Whf& awhf) {
    utils::Whf whf(awhf);

    mRotInfo.src.format = whf.format;
    if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
        whf.format == MDP_Y_CBCR_H2V2_TILE) {
        whf.w =  utils::alignup(awhf.w, 64);
        whf.h = utils::alignup(awhf.h, 32);
    }

    mRotInfo.src.width = whf.w;
    mRotInfo.src.height = whf.h;

    mRotInfo.src_rect.w = whf.w;
    mRotInfo.src_rect.h = whf.h;

    mRotInfo.dst_rect.w = whf.w;
    mRotInfo.dst_rect.h = whf.h;
}
Example #4
0
bool MdpCtrl::setInfo(RotatorBase* r,
        const utils::PipeArgs& args,
        const utils::ScreenInfo& info)
{
    // new request
    utils::Whf whf(args.whf);
    mOVInfo.id = MSMFB_NEW_REQUEST;

    updateSource(r, args, info);

    setUserData(0);
    mOVInfo.alpha = 0xff;
    mOVInfo.transp_mask = 0xffffffff;
    setZ(args.zorder);
    setFlags(args.mdpFlags);
    setWait(args.wait);
    setIsFg(args.isFg);
    mSize = whf.size;
    return true;
}
bool GenericPipe::setSource(
        const utils::PipeArgs& args)
{
    utils::PipeArgs newargs(args);
    //Interlace video handling.
    if(newargs.whf.format & INTERLACE_MASK) {
        setMdpFlags(newargs.mdpFlags, utils::OV_MDP_DEINTERLACE);
    }
    utils::Whf whf(newargs.whf);
    //Extract HAL format from lower bytes. Deinterlace if interlaced.
    whf.format = utils::getColorFormat(whf.format);
    //Get MDP equivalent of HAL format.
    whf.format = utils::getMdpFormat(whf.format);
    newargs.whf = whf;

    //Cache if user wants 0-rotation
    mRotUsed = newargs.rotFlags & utils::ROT_0_ENABLED;
    mRotDownscaleOpt = newargs.rotFlags & utils::ROT_DOWNSCALE_ENABLED;

    mRot->setSource(newargs.whf);
    mRot->setFlags(newargs.mdpFlags);
    return mCtrlData.ctrl.setSource(newargs);
}
/**
 * For that test you would need to luanch camera
 * so it would punch a hole for you.
 */
int main(int, char**)
{
   LOGE("%s start", LOG_TAG);

   overlay2::GenericPipe<ovutils::FB0> pipe;
   overlay2::RotatorBase* r = new overlay2::NullRotator();
   LOGE("Using null rotator");
   bool ret = pipe.open(r);
   OVASSERT(ret, "Failed to open pipe");

   LOGE("start ...");
   ovutils::Whf whf(1024, 600, HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED);
   /* since we are using camera apk for punching a hole for us
    * we need ZOERDER_1 here so it will be on top of camera */
   ovutils::eMdpFlags flags = ovutils::OV_MDP_FLAGS_NONE;
   ovutils::PipeArgs args(flags,
                          ovutils::OVERLAY_TRANSFORM_0,
                          whf,
                          ovutils::WAIT,
                          ovutils::ZORDER_1,
                          ovutils::IS_FG_OFF,
                          ovutils::ROT_FLAG_DISABLED,
                          ovutils::PMEM_SRC_SMI,
                          ovutils::RECONFIG_OFF);
   ret = pipe.start(args);

   OVASSERT(ret, "Failed to start pipe");

   // let's try openning /dev/zero and mmap it.
   LOGE("Open /dev/pmem_adsp");
   overlay2::OvMem m;
   uint32_t bfsz = 1024*600*4;
   ret = m.open(ovutils::PMEM_SRC_ADSP,
                1,     // one buf
                bfsz); //size
   OVASSERT(ret, "Failed to open /dev/pmem_adsp pipe");
   m.dump();
   ::memset(m.addr(), 0, bfsz);
   pipe.setMemoryId(m.getFD());
   ovutils::Dim dim(0, 0, 1024, 600); // x,y,w,h
   ret = pipe.setPosition(dim);
   OVASSERT(ret, "Failed to setPosition");

   LOGE("Before play ...");
   pipe.dump();
   enum { NUM_PLAY = 10 };
   for (uint32_t i=0; i < NUM_PLAY; ++i) {
      ret = pipe.queueBuffer(0); // offset 0
      OVASSERT(ret, "Failed to queueBuffer");
      sleep(1);
   }

   ret = r->close();
   OVASSERT(ret, "Error in rotator close");

   ret = pipe.close();
   OVASSERT(ret, "Error in pipe close");

   ret = m.close();

   delete r;
   r=0;
   LOGE("%s end", LOG_TAG);
   return 0;
}
int main(int, char**)
{
   LOGE("OverlayCtrlTest start");

   overlay2::Ctrl ctrl;
   overlay2::RotatorBase* rot = new overlay2::NullRotator();

   // open rot here
   bool ret = rot->open();
   OVASSERT(ret, "Rotator failed to open");
   ovutils::PipeArgs args(ovutils::OV_MDP_FLAGS_NONE,//flags PIPE SHARED
                          ovutils::OVERLAY_TRANSFORM_0,
                          ovutils::Whf(),
                          ovutils::WAIT,
                          ovutils::ZORDER_0,
                          ovutils::IS_FG_OFF,
                          ovutils::ROT_FLAG_ENABLED,
                          ovutils::PMEM_SRC_ADSP,
                          ovutils::RECONFIG_OFF);
   ret = rot->remap(ROT_NUM_BUF, args);
   OVASSERT(ret, "Rotator failed to remap");

   ret = ctrl.open(ovutils::FB0, rot);
   OVASSERT(ret, "Ctrl failed to open");
   ovutils::Whf whf(100, 200, HAL_PIXEL_FORMAT_RGBA_8888);
   ovutils::eMdpFlags flags = ovutils::OV_MDP_FLAGS_NONE;
   ret = ctrl.start(args);
   OVASSERT(ret, "Ctrl failed to start");
   ctrl.dump();

   LOGE("setPosition ...");
   ovutils::Dim dim(0, 0, 50, 100);
   ret = ctrl.setPosition(dim);
   OVASSERT(ret, "Ctrl failed to setPosition");
   ctrl.dump();

   LOGE("setParameter ...");
   ovutils::Params p ( ovutils::OVERLAY_DITHER, 0 );
   ret = ctrl.setParameter(p);
   OVASSERT(ret, "Ctrl failed to setParameter");
   ctrl.dump();

   LOGE("setSource ...");
   ovutils::PipeArgs args1(flags,
                           ovutils::OVERLAY_TRANSFORM_0,
                           ovutils::Whf(75, 150, HAL_PIXEL_FORMAT_RGBA_8888),
                           ovutils::WAIT,
                           ovutils::ZORDER_0,
                           ovutils::IS_FG_OFF,
                           ovutils::ROT_FLAG_DISABLED,
                           ovutils::PMEM_SRC_SMI,
                           ovutils::RECONFIG_OFF);
   ret = ctrl.setSource(args1);
   OVASSERT(ret, "Ctrl failed to setSource");
   ctrl.commit();
   ctrl.dump();

   ctrl.close();
   rot->close();
   delete rot;

   LOGE("OverlayCtrlTest end");
   return 0;
}
int configureLowRes(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy, eMdpFlags& mdpFlags, const eZorder& z,
        const eIsFg& isFg, const eDest& dest, Rotator **rot) {

    private_handle_t *hnd = (private_handle_t *)layer->handle;
    if(!hnd) {
        ALOGE("%s: layer handle is NULL", __FUNCTION__);
        return -1;
    }

    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;

    hwc_rect_t crop = layer->sourceCrop;
    hwc_rect_t dst = layer->displayFrame;
    int transform = layer->transform;
    eTransform orient = static_cast<eTransform>(transform);
    int downscale = 0;
    int rotFlags = ovutils::ROT_FLAGS_NONE;
    Whf whf(getWidth(hnd), getHeight(hnd),
            getMdpFormat(hnd->format), hnd->size);
    bool forceRot = false;

    if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 &&
       ctx->mMDP.version < qdutils::MDSS_V5) {
        downscale =  getDownscaleFactor(
            crop.right - crop.left,
            crop.bottom - crop.top,
            dst.right - dst.left,
            dst.bottom - dst.top);
        if(downscale) {
            rotFlags = ROT_DOWNSCALE_ENABLED;
        }
        unsigned int& prevWidth = ctx->mPrevWHF[dpy].w;
        unsigned int& prevHeight = ctx->mPrevWHF[dpy].h;
        if(prevWidth != (uint32_t)getWidth(hnd) ||
               prevHeight != (uint32_t)getHeight(hnd)) {
            uint32_t prevBufArea = (prevWidth * prevHeight);
            if(prevBufArea) {
                forceRot = true;
            }
            prevWidth = (uint32_t)getWidth(hnd);
            prevHeight = (uint32_t)getHeight(hnd);
        }
    }

    setMdpFlags(layer, mdpFlags, downscale);
    trimLayer(ctx, dpy, transform, crop, dst);

    if(isYuvBuffer(hnd) && //if 90 component or downscale, use rot
            ((transform & HWC_TRANSFORM_ROT_90) || downscale || forceRot)) {
        *rot = ctx->mRotMgr->getNext();
        if(*rot == NULL) return -1;
        //Configure rotator for pre-rotation
        Whf origWhf(hnd->width, hnd->height,
                    getMdpFormat(hnd->format), hnd->size);
        if(configRotator(*rot, whf, origWhf,  mdpFlags, orient, downscale) < 0)
            return -1;
        ctx->mLayerRotMap[dpy]->add(layer, *rot);
        whf.format = (*rot)->getDstFormat();
        updateSource(orient, whf, crop);
        rotFlags |= ovutils::ROT_PREROTATED;
    }

    //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), 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__);
        ctx->mLayerRotMap[dpy]->reset();
        return -1;
    }
    return 0;
}
int configureHighRes(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy, eMdpFlags& mdpFlagsL, const eZorder& z,
        const eIsFg& isFg, const eDest& lDest, const eDest& rDest,
        Rotator **rot) {
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    if(!hnd) {
        ALOGE("%s: layer handle is NULL", __FUNCTION__);
        return -1;
    }

    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;

    int hw_w = ctx->dpyAttr[dpy].xres;
    int hw_h = ctx->dpyAttr[dpy].yres;
    hwc_rect_t crop = layer->sourceCrop;
    hwc_rect_t dst = layer->displayFrame;
    int transform = layer->transform;
    eTransform orient = static_cast<eTransform>(transform);
    const int downscale = 0;
    int rotFlags = ROT_FLAGS_NONE;

    Whf whf(getWidth(hnd), getHeight(hnd),
            getMdpFormat(hnd->format), hnd->size);

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

    if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
        (*rot) = ctx->mRotMgr->getNext();
        if((*rot) == NULL) return -1;
        //Configure rotator for pre-rotation
        Whf origWhf(hnd->width, hnd->height,
                    getMdpFormat(hnd->format), hnd->size);
        if(configRotator(*rot, whf, origWhf, mdpFlagsL, orient, downscale) < 0)
            return -1;
        ctx->mLayerRotMap[dpy]->add(layer, *rot);
        whf.format = (*rot)->getDstFormat();
        updateSource(orient, whf, crop);
        rotFlags |= ROT_PREROTATED;
    }

    eMdpFlags mdpFlagsR = mdpFlagsL;
    setMdpFlags(mdpFlagsR, OV_MDSS_MDP_RIGHT_MIXER);

    hwc_rect_t tmp_cropL, tmp_dstL;
    hwc_rect_t tmp_cropR, tmp_dstR;

    if(lDest != OV_INVALID) {
        tmp_cropL = crop;
        tmp_dstL = dst;
        hwc_rect_t scissor = {0, 0, hw_w/2, hw_h };
        qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
    }
    if(rDest != OV_INVALID) {
        tmp_cropR = crop;
        tmp_dstR = dst;
        hwc_rect_t scissor = {hw_w/2, 0, hw_w, hw_h };
        qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
    }

    //When buffer is flipped, contents of mixer config also needs to swapped.
    //Not needed if the layer is confined to one half of the screen.
    //If rotator has been used then it has also done the flips, so ignore them.
    if((orient & OVERLAY_TRANSFORM_FLIP_V) && lDest != OV_INVALID
            && rDest != OV_INVALID && rot == NULL) {
        hwc_rect_t new_cropR;
        new_cropR.left = tmp_cropL.left;
        new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);

        hwc_rect_t new_cropL;
        new_cropL.left  = new_cropR.right;
        new_cropL.right = tmp_cropR.right;

        tmp_cropL.left =  new_cropL.left;
        tmp_cropL.right =  new_cropL.right;

        tmp_cropR.left = new_cropR.left;
        tmp_cropR.right =  new_cropR.right;

    }

    //For the mdp, since either we are pre-rotating or MDP does flips
    orient = OVERLAY_TRANSFORM_0;
    transform = 0;

    //configure left mixer
    if(lDest != OV_INVALID) {
        PipeArgs pargL(mdpFlagsL, whf, z, isFg,
                       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__);
            return -1;
        }
    }

    //configure right mixer
    if(rDest != OV_INVALID) {
        PipeArgs pargR(mdpFlagsR, whf, z, isFg,
                static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
                (ovutils::eBlending) getBlending(layer->blending));

        tmp_dstR.right = tmp_dstR.right - tmp_dstR.left;
        tmp_dstR.left = 0;
        if(configMdp(ctx->mOverlay, pargR, orient,
                tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
            return -1;
        }
    }

    return 0;
}