Exemplo n.º 1
0
void VideoOverlay::chooseState(hwc_context_t *ctx, int dpy,
        hwc_layer_1_t *yuvLayer) {
    ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__,
            ovutils::getStateString(sState[dpy]));

    private_handle_t *hnd = NULL;
    if(yuvLayer) {
        hnd = (private_handle_t *)yuvLayer->handle;
    }
    ovutils::eOverlayState newState = ovutils::OV_CLOSED;
    switch(dpy) {
        case HWC_DISPLAY_PRIMARY:
            if(ctx->listStats[dpy].yuvCount == 1) {
                newState = ovutils::OV_2D_VIDEO_ON_PANEL;
                if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) {
                    newState = ovutils::OV_CLOSED;
                }
            }
            break;
        case HWC_DISPLAY_EXTERNAL:
            newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState(); //If we are here, external is active
            if(ctx->listStats[dpy].yuvCount == 1) {
                if(!isSkipLayer(yuvLayer) || isSecureBuffer(hnd)) {
                    newState = ovutils::OV_UI_VIDEO_TV;
                }
            }
            break;
        default:
            break;
    }

    sState[dpy] = newState;
    ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
            ovutils::getStateString(sState[dpy]));
}
Exemplo n.º 2
0
//Cache stats, figure out the state, config overlay
bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
        int dpy) {

    int yuvIndex =  ctx->listStats[dpy].yuvIndex;
    sIsModeOn[dpy] = false;

    if(!ctx->mMDP.hasOverlay) {
       ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
       return false;
    }

    if(yuvIndex == -1 || ctx->listStats[dpy].yuvCount != 1) {
        return false;
    }

    //index guaranteed to be not -1 at this point
    hwc_layer_1_t *yuvLayer = &list->hwLayers[yuvIndex];

    private_handle_t *hnd = (private_handle_t *)yuvLayer->handle;
    if(ctx->mSecureMode) {
        if (! isSecureBuffer(hnd)) {
            ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer"
                     "during secure playback gracefully", __FUNCTION__);
            return false;
        }
    } else {
        if (isSecureBuffer(hnd)) {
            ALOGD_IF(VIDEO_DEBUG, "%s: Handle secure video layer"
                     "during non-secure playback gracefully", __FUNCTION__);
            return false;
        }
    }
    chooseState(ctx, dpy, yuvLayer);
    if(configure(ctx, dpy, yuvLayer)) {
        markFlags(yuvLayer);
        sIsModeOn[dpy] = true;
    }

    return sIsModeOn[dpy];
}
bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer) {
    if((ctx->mMDP.version < qdutils::MDSS_V5) &&
       (ctx->mMDP.version > qdutils::MDP_V3_0) &&
        ctx->mSecuring) {
        return true;
    }
    //  On A-Family, Secure policy is applied system wide and not on
    //  buffers.
    if (isSecureModePolicy(ctx->mMDP.version)) {
        private_handle_t *hnd = (private_handle_t *)layer->handle;
        if(ctx->mSecureMode) {
            if (! isSecureBuffer(hnd)) {
                // This code path executes for the following usecase:
                // Some Apps in which first few seconds, framework
                // sends non-secure buffer and with out destroying
                // surfaces, switches to secure buffer thereby exposing
                // vulnerability on A-family devices. Catch this situation
                // and handle it gracefully by allowing it to be composed by
                // GPU.
                ALOGD_IF(HWC_UTILS_DEBUG, "%s: Handle non-secure video layer"
                         "during secure playback gracefully", __FUNCTION__);
                return true;
            }
        } else {
            if (isSecureBuffer(hnd)) {
                // This code path executes for the following usecase:
                // For some Apps, when User terminates playback, Framework
                // doesnt destroy video surface and video surface still
                // comes to Display HAL. This exposes vulnerability on
                // A-family. Catch this situation and handle it gracefully
                // by allowing it to be composed by GPU.
                ALOGD_IF(HWC_UTILS_DEBUG, "%s: Handle secure video layer"
                         "during non-secure playback gracefully", __FUNCTION__);
                return true;
            }
        }
    }
    return false;
}
void setMdpFlags(hwc_layer_1_t *layer,
        ovutils::eMdpFlags &mdpFlags,
        int rotDownscale) {
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    const int& transform = layer->transform;

    if(layer->blending == HWC_BLENDING_PREMULT) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_BLEND_FG_PREMULT);
    }

    if(isYuvBuffer(hnd)) {
        if(isSecureBuffer(hnd)) {
            ovutils::setMdpFlags(mdpFlags,
                    ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
        }
        if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
                metadata->interlaced) {
            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);
        }
    }

    //No 90 component and no rot-downscale then flips done by MDP
    //If we use rot then it might as well do flips
    if(!(layer->transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) {
        if(layer->transform & HWC_TRANSFORM_FLIP_H) {
            ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
        }

        if(layer->transform & HWC_TRANSFORM_FLIP_V) {
            ovutils::setMdpFlags(mdpFlags,  ovutils::OV_MDP_FLIP_V);
        }
    }

    if(metadata &&
        ((metadata->operation & PP_PARAM_HSIC)
        || (metadata->operation & PP_PARAM_IGC)
        || (metadata->operation & PP_PARAM_SHARP2))) {
        ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_PP_EN);
    }
}
bool AssertiveDisplay::prepare(hwc_context_t *ctx,
        const hwc_rect_t& crop,
        const Whf& whf,
        const private_handle_t *hnd) {
    if(!isDoable()) {
        if(isModeOn()) {
            //Cleanup one time during this switch
            const int off = 0;
            adWrite(off);
            closeWbFb(mWbFd);
        }
        return false;
    }

    ovutils::eDest dest = ctx->mOverlay->nextPipe(ovutils::OV_MDP_PIPE_VG,
            overlay::Overlay::DPY_WRITEBACK, Overlay::MIXER_DEFAULT);
    if(dest == OV_INVALID) {
        ALOGE("%s failed: No VG pipe available", __func__);
        mDoable = false;
        return false;
    }

    overlay::Writeback *wb = overlay::Writeback::getInstance();

    //Set Security flag on writeback
    if(isSecureBuffer(hnd)) {
        if(!wb->setSecure(isSecureBuffer(hnd))) {
            ALOGE("Failure in setting WB secure flag for ad");
            return false;
        }
    }

    if(!wb->configureDpyInfo(hnd->width, hnd->height)) {
        ALOGE("%s: config display failed", __func__);
        mDoable = false;
        return false;
    }

    int tmpW, tmpH, size;
    int format = ovutils::getHALFormat(wb->getOutputFormat());
    if(format < 0) {
        ALOGE("%s invalid format %d", __func__, format);
        mDoable = false;
        return false;
    }

    size = getBufferSizeAndDimensions(hnd->width, hnd->height,
                format, tmpW, tmpH);

    if(!wb->configureMemory(size)) {
        ALOGE("%s: config memory failed", __func__);
        mDoable = false;
        return false;
    }

    eMdpFlags mdpFlags = OV_MDP_FLAGS_NONE;
    if(isSecureBuffer(hnd)) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
    }

    PipeArgs parg(mdpFlags, whf, ZORDER_0, IS_FG_OFF,
            ROT_FLAGS_NONE);
    hwc_rect_t dst = crop; //input same as output

    if(configMdp(ctx->mOverlay, parg, OVERLAY_TRANSFORM_0, crop, dst, NULL,
                dest) < 0) {
        ALOGE("%s: configMdp failed", __func__);
        mDoable = false;
        return false;
    }

    mDest = dest;
    if(!isModeOn()) {
        mWbFd = openWbFb();
        if(mWbFd >= 0) {
            //write to sysfs, one time during this switch
            const int on = 1;
            adWrite(on);
        }
    }
    return true;
}
Exemplo n.º 6
0
void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
{
    //Video specific stats
    int yuvCount = 0;
    int yuvLayerIndex = -1;
    int pipLayerIndex = -1; //2nd video in pip scenario
    bool isYuvLayerSkip = false;
    int skipCount = 0;
    int ccLayerIndex = -1; //closed caption
    int extLayerIndex = -1; //ext-only or block except closed caption
    int extCount = 0; //ext-only except closed caption
    bool isExtBlockPresent = false; //is BLOCK layer present
    bool yuvSecure = false;

    for (size_t i = 0; i < list->numHwLayers; i++) {
        private_handle_t *hnd =
            (private_handle_t *)list->hwLayers[i].handle;

        if (UNLIKELY(isYuvBuffer(hnd))) {
            yuvCount++;
            if(yuvCount==1) {
                //Set the primary video to the video layer in
                //lower z-order
                yuvLayerIndex = i;
            }
            if(yuvCount == 2) {
                //In case of two videos, set the pipLayerIndex to the
                //second video
                pipLayerIndex = i;
            }
            yuvSecure = isSecureBuffer(hnd);
            //Animating
            //Do not mark as SKIP if it is secure buffer
            if (isSkipLayer(&list->hwLayers[i]) && !yuvSecure) {
                isYuvLayerSkip = true;
            }
        } else if(UNLIKELY(isExtCC(hnd))) {
            ccLayerIndex = i;
        } else if(UNLIKELY(isExtBlock(hnd))) {
            extCount++;
            extLayerIndex = i;
            isExtBlockPresent = true;
        } else if(UNLIKELY(isExtOnly(hnd))) {
            extCount++;
            //If BLOCK layer present, dont cache index, display BLOCK only.
            if(isExtBlockPresent == false) extLayerIndex = i;
        } else if (isSkipLayer(&list->hwLayers[i])) { //Popups
            skipCount++;
        }
    }

    VideoOverlay::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip,
                           ccLayerIndex);
    VideoPIP::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip,
                       pipLayerIndex);
    ExtOnly::setStats(extCount, extLayerIndex, isExtBlockPresent);
    CopyBit::setStats(skipCount);
    MDPComp::setStats(skipCount);

    ctx->numHwLayers = list->numHwLayers;
    return;
}
Exemplo n.º 7
0
bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
    overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);

    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
    if (isSecureBuffer(hnd)) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
    }

    if(layer->blending == HWC_BLENDING_PREMULT) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_BLEND_FG_PREMULT);
    }

    ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
    if (ctx->listStats[HWC_DISPLAY_EXTERNAL].numAppLayers == 1) {
        isFgFlag = ovutils::IS_FG_SET;
    }

    ovutils::PipeArgs parg(mdpFlags,
            info,
            ovutils::ZORDER_1,
            isFgFlag,
            ovutils::ROT_FLAG_DISABLED);
    ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
    ov.setSource(pargs, ovutils::OV_PIPE1);

    int transform = layer->transform;
    ovutils::eTransform orient =
            static_cast<ovutils::eTransform>(transform);

    hwc_rect_t sourceCrop = layer->sourceCrop;
    hwc_rect_t displayFrame = layer->displayFrame;

    //Calculate the rect for primary based on whether the supplied position
    //is within or outside bounds.
    const int fbWidth = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres;
    const int fbHeight = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].yres;

    if( displayFrame.left < 0 ||
            displayFrame.top < 0 ||
            displayFrame.right > fbWidth ||
            displayFrame.bottom > fbHeight) {
        calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight,
                transform);
    }

    // x,y,w,h
    ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
            sourceCrop.right - sourceCrop.left,
            sourceCrop.bottom - sourceCrop.top);
    //Only for External
    ov.setCrop(dcrop, ovutils::OV_PIPE1);

    ov.setTransform(orient, ovutils::OV_PIPE1);

    ovutils::Dim dpos(displayFrame.left,
            displayFrame.top,
            (displayFrame.right - displayFrame.left),
            (displayFrame.bottom - displayFrame.top));

    //Only for External
    ov.setPosition(dpos, ovutils::OV_PIPE1);

    if (!ov.commit(ovutils::OV_PIPE1)) {
        ALOGE("%s: commit fails", __FUNCTION__);
        return false;
    }
    return true;
}