// Configure
bool FBUpdateSplit::configure(hwc_context_t *ctx,
        hwc_display_contents_1 *list, hwc_rect_t fbUpdatingRect, int fbZorder) {
    bool ret = false;
    hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
    if (LIKELY(ctx->mOverlay)) {
        /*  External only layer present */
        int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
        if(extOnlyLayerIndex != -1) {
            layer = &list->hwLayers[extOnlyLayerIndex];
            layer->compositionType = HWC_OVERLAY;
        }
        ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
                          ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
                                                mTileEnabled));

        overlay::Overlay& ov = *(ctx->mOverlay);
        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
        ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
        ovutils::eTransform orient =
            static_cast<ovutils::eTransform>(layer->transform);
        const int hw_w = ctx->dpyAttr[mDpy].xres;
        const int hw_h = ctx->dpyAttr[mDpy].yres;
        const int lSplit = getLeftSplit(ctx, mDpy);
        mDestLeft = ovutils::OV_INVALID;
        mDestRight = ovutils::OV_INVALID;

        hwc_rect_t sourceCrop = fbUpdatingRect;
        hwc_rect_t displayFrame = fbUpdatingRect;

        ret = true;
        Overlay::PipeSpecs pipeSpecs;
        pipeSpecs.formatClass = Overlay::FORMAT_RGB;
        pipeSpecs.needsScaling = qhwc::needsScaling(layer);
        pipeSpecs.dpy = mDpy;
        pipeSpecs.fb = true;

        /* Configure left pipe */
        if(displayFrame.left < lSplit) {
            pipeSpecs.mixer = Overlay::MIXER_LEFT;
            ovutils::eDest destL = ov.getPipe(pipeSpecs);
            if(destL == ovutils::OV_INVALID) { //None available
                ALOGE("%s: No pipes available to configure fb for dpy %d's left"
                      " mixer", __FUNCTION__, mDpy);
                return false;
            }

            mDestLeft = destL;

            //XXX: FB layer plane alpha is currently sent as zero from
            //surfaceflinger
            ovutils::PipeArgs pargL(mdpFlags,
                                    info,
                                    zOrder,
                                    ovutils::IS_FG_OFF,
                                    ovutils::ROT_FLAGS_NONE,
                                    ovutils::DEFAULT_PLANE_ALPHA,
                                    (ovutils::eBlending)
                                    getBlending(layer->blending));
            hwc_rect_t cropL = sourceCrop;
            hwc_rect_t dstL = displayFrame;
            hwc_rect_t scissorL = {0, 0, lSplit, hw_h };
            qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);

            if (configMdp(ctx->mOverlay, pargL, orient, cropL,
                           dstL, NULL, destL)< 0) {
                ALOGE("%s: configMdp fails for left FB", __FUNCTION__);
                ret = false;
            }
        }

        /* Configure right pipe */
        if(displayFrame.right > lSplit) {
            pipeSpecs.mixer = Overlay::MIXER_RIGHT;
            ovutils::eDest destR = ov.getPipe(pipeSpecs);
            if(destR == ovutils::OV_INVALID) { //None available
                ALOGE("%s: No pipes available to configure fb for dpy %d's"
                      " right mixer", __FUNCTION__, mDpy);
                return false;
            }

            mDestRight = destR;
            ovutils::eMdpFlags mdpFlagsR = mdpFlags;
            ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);

            //XXX: FB layer plane alpha is currently sent as zero from
            //surfaceflinger
            ovutils::PipeArgs pargR(mdpFlagsR,
                                    info,
                                    zOrder,
                                    ovutils::IS_FG_OFF,
                                    ovutils::ROT_FLAGS_NONE,
                                    ovutils::DEFAULT_PLANE_ALPHA,
                                    (ovutils::eBlending)
                                    getBlending(layer->blending));

            hwc_rect_t cropR = sourceCrop;
            hwc_rect_t dstR = displayFrame;
            hwc_rect_t scissorR = {lSplit, 0, hw_w, hw_h };
            qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);

            dstR.left -= lSplit;
            dstR.right -= lSplit;

            if (configMdp(ctx->mOverlay, pargR, orient, cropR,
                           dstR, NULL, destR) < 0) {
                ALOGE("%s: configMdp fails for right FB", __FUNCTION__);
                ret = false;
            }
        }
    }
    return ret;
}
예제 #2
0
int allocate_overlay(int fd, GGLSurface gr_fb[])
{
    int ret = 0;

    if (!overlay_supported)
        return -EINVAL;

    if (!isDisplaySplit()) {
        // Check if overlay is already allocated
        if (MSMFB_NEW_REQUEST == overlayL_id) {
            struct mdp_overlay overlayL;

            memset(&overlayL, 0 , sizeof (struct mdp_overlay));

            /* Fill Overlay Data */
            overlayL.src.width  = ALIGN(gr_fb[0].width, 32);
            overlayL.src.height = gr_fb[0].height;
            overlayL.src.format = map_mdp_pixel_format();
            overlayL.src_rect.w = gr_fb[0].width;
            overlayL.src_rect.h = gr_fb[0].height;
            overlayL.dst_rect.w = gr_fb[0].width;
            overlayL.dst_rect.h = gr_fb[0].height;
            overlayL.alpha = 0xFF;
            overlayL.transp_mask = MDP_TRANSP_NOP;
            overlayL.id = MSMFB_NEW_REQUEST;
            ret = ioctl(fd, MSMFB_OVERLAY_SET, &overlayL);
            if (ret < 0) {
                perror("Overlay Set Failed");
                return ret;
            }
            overlayL_id = overlayL.id;
        }
    } else {
        float xres = getFbXres();
        int lSplit = getLeftSplit();
        float lSplitRatio = lSplit / xres;
        float lCropWidth = gr_fb[0].width * lSplitRatio;
        int lWidth = lSplit;
        int rWidth = gr_fb[0].width - lSplit;
        int height = gr_fb[0].height;

        if (MSMFB_NEW_REQUEST == overlayL_id) {

            struct mdp_overlay overlayL;

            memset(&overlayL, 0 , sizeof (struct mdp_overlay));

            /* Fill OverlayL Data */
            overlayL.src.width  = ALIGN(gr_fb[0].width, 32);
            overlayL.src.height = gr_fb[0].height;
            overlayL.src.format = map_mdp_pixel_format();
            overlayL.src_rect.x = 0;
            overlayL.src_rect.y = 0;
            overlayL.src_rect.w = lCropWidth;
            overlayL.src_rect.h = gr_fb[0].height;
            overlayL.dst_rect.x = 0;
            overlayL.dst_rect.y = 0;
            overlayL.dst_rect.w = lWidth;
            overlayL.dst_rect.h = height;
            overlayL.alpha = 0xFF;
            overlayL.transp_mask = MDP_TRANSP_NOP;
            overlayL.id = MSMFB_NEW_REQUEST;
            ret = ioctl(fd, MSMFB_OVERLAY_SET, &overlayL);
            if (ret < 0) {
                perror("OverlayL Set Failed");
                return ret;
            }
            overlayL_id = overlayL.id;
        }
        if (MSMFB_NEW_REQUEST == overlayR_id) {
            struct mdp_overlay overlayR;

            memset(&overlayR, 0 , sizeof (struct mdp_overlay));

            /* Fill OverlayR Data */
            overlayR.src.width  = ALIGN(gr_fb[0].width, 32);
            overlayR.src.height = gr_fb[0].height;
            overlayR.src.format = map_mdp_pixel_format();
            overlayR.src_rect.x = lCropWidth;
            overlayR.src_rect.y = 0;
            overlayR.src_rect.w = gr_fb[0].width - lCropWidth;
            overlayR.src_rect.h = gr_fb[0].height;
            overlayR.dst_rect.x = 0;
            overlayR.dst_rect.y = 0;
            overlayR.dst_rect.w = rWidth;
            overlayR.dst_rect.h = height;
            overlayR.alpha = 0xFF;
            overlayR.flags = MDSS_MDP_RIGHT_MIXER;
            overlayR.transp_mask = MDP_TRANSP_NOP;
            overlayR.id = MSMFB_NEW_REQUEST;
            ret = ioctl(fd, MSMFB_OVERLAY_SET, &overlayR);
            if (ret < 0) {
                perror("OverlayR Set Failed");
                return ret;
            }
            overlayR_id = overlayR.id;
        }

    }
    return 0;
}