C++程序  |  485行  |  11.15 KB

/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef OVERLAY_MDP_H
#define OVERLAY_MDP_H

#include <linux/msm_mdp.h>

#include "overlayUtils.h"
#include "mdpWrapper.h"

namespace overlay{

/*
* Mdp Ctrl holds corresponding fd and MDP related struct.
* It is simple wrapper to MDP services
* */
class MdpCtrl {
public:
    /* ctor reset */
    explicit MdpCtrl();

    /* dtor close */
    ~MdpCtrl();

    /* init underlying device using fbnum */
    bool init(uint32_t fbnum);

    /* unset overlay, reset and close fd */
    bool close();

    /* reset and set ov id to -1 / MSMFB_NEW_REQUEST */
    void reset();

    /* get orient / user_data[0] */
    int getOrient() const;

    /* returns session id */
    int getPipeId() const;

    /* returns the fd associated to ctrl*/
    int getFd() const;

    /* Get screen info. out: info*/
    bool getScreenInfo(utils::ScreenInfo& info);

    /* overlay get */
    bool get();

    /* returns flags from mdp structure */
    int getFlags() const;

    /* set flags to mdp structure */
    void setFlags(int f);

    /* set z order */
    void setZ(utils::eZorder z);

    /* set isFg flag */
    void setIsFg(utils::eIsFg isFg);

    /* calls overlay set
     * Set would always consult last good known ov instance.
     * Only if it is different, set would actually exectue ioctl.
     * On a sucess ioctl. last good known ov instance is updated */
    bool set();

    /* return a copy of src whf*/
    utils::Whf getSrcWhf() const;

    /* set src whf */
    void setSrcWhf(const utils::Whf& whf);

    /* adjust source width height format based on rot info */
    void adjustSrcWhf(const bool& rotUsed);

    /* swap src w/h*/
    void swapSrcWH();

    /* swap src rect w/h */
    void swapSrcRectWH();

    /* returns a copy to src rect dim */
    utils::Dim getSrcRectDim() const;

    /* set src/dst rect dim */
    void setSrcRectDim(const utils::Dim d);
    void setDstRectDim(const utils::Dim d);

    /* returns a copy ro dst rect dim */
    utils::Dim getDstRectDim() const;

    /* returns user_data[0]*/
    int getUserData() const;

    /* sets user_data[0] */
    void setUserData(int v);

    /* return true if current overlay is different
     * than last known good overlay */
    bool ovChanged() const;

    /* save mOVInfo to be last known good ov*/
    void save();

    /* restore last known good ov to be the current */
    void restore();

    /* Sets the source total width, height, format */
    bool setSource(const utils::PipeArgs& pargs);

    /*
     * Sets ROI, the unpadded region, for source buffer.
     * Should be called before a setPosition, for small clips.
     * Dim - ROI dimensions.
     */
    bool setCrop(const utils::Dim& d);

    bool setTransform(const utils::eTransform& orient, const bool& rotUsed);

    /* given a dim and w/h, set overlay dim */
    bool setPosition(const utils::Dim& dim, int w, int h);

    /* using user_data, sets/unsets roationvalue in mdp flags */
    void setRotationFlags();

    /* dump state of the object */
    void dump() const;

private:

    /* helper functions for overlayTransform */
    void doTransform();
    void overlayTransFlipH();
    void overlayTransFlipV();
    void overlayTransRot90();

    utils::eTransform mOrientation; //Holds requested orientation
    bool mRotUsed; //whether rotator should be used even if requested
                   //orientation is 0.

    /* last good known ov info */
    mdp_overlay   mLkgo;

    /* Actual overlay mdp structure */
    mdp_overlay   mOVInfo;

    /* FD for the mdp fbnum */
    OvFD          mFd;
};


/* MDP 3D related ctrl */
class MdpCtrl3D {
public:
    /* ctor reset data */
    MdpCtrl3D();
    /* calls MSMFB_OVERLAY_3D */
    bool close();
    /* set w/h. format is ignored*/
    void setWh(const utils::Whf& whf);
    /* set is_3d calls MSMFB_OVERLAY_3D */
    bool useVirtualFB();
    /* set fd to be used in ioctl */
    void setFd(int fd);
    /* dump */
    void dump() const;
private:
    /* reset */
    void reset();
    /* actual MSM 3D info */
    msmfb_overlay_3d m3DOVInfo;
    /* FD for the mdp 3D */
    OvFD mFd;
};

/* MDP data */
class MdpData {
public:
    /* ctor reset data */
    explicit MdpData();

    /* dtor close*/
    ~MdpData();

    /* init FD */
    bool init(uint32_t fbnum);

    /* memset0 the underlying mdp object */
    void reset();

    /* close fd, and reset */
    bool close();

    /* set id of mdp data */
    void setPipeId(int id);

    /* return ses id of data */
    int getPipeId() const;

    /* get underlying fd*/
    int getFd() const;

    /* get memory_id */
    int getSrcMemoryId() const;

    /* calls wrapper play */
    bool play(int fd, uint32_t offset);

    /* dump state of the object */
    void dump() const;
private:

    /* actual overlay mdp data */
    msmfb_overlay_data mOvData;

    /* fd to mdp fbnum */
    OvFD mFd;
};

//--------------Inlines---------------------------------
namespace {
// just a helper func for common operations x-(y+z)
int compute(uint32_t x, uint32_t y, uint32_t z) {
    return x-(y+z);
}
}

/////   MdpCtrl  //////

inline MdpCtrl::MdpCtrl() {
    reset();
}

inline MdpCtrl::~MdpCtrl() {
    close();
}

inline int MdpCtrl::getOrient() const {
    return getUserData();
}

inline int MdpCtrl::getPipeId() const {
    return mOVInfo.id;
}

inline int MdpCtrl::getFd() const {
    return mFd.getFD();
}

inline int MdpCtrl::getFlags() const {
    return mOVInfo.flags;
}

inline void MdpCtrl::setFlags(int f) {
    mOVInfo.flags = f;
}

inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
    mOVInfo.z_order = z;
}

inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
    mOVInfo.is_fg = isFg;
}

inline bool MdpCtrl::ovChanged() const {
    // 0 means same
    if(0 == ::memcmp(&mOVInfo, &mLkgo, sizeof (mdp_overlay))) {
        return false;
    }
    return true;
}

inline void MdpCtrl::save() {
    if(static_cast<ssize_t>(mOVInfo.id) == MSMFB_NEW_REQUEST) {
        ALOGE("MdpCtrl current ov has id -1, will not save");
        return;
    }
    mLkgo = mOVInfo;
}

inline void MdpCtrl::restore() {
    if(static_cast<ssize_t>(mLkgo.id) == MSMFB_NEW_REQUEST) {
        ALOGE("MdpCtrl Lkgo ov has id -1, will not restore");
        return;
    }
    mOVInfo = mLkgo;
}

inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
    return utils::Whf(  mOVInfo.src.width,
                        mOVInfo.src.height,
                        mOVInfo.src.format);
}

inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
    mOVInfo.src.width  = whf.w;
    mOVInfo.src.height = whf.h;
    mOVInfo.src.format = whf.format;
}

inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
    return utils::Dim(  mOVInfo.src_rect.x,
                        mOVInfo.src_rect.y,
                        mOVInfo.src_rect.w,
                        mOVInfo.src_rect.h);
}

inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
    mOVInfo.src_rect.x = d.x;
    mOVInfo.src_rect.y = d.y;
    mOVInfo.src_rect.w = d.w;
    mOVInfo.src_rect.h = d.h;
}

inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
    return utils::Dim(  mOVInfo.dst_rect.x,
                        mOVInfo.dst_rect.y,
                        mOVInfo.dst_rect.w,
                        mOVInfo.dst_rect.h);
}

inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) {
    mOVInfo.dst_rect.x = d.x;
    mOVInfo.dst_rect.y = d.y;
    mOVInfo.dst_rect.w = d.w;
    mOVInfo.dst_rect.h = d.h;
}

inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }

inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }

inline void MdpCtrl::setRotationFlags() {
    const int u = getUserData();
    if (u == MDP_ROT_90 || u == MDP_ROT_270)
        mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
    else
        mOVInfo.flags &= ~MDP_SOURCE_ROTATED_90;
}

inline void MdpCtrl::swapSrcWH() {
    utils::swap(mOVInfo.src.width,
            mOVInfo.src.height);
}

inline void MdpCtrl::swapSrcRectWH() {
    utils::swap(mOVInfo.src_rect.w,
            mOVInfo.src_rect.h);
}

inline void MdpCtrl::overlayTransFlipH()
{
    utils::Dim d   = getSrcRectDim();
    utils::Whf whf = getSrcWhf();
    d.x = compute(whf.w, d.x, d.w);
    setSrcRectDim(d);
}

inline void MdpCtrl::overlayTransFlipV()
{
    utils::Dim d   = getSrcRectDim();
    utils::Whf whf = getSrcWhf();
    d.y = compute(whf.h, d.y, d.h);
    setSrcRectDim(d);
}

inline void MdpCtrl::overlayTransRot90()
{
    utils::Dim d   = getSrcRectDim();
    utils::Whf whf = getSrcWhf();
    int tmp = d.x;
    d.x = compute(whf.h,
            d.y,
            d.h);
    d.y = tmp;
    setSrcRectDim(d);
    swapSrcWH();
    swapSrcRectWH();
}


///////    MdpCtrl3D //////

inline MdpCtrl3D::MdpCtrl3D() { reset(); }
inline bool MdpCtrl3D::close() {
    if (m3DOVInfo.is_3d) {
        m3DOVInfo.is_3d = 0;
        if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
            ALOGE("MdpCtrl3D close failed set3D with 0");
            return false;
        }
    }
    reset();
    return true;
}
inline void MdpCtrl3D::reset() {
    utils::memset0(m3DOVInfo);
}

inline void MdpCtrl3D::setFd(int fd) {
    mFd.copy(fd);
    OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid");
}

inline void MdpCtrl3D::setWh(const utils::Whf& whf) {
    // ignore fmt. Needed for useVirtualFB callflow
    m3DOVInfo.width = whf.w;
    m3DOVInfo.height = whf.h;
}

inline bool MdpCtrl3D::useVirtualFB() {
    if(!m3DOVInfo.is_3d) {
        m3DOVInfo.is_3d = 1;
        if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
            ALOGE("MdpCtrl3D close failed set3D with 0");
            return false;
        }
    }
    return true;
}

///////    MdpData   //////

inline MdpData::MdpData() { reset(); }

inline MdpData::~MdpData() { close(); }

inline bool MdpData::init(uint32_t fbnum) {
    // FD init
    if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
        ALOGE("Ctrl failed to init fbnum=%d", fbnum);
        return false;
    }
    return true;
}

inline void MdpData::reset() {
    overlay::utils::memset0(mOvData);
    mOvData.data.memory_id = -1;
}

inline bool MdpData::close() {
    reset();
    return mFd.close();
}

inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }

inline void MdpData::setPipeId(int id) { mOvData.id = id; }

inline int MdpData::getPipeId() const { return mOvData.id; }

inline int MdpData::getFd() const { return mFd.getFD(); }

inline bool MdpData::play(int fd, uint32_t offset) {
    mOvData.data.memory_id = fd;
    mOvData.data.offset = offset;
    if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
        ALOGE("MdpData failed to play");
        dump();
        return false;
    }
    return true;
}

} // overlay

#endif // OVERLAY_MDP_H