| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * Copyright (c) 2010-2013, The Linux Foundation. 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" |
| #include "qdMetaData.h" |
| #ifdef USES_POST_PROCESSING |
| #include "lib-postproc.h" |
| #endif |
| |
| 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(); |
| /* 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(); |
| /* Sets the source total width, height, format */ |
| void setSource(const utils::PipeArgs& pargs); |
| /* |
| * Sets ROI, the unpadded region, for source buffer. |
| * Dim - ROI dimensions. |
| */ |
| void setCrop(const utils::Dim& d); |
| void setTransform(const utils::eTransform& orient); |
| /* given a dim and w/h, set overlay dim */ |
| void setPosition(const utils::Dim& dim); |
| /* using user_data, sets/unsets roationvalue in mdp flags */ |
| void setRotationFlags(); |
| /* Performs downscale calculations */ |
| void setDownscale(int dscale_factor); |
| /* Update the src format with rotator's dest*/ |
| void updateSrcFormat(const uint32_t& rotDstFormat); |
| /* dump state of the object */ |
| void dump() const; |
| /* Return the dump in the specified buffer */ |
| void getDump(char *buf, size_t len); |
| |
| /* returns session id */ |
| int getPipeId() const; |
| /* returns the fd associated to ctrl*/ |
| int getFd() const; |
| /* returns a copy ro dst rect dim */ |
| utils::Dim getDstRectDim() const; |
| /* returns a copy to src rect dim */ |
| utils::Dim getSrcRectDim() const; |
| /* setVisualParam */ |
| bool setVisualParams(const MetaData_t& data); |
| void forceSet(); |
| |
| private: |
| /* Perform transformation calculations */ |
| void doTransform(); |
| void doDownscale(); |
| /* get orient / user_data[0] */ |
| int getOrient() const; |
| /* 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); |
| /* return a copy of src whf*/ |
| utils::Whf getSrcWhf() const; |
| /* set src whf */ |
| void setSrcWhf(const utils::Whf& whf); |
| /* set src/dst rect dim */ |
| void setSrcRectDim(const utils::Dim d); |
| void setDstRectDim(const utils::Dim d); |
| /* 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(); |
| |
| utils::eTransform mOrientation; //Holds requested orientation |
| /* last good known ov info */ |
| mdp_overlay mLkgo; |
| /* Actual overlay mdp structure */ |
| mdp_overlay mOVInfo; |
| /* FD for the mdp fbnum */ |
| OvFD mFd; |
| int mDownscale; |
| bool mForceSet; |
| |
| #ifdef USES_POST_PROCESSING |
| /* PP Compute Params */ |
| struct compute_params mParams; |
| /* indicate if PP params have been changed */ |
| bool mPPChanged; |
| #endif |
| }; |
| |
| |
| /* 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; |
| /* Return the dump in the specified buffer */ |
| void getDump(char *buf, size_t len); |
| |
| private: |
| |
| /* actual overlay mdp data */ |
| msmfb_overlay_data mOvData; |
| /* fd to mdp fbnum */ |
| OvFD mFd; |
| }; |
| |
| //--------------Inlines--------------------------------- |
| |
| ///// 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 void MdpCtrl::setDownscale(int dscale) { |
| mDownscale = dscale; |
| } |
| |
| inline bool MdpCtrl::ovChanged() const { |
| #ifdef USES_POST_PROCESSING |
| // Some pp params are stored as pointer address, |
| // so can't compare their content directly. |
| if (mPPChanged) { |
| return true; |
| } |
| #endif |
| // 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) |
| mOVInfo.flags |= MDP_SOURCE_ROTATED_90; |
| } |
| |
| inline void MdpCtrl::forceSet() { |
| mForceSet = true; |
| } |
| |
| /////// 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 |