Home | History | Annotate | Download | only in liboverlay
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
      4  * Not a Contribution, Apache license notifications and license are retained
      5  * for attribution purposes only.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18 */
     19 
     20 #include "overlayRotator.h"
     21 #include "overlayUtils.h"
     22 #include "mdp_version.h"
     23 #include "gr.h"
     24 
     25 namespace ovutils = overlay::utils;
     26 
     27 namespace overlay {
     28 
     29 //============Rotator=========================
     30 
     31 Rotator::~Rotator() {}
     32 
     33 Rotator* Rotator::getRotator() {
     34     int type = getRotatorHwType();
     35     if(type == TYPE_MDP) {
     36         return new MdpRot(); //will do reset
     37     } else if(type == TYPE_MDSS) {
     38         return new MdssRot();
     39     } else {
     40         ALOGE("%s Unknown h/w type %d", __FUNCTION__, type);
     41         return NULL;
     42     }
     43 }
     44 
     45 uint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) {
     46     //dummy aligned w & h.
     47     int alW = 0, alH = 0;
     48     int halFormat = ovutils::getHALFormat(destWhf.format);
     49     //A call into gralloc/memalloc
     50     return getBufferSizeAndDimensions(
     51             destWhf.w, destWhf.h, halFormat, alW, alH);
     52 }
     53 
     54 int Rotator::getRotatorHwType() {
     55     int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
     56     if (mdpVersion == qdutils::MDSS_V5)
     57         return TYPE_MDSS;
     58     return TYPE_MDP;
     59 }
     60 
     61 
     62 //============RotMem=========================
     63 
     64 bool RotMem::close() {
     65     bool ret = true;
     66     if(valid()) {
     67         if(mem.close() == false) {
     68             ALOGE("%s error in closing rot mem", __FUNCTION__);
     69             ret = false;
     70         }
     71     }
     72     return ret;
     73 }
     74 
     75 RotMem::RotMem() : mCurrIndex(0) {
     76     utils::memset0(mRotOffset);
     77     for(int i = 0; i < ROT_NUM_BUFS; i++) {
     78         mRelFence[i] = -1;
     79     }
     80 }
     81 
     82 RotMem::~RotMem() {
     83     for(int i = 0; i < ROT_NUM_BUFS; i++) {
     84         ::close(mRelFence[i]);
     85         mRelFence[i] = -1;
     86     }
     87 }
     88 
     89 void RotMem::setReleaseFd(const int& fence) {
     90     int ret = 0;
     91 
     92     if(mRelFence[mCurrIndex] >= 0) {
     93         //Wait for previous usage of this buffer to be over.
     94         //Can happen if rotation takes > vsync and a fast producer. i.e queue
     95         //happens in subsequent vsyncs either because content is 60fps or
     96         //because the producer is hasty sometimes.
     97         ret = sync_wait(mRelFence[mCurrIndex], 1000);
     98         if(ret < 0) {
     99             ALOGE("%s: sync_wait error!! error no = %d err str = %s",
    100                 __FUNCTION__, errno, strerror(errno));
    101         }
    102         ::close(mRelFence[mCurrIndex]);
    103     }
    104     mRelFence[mCurrIndex] = fence;
    105 }
    106 
    107 //============RotMgr=========================
    108 RotMgr * RotMgr::sRotMgr = NULL;
    109 
    110 RotMgr* RotMgr::getInstance() {
    111     if(sRotMgr == NULL) {
    112         sRotMgr = new RotMgr();
    113     }
    114     return sRotMgr;
    115 }
    116 
    117 RotMgr::RotMgr() {
    118     for(int i = 0; i < MAX_ROT_SESS; i++) {
    119         mRot[i] = 0;
    120     }
    121     mUseCount = 0;
    122     mRotDevFd = -1;
    123 }
    124 
    125 RotMgr::~RotMgr() {
    126     clear();
    127 }
    128 
    129 void RotMgr::configBegin() {
    130     //Reset the number of objects used
    131     mUseCount = 0;
    132 }
    133 
    134 void RotMgr::configDone() {
    135     //Remove the top most unused objects. Videos come and go.
    136     for(int i = mUseCount; i < MAX_ROT_SESS; i++) {
    137         if(mRot[i]) {
    138             delete mRot[i];
    139             mRot[i] = 0;
    140         }
    141     }
    142 }
    143 
    144 Rotator* RotMgr::getNext() {
    145     //Return a rot object, creating one if necessary
    146     overlay::Rotator *rot = NULL;
    147     if(mUseCount >= MAX_ROT_SESS) {
    148         ALOGW("%s, MAX rotator sessions reached, request rejected", __func__);
    149     } else {
    150         if(mRot[mUseCount] == NULL)
    151             mRot[mUseCount] = overlay::Rotator::getRotator();
    152         rot = mRot[mUseCount++];
    153     }
    154     return rot;
    155 }
    156 
    157 void RotMgr::clear() {
    158     //Brute force obj destruction, helpful in suspend.
    159     for(int i = 0; i < MAX_ROT_SESS; i++) {
    160         if(mRot[i]) {
    161             delete mRot[i];
    162             mRot[i] = 0;
    163         }
    164     }
    165     mUseCount = 0;
    166     ::close(mRotDevFd);
    167     mRotDevFd = -1;
    168 }
    169 
    170 void RotMgr::getDump(char *buf, size_t len) {
    171     for(int i = 0; i < MAX_ROT_SESS; i++) {
    172         if(mRot[i]) {
    173             mRot[i]->getDump(buf, len);
    174         }
    175     }
    176     char str[4] = {'\0'};
    177     snprintf(str, 4, "\n");
    178     strlcat(buf, str, len);
    179 }
    180 
    181 int RotMgr::getRotDevFd() {
    182     if(mRotDevFd < 0 && Rotator::getRotatorHwType() == Rotator::TYPE_MDSS) {
    183         mRotDevFd = ::open("/dev/graphics/fb0", O_RDWR, 0);
    184         if(mRotDevFd < 0) {
    185             ALOGE("%s failed to open fb0", __FUNCTION__);
    186         }
    187     }
    188     return mRotDevFd;
    189 }
    190 
    191 }
    192