129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
2d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * Copyright (C) 2008 The Android Open Source Project
3d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
4d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * Not a Contribution, Apache license notifications and license are retained
5d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * for attribution purposes only.
6d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed *
7d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
8d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * you may not use this file except in compliance with the License.
9d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * You may obtain a copy of the License at
10d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed *
11d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
12d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed *
13d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * Unless required by applicable law or agreed to in writing, software
14d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
15d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * See the License for the specific language governing permissions and
17d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed * limitations under the License.
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*/
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2069d8a69d105eb02bf882a6d3d7214faf18f21043Rom Lemarchand#include <sync/sync.h>
2129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "overlayRotator.h"
2229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "overlayUtils.h"
23e012f7ad3026349c5a6edafbd550cd83655b99d5Saurabh Shah#include "mdp_version.h"
244e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah#include "gr.h"
2529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmednamespace ovutils = overlay::utils;
2729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmednamespace overlay {
2929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
301e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah//============Rotator=========================
311e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
32d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer AhmedRotator::~Rotator() {}
33d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
34d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer AhmedRotator* Rotator::getRotator() {
35d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    int type = getRotatorHwType();
36d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    if(type == TYPE_MDP) {
37d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        return new MdpRot(); //will do reset
38d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    } else if(type == TYPE_MDSS) {
39d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        return new MdssRot();
40d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    } else {
41d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        ALOGE("%s Unknown h/w type %d", __FUNCTION__, type);
42d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        return NULL;
43d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    }
44d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}
45d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
464e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shahuint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) {
474e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah    //dummy aligned w & h.
484e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah    int alW = 0, alH = 0;
494e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah    int halFormat = ovutils::getHALFormat(destWhf.format);
504e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah    //A call into gralloc/memalloc
514e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah    return getBufferSizeAndDimensions(
524e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah            destWhf.w, destWhf.h, halFormat, alW, alH);
534e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah}
544e2cfc92692f8b9c03cb35702fa5ffeda0d29571Saurabh Shah
55d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedint Rotator::getRotatorHwType() {
56e012f7ad3026349c5a6edafbd550cd83655b99d5Saurabh Shah    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
57e012f7ad3026349c5a6edafbd550cd83655b99d5Saurabh Shah    if (mdpVersion == qdutils::MDSS_V5)
58e012f7ad3026349c5a6edafbd550cd83655b99d5Saurabh Shah        return TYPE_MDSS;
59f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed    return TYPE_MDP;
60f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed}
6129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
621e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
631e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah//============RotMem=========================
641e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
65f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmedbool RotMem::close() {
66f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed    bool ret = true;
67f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed    for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
68f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed        // skip current, and if valid, close
69f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed        if(m[i].valid()) {
70f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed            if(m[i].close() == false) {
71f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed                ALOGE("%s error in closing rot mem %d", __FUNCTION__, i);
72f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed                ret = false;
73f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed            }
74f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed        }
75f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed    }
76f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed    return ret;
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
7829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
791e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh ShahRotMem::Mem::Mem() : mCurrOffset(0) {
801e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    utils::memset0(mRotOffset);
811e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    for(int i = 0; i < ROT_NUM_BUFS; i++) {
821e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        mRelFence[i] = -1;
831e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    }
841e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah}
851e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
861e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh ShahRotMem::Mem::~Mem() {
871e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    for(int i = 0; i < ROT_NUM_BUFS; i++) {
881e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        ::close(mRelFence[i]);
891e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        mRelFence[i] = -1;
901e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    }
911e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah}
921e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
931e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shahvoid RotMem::Mem::setReleaseFd(const int& fence) {
941e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    int ret = 0;
951e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
961e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    if(mRelFence[mCurrOffset] >= 0) {
971e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        //Wait for previous usage of this buffer to be over.
981e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        //Can happen if rotation takes > vsync and a fast producer. i.e queue
991e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        //happens in subsequent vsyncs either because content is 60fps or
1001e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        //because the producer is hasty sometimes.
1011e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        ret = sync_wait(mRelFence[mCurrOffset], 1000);
1021e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        if(ret < 0) {
1031e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah            ALOGE("%s: sync_wait error!! error no = %d err str = %s",
1041e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah                __FUNCTION__, errno, strerror(errno));
1051e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        }
1061e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        ::close(mRelFence[mCurrOffset]);
1071e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    }
1081e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    mRelFence[mCurrOffset] = fence;
1091e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah}
1101e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
1111e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah//============RotMgr=========================
1121e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
11336963690317abceae79621f14ba41ff62b3ff489Saurabh ShahRotMgr::RotMgr() {
11436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    for(int i = 0; i < MAX_ROT_SESS; i++) {
11536963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        mRot[i] = 0;
11636963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    }
11736963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    mUseCount = 0;
1181e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    mRotDevFd = -1;
11936963690317abceae79621f14ba41ff62b3ff489Saurabh Shah}
12036963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
12136963690317abceae79621f14ba41ff62b3ff489Saurabh ShahRotMgr::~RotMgr() {
12236963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    clear();
12336963690317abceae79621f14ba41ff62b3ff489Saurabh Shah}
12436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
12536963690317abceae79621f14ba41ff62b3ff489Saurabh Shahvoid RotMgr::configBegin() {
12636963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    //Reset the number of objects used
12736963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    mUseCount = 0;
12836963690317abceae79621f14ba41ff62b3ff489Saurabh Shah}
12936963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
13036963690317abceae79621f14ba41ff62b3ff489Saurabh Shahvoid RotMgr::configDone() {
13136963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    //Remove the top most unused objects. Videos come and go.
13236963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    for(int i = mUseCount; i < MAX_ROT_SESS; i++) {
13336963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        if(mRot[i]) {
13436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah            delete mRot[i];
13536963690317abceae79621f14ba41ff62b3ff489Saurabh Shah            mRot[i] = 0;
13636963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        }
13736963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    }
13836963690317abceae79621f14ba41ff62b3ff489Saurabh Shah}
13936963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
14036963690317abceae79621f14ba41ff62b3ff489Saurabh ShahRotator* RotMgr::getNext() {
14136963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    //Return a rot object, creating one if necessary
14236963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    overlay::Rotator *rot = NULL;
14336963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    if(mUseCount >= MAX_ROT_SESS) {
14436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        ALOGE("%s, MAX rotator sessions reached", __func__);
14536963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    } else {
14636963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        if(mRot[mUseCount] == NULL)
14736963690317abceae79621f14ba41ff62b3ff489Saurabh Shah            mRot[mUseCount] = overlay::Rotator::getRotator();
14836963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        rot = mRot[mUseCount++];
14936963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    }
15036963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    return rot;
15136963690317abceae79621f14ba41ff62b3ff489Saurabh Shah}
15236963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
15336963690317abceae79621f14ba41ff62b3ff489Saurabh Shahvoid RotMgr::clear() {
15436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    //Brute force obj destruction, helpful in suspend.
15536963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    for(int i = 0; i < MAX_ROT_SESS; i++) {
15636963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        if(mRot[i]) {
15736963690317abceae79621f14ba41ff62b3ff489Saurabh Shah            delete mRot[i];
15836963690317abceae79621f14ba41ff62b3ff489Saurabh Shah            mRot[i] = 0;
15936963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        }
16036963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    }
16136963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    mUseCount = 0;
1621e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    ::close(mRotDevFd);
1631e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    mRotDevFd = -1;
16436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah}
16536963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
16636963690317abceae79621f14ba41ff62b3ff489Saurabh Shahvoid RotMgr::getDump(char *buf, size_t len) {
16736963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    for(int i = 0; i < MAX_ROT_SESS; i++) {
16836963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        if(mRot[i]) {
16936963690317abceae79621f14ba41ff62b3ff489Saurabh Shah            mRot[i]->getDump(buf, len);
17036963690317abceae79621f14ba41ff62b3ff489Saurabh Shah        }
17136963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    }
17236963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    char str[32] = {'\0'};
17336963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    snprintf(str, 32, "\n================\n");
17436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    strncat(buf, str, strlen(str));
17536963690317abceae79621f14ba41ff62b3ff489Saurabh Shah}
17636963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
1771e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shahint RotMgr::getRotDevFd() {
1781e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    //2nd check just in case
1791e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    if(mRotDevFd < 0 && Rotator::getRotatorHwType() == Rotator::TYPE_MDP) {
1801e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        mRotDevFd = ::open("/dev/msm_rotator", O_RDWR, 0);
1811e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        if(mRotDevFd < 0) {
1821e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah            ALOGE("%s failed to open rotator device", __FUNCTION__);
1831e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        }
1841e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    }
1851e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah    return mRotDevFd;
1861e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah}
1871e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah
18829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
189