129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
244d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*
429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* Redistribution and use in source and binary forms, with or without
529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* modification, are permitted provided that the following conditions are
629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* met:
729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*    * Redistributions of source code must retain the above copyright
829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*      notice, this list of conditions and the following disclaimer.
929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*    * Redistributions in binary form must reproduce the above
1029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*      copyright notice, this list of conditions and the following
1129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*      disclaimer in the documentation and/or other materials provided
1229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*      with the distribution.
13d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed*    * Neither the name of The Linux Foundation nor the names of its
1429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*      contributors may be used to endorse or promote products derived
1529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*      from this software without specific prior written permission.
1629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*
1729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
2029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
2129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed*/
2929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "overlay.h"
31d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#include "pipes/overlayGenPipe.h"
32d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#include "mdp_version.h"
33e2b94da0a7de2a5cad9ecb90ed3eee5dca219863Saurabh Shah#include "qdMetaData.h"
3429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
35d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#define PIPE_DEBUG 0
3629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmednamespace overlay {
38d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedusing namespace utils;
3929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
40d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer AhmedOverlay::Overlay() {
4144d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    PipeBook::NUM_PIPES = qdutils::MDPVersion::getInstance().getTotalPipes();
42d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
43d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        mPipeBook[i].init();
4429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
4529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mDumpStr[0] = '\0';
471ddf366c267e01dbb7ac736d9c40272d5541b724Naseer Ahmed}
481ddf366c267e01dbb7ac736d9c40272d5541b724Naseer Ahmed
491ddf366c267e01dbb7ac736d9c40272d5541b724Naseer AhmedOverlay::~Overlay() {
50d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
51d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        mPipeBook[i].destroy();
5229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
5329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
55d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::configBegin() {
56d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
57d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        //Mark as available for this round.
58d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        PipeBook::resetUse(i);
59d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        PipeBook::resetAllocation(i);
60d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    }
614f4c03bfb459159490795165a191e01c564e5788Saurabh Shah    sForceSetBitmap = 0;
62d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mDumpStr[0] = '\0';
63d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}
64d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
65d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::configDone() {
66d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
67d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        if(PipeBook::isNotUsed(i)) {
68d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            //Forces UNSET on pipes, flushes rotator memory and session, closes
69d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            //fds
70d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            if(mPipeBook[i].valid()) {
71d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                char str[32];
72a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah                sprintf(str, "Unset=%s dpy=%d mix=%d; ",
73a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah                        PipeBook::getDestStr((eDest)i),
74a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah                        mPipeBook[i].mDisplay, mPipeBook[i].mMixer);
751eda3814b8feedadcc2801b2af4d1076caae55adSaurabh Shah#if PIPE_DEBUG
76d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                strncat(mDumpStr, str, strlen(str));
771eda3814b8feedadcc2801b2af4d1076caae55adSaurabh Shah#endif
78d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            }
79d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            mPipeBook[i].destroy();
801ddf366c267e01dbb7ac736d9c40272d5541b724Naseer Ahmed        }
8129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
82d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    dump();
83d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    PipeBook::save();
84d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}
85d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
86a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh ShaheDest Overlay::nextPipe(eMdpPipeType type, int dpy, int mixer) {
87d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    eDest dest = OV_INVALID;
88d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
89d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
90a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah        if( (type == OV_MDP_PIPE_ANY || //Pipe type match
91a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah             type == PipeBook::getPipeType((eDest)i)) &&
92a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            (mPipeBook[i].mDisplay == DPY_UNUSED || //Free or same display
93a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah             mPipeBook[i].mDisplay == dpy) &&
94a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            (mPipeBook[i].mMixer == MIXER_UNUSED || //Free or same mixer
95a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah             mPipeBook[i].mMixer == mixer) &&
96a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            PipeBook::isNotAllocated(i) && //Free pipe
97a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            !(sDMAMode == DMA_BLOCK_MODE && //DMA pipe in Line mode
98a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah               PipeBook::getPipeType((eDest)i) == OV_MDP_PIPE_DMA)) {
99a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            dest = (eDest)i;
100a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            PipeBook::setAllocation(i);
101a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            break;
1021ddf366c267e01dbb7ac736d9c40272d5541b724Naseer Ahmed        }
10329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
104d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
105d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    if(dest != OV_INVALID) {
106d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        int index = (int)dest;
107d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        mPipeBook[index].mDisplay = dpy;
108a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah        mPipeBook[index].mMixer = mixer;
109d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        if(not mPipeBook[index].valid()) {
110d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            mPipeBook[index].mPipe = new GenericPipe(dpy);
111d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            char str[32];
112a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah            snprintf(str, 32, "Set=%s dpy=%d mix=%d; ",
113a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah                     PipeBook::getDestStr(dest), dpy, mixer);
1141eda3814b8feedadcc2801b2af4d1076caae55adSaurabh Shah#if PIPE_DEBUG
115d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            strncat(mDumpStr, str, strlen(str));
1161eda3814b8feedadcc2801b2af4d1076caae55adSaurabh Shah#endif
1171ddf366c267e01dbb7ac736d9c40272d5541b724Naseer Ahmed        }
118d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    } else {
119a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah        ALOGD_IF(PIPE_DEBUG, "Pipe unavailable type=%d display=%d mixer=%d",
120a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah                (int)type, dpy, mixer);
12129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
122d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
123d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    return dest;
12429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
125f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
1265a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shahbool Overlay::isPipeTypeAttached(eMdpPipeType type) {
1275a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
1285a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah        if(type == PipeBook::getPipeType((eDest)i) &&
1295ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah                mPipeBook[i].mDisplay != DPY_UNUSED) {
1305a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah            return true;
1315a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah        }
1325a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah    }
1335a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah    return false;
1345a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah}
1355a4b615e1d04b0b9f3572530b330dda4f10853d0Saurabh Shah
136d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedbool Overlay::commit(utils::eDest dest) {
137d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    bool ret = false;
138d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    int index = (int)dest;
139d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    validate(index);
140f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
141d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    if(mPipeBook[index].mPipe->commit()) {
142d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        ret = true;
143d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        PipeBook::setUse((int)dest);
1444f4c03bfb459159490795165a191e01c564e5788Saurabh Shah        if(sForceSetBitmap & (1 << mPipeBook[index].mDisplay)) {
1454f4c03bfb459159490795165a191e01c564e5788Saurabh Shah            mPipeBook[index].mPipe->forceSet();
1464f4c03bfb459159490795165a191e01c564e5788Saurabh Shah        }
147d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    } else {
148dbe48d71be758dd07d7f64417aef57f30c478a54Sushil Chauhan        int dpy = mPipeBook[index].mDisplay;
149dbe48d71be758dd07d7f64417aef57f30c478a54Sushil Chauhan        for(int i = 0; i < PipeBook::NUM_PIPES; i++)
150817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah            if (mPipeBook[i].mDisplay == dpy) {
151dbe48d71be758dd07d7f64417aef57f30c478a54Sushil Chauhan                PipeBook::resetAllocation(i);
152817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah                PipeBook::resetUse(i);
153817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah                if(mPipeBook[i].valid()) {
154817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah                    mPipeBook[i].mPipe->forceSet();
155817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah                }
156817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah            }
15729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
158d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    return ret;
15929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
160f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
161d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedbool Overlay::queueBuffer(int fd, uint32_t offset,
162d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        utils::eDest dest) {
163d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    int index = (int)dest;
164d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    bool ret = false;
165d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    validate(index);
166d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    //Queue only if commit() has succeeded (and the bit set)
167d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    if(PipeBook::isUsed((int)dest)) {
168d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        ret = mPipeBook[index].mPipe->queueBuffer(fd, offset);
16929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
170d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    return ret;
17129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
17229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
173d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::setCrop(const utils::Dim& d,
174d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        utils::eDest dest) {
175d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    int index = (int)dest;
176d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    validate(index);
177d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mPipeBook[index].mPipe->setCrop(d);
17829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
17929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
180d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::setPosition(const utils::Dim& d,
181d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        utils::eDest dest) {
182d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    int index = (int)dest;
183d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    validate(index);
184d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mPipeBook[index].mPipe->setPosition(d);
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
18629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
187d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::setTransform(const int orient,
188d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        utils::eDest dest) {
189d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    int index = (int)dest;
190d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    validate(index);
191d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
192d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    utils::eTransform transform =
193d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            static_cast<utils::eTransform>(orient);
194d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mPipeBook[index].mPipe->setTransform(transform);
195d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
19629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
19729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
198d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::setSource(const utils::PipeArgs args,
199d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        utils::eDest dest) {
200d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    int index = (int)dest;
201d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    validate(index);
20229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
203d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    PipeArgs newArgs(args);
20444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    if(PipeBook::getPipeType(dest) == OV_MDP_PIPE_VG) {
205d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE);
206d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    } else {
207d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE);
208c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
2096371fcefbcaf155e7402b3a7343d800470631d04Jeykumar Sankaran
21044d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    if(PipeBook::getPipeType(dest) == OV_MDP_PIPE_DMA) {
2116371fcefbcaf155e7402b3a7343d800470631d04Jeykumar Sankaran        setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_FORCE_DMA);
2126371fcefbcaf155e7402b3a7343d800470631d04Jeykumar Sankaran    } else {
2136371fcefbcaf155e7402b3a7343d800470631d04Jeykumar Sankaran        clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_FORCE_DMA);
2146371fcefbcaf155e7402b3a7343d800470631d04Jeykumar Sankaran    }
2156371fcefbcaf155e7402b3a7343d800470631d04Jeykumar Sankaran
216d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mPipeBook[index].mPipe->setSource(newArgs);
217d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}
218d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
219e2b94da0a7de2a5cad9ecb90ed3eee5dca219863Saurabh Shahvoid Overlay::setVisualParams(const MetaData_t& metadata, utils::eDest dest) {
220e2b94da0a7de2a5cad9ecb90ed3eee5dca219863Saurabh Shah    int index = (int)dest;
221e2b94da0a7de2a5cad9ecb90ed3eee5dca219863Saurabh Shah    validate(index);
222e2b94da0a7de2a5cad9ecb90ed3eee5dca219863Saurabh Shah    mPipeBook[index].mPipe->setVisualParams(metadata);
223e2b94da0a7de2a5cad9ecb90ed3eee5dca219863Saurabh Shah}
224e2b94da0a7de2a5cad9ecb90ed3eee5dca219863Saurabh Shah
225d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer AhmedOverlay* Overlay::getInstance() {
226d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    if(sInstance == NULL) {
227d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        sInstance = new Overlay();
228d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    }
229d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    return sInstance;
230c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah}
231c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
23244d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah// Clears any VG pipes allocated to the fb devices
23344d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah// Generates a LUT for pipe types.
23444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shahint Overlay::initOverlay() {
23544d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
23644d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    int numPipesXType[OV_MDP_PIPE_ANY] = {0};
23744d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    numPipesXType[OV_MDP_PIPE_RGB] =
23844d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            qdutils::MDPVersion::getInstance().getRGBPipes();
23944d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    numPipesXType[OV_MDP_PIPE_VG] =
24044d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            qdutils::MDPVersion::getInstance().getVGPipes();
24144d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    numPipesXType[OV_MDP_PIPE_DMA] =
24244d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            qdutils::MDPVersion::getInstance().getDMAPipes();
24344d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah
24444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    int index = 0;
24544d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    for(int X = 0; X < (int)OV_MDP_PIPE_ANY; X++) { //iterate over types
24644d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah        for(int j = 0; j < numPipesXType[X]; j++) { //iterate over num
24744d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            PipeBook::pipeTypeLUT[index] = (utils::eMdpPipeType)X;
24844d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            index++;
24944d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah        }
25044d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    }
25144d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah
252804e5a7dd92125415251701d866b792cb0c22913Xiaoming Zhou    if (mdpVersion < qdutils::MDSS_V5 && mdpVersion != qdutils::MDP_V3_0_4) {
25344d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah        msmfb_mixer_info_req  req;
25444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah        mdp_mixer_info *minfo = NULL;
25544d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah        char name[64];
25644d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah        int fd = -1;
2575ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah        for(int i = 0; i < MAX_FB_DEVICES; i++) {
25844d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
25944d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            ALOGD("initoverlay:: opening the device:: %s", name);
26044d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            fd = ::open(name, O_RDWR, 0);
26144d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            if(fd < 0) {
26244d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                ALOGE("cannot open framebuffer(%d)", i);
26344d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                return -1;
26444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            }
26544d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            //Get the mixer configuration */
26644d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            req.mixer_num = i;
26744d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
26844d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
26944d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                close(fd);
27044d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                return -1;
27144d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            }
27244d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            minfo = req.info;
27344d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            for (int j = 0; j < req.cnt; j++) {
27444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
27544d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                      minfo->z_order);
27630851159787a142ff3144bc34013eaed2d6f9e9bNaseer Ahmed                // clear any pipe connected to mixer including base pipe.
27730851159787a142ff3144bc34013eaed2d6f9e9bNaseer Ahmed                int index = minfo->pndx;
27830851159787a142ff3144bc34013eaed2d6f9e9bNaseer Ahmed                ALOGD("Unset overlay with index: %d at mixer %d", index, i);
27930851159787a142ff3144bc34013eaed2d6f9e9bNaseer Ahmed                if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
28030851159787a142ff3144bc34013eaed2d6f9e9bNaseer Ahmed                    ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
28130851159787a142ff3144bc34013eaed2d6f9e9bNaseer Ahmed                    close(fd);
28230851159787a142ff3144bc34013eaed2d6f9e9bNaseer Ahmed                    return -1;
28344d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                }
28444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah                minfo++;
28544d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            }
28644d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            close(fd);
28744d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah            fd = -1;
28844d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah        }
289d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    }
2905ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
2915ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    FILE *displayDeviceFP = NULL;
2925ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    const int MAX_FRAME_BUFFER_NAME_SIZE = 128;
2935ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
2945ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
2955ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    const char *strDtvPanel = "dtv panel";
2965ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    const char *strWbPanel = "writeback panel";
2975ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
2985ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    for(int num = 1; num < MAX_FB_DEVICES; num++) {
2995ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah        snprintf (msmFbTypePath, sizeof(msmFbTypePath),
3005ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah                "/sys/class/graphics/fb%d/msm_fb_type", num);
3015ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah        displayDeviceFP = fopen(msmFbTypePath, "r");
3025ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
3035ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah        if(displayDeviceFP){
3045ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah            fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
3055ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah                    displayDeviceFP);
3065ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
3075ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah            if(strncmp(fbType, strDtvPanel, strlen(strDtvPanel)) == 0) {
3085ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah                sDpyFbMap[DPY_EXTERNAL] = num;
3095ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah            } else if(strncmp(fbType, strWbPanel, strlen(strWbPanel)) == 0) {
3105ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah                sDpyFbMap[DPY_WRITEBACK] = num;
3115ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah            }
3125ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
3135ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah            fclose(displayDeviceFP);
3145ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah        }
3155ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    }
3165ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
31744d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    return 0;
318d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}
319d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
3205ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shahbool Overlay::displayCommit(const int& fd) {
3215ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    //Commit
3225ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    struct mdp_display_commit info;
3235ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    memset(&info, 0, sizeof(struct mdp_display_commit));
3245ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
3255ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    if(!mdp_wrapper::displayCommit(fd, info)) {
3265ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah       ALOGE("%s: commit failed", __func__);
3275ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah       return false;
3285ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    }
3295ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    return true;
3305ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah}
3315ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
332d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::dump() const {
3331eda3814b8feedadcc2801b2af4d1076caae55adSaurabh Shah#if PIPE_DEBUG
334d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    if(strlen(mDumpStr)) { //dump only on state change
3351eda3814b8feedadcc2801b2af4d1076caae55adSaurabh Shah        ALOGD("%s\n", mDumpStr);
336d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    }
3371eda3814b8feedadcc2801b2af4d1076caae55adSaurabh Shah#endif
338d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}
339d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
340f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shahvoid Overlay::getDump(char *buf, size_t len) {
341f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    int totalPipes = 0;
34289cadba6f59425c741d9f376a1f407fcb3bae675Saurabh Shah    const char *str = "\nOverlay State\n\n";
343f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    strncat(buf, str, strlen(str));
344f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
345f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah        if(mPipeBook[i].valid()) {
346f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah            mPipeBook[i].mPipe->getDump(buf, len);
347f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah            char str[64] = {'\0'};
34889cadba6f59425c741d9f376a1f407fcb3bae675Saurabh Shah            snprintf(str, 64, "Display=%d\n\n", mPipeBook[i].mDisplay);
349f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah            strncat(buf, str, strlen(str));
350f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah            totalPipes++;
351f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah        }
352f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    }
353f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    char str_pipes[64] = {'\0'};
35489cadba6f59425c741d9f376a1f407fcb3bae675Saurabh Shah    snprintf(str_pipes, 64, "Pipes=%d\n\n", totalPipes);
355f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    strncat(buf, str_pipes, strlen(str_pipes));
356f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah}
357f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah
358cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhanvoid Overlay::clear(int dpy) {
359cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
360cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan        if (mPipeBook[i].mDisplay == dpy) {
361cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan            // Mark as available for this round
362cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan            PipeBook::resetUse(i);
363cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan            PipeBook::resetAllocation(i);
364817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah            if(mPipeBook[i].valid()) {
365817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah                mPipeBook[i].mPipe->forceSet();
366817dac3acfc9887b58a3aff61805f4c31f8c7939Saurabh Shah            }
367cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan        }
368cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan    }
369cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan}
370cf2536998ecd888681570bd713836115f8979cd0Sushil Chauhan
371d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::PipeBook::init() {
372d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mPipe = NULL;
373d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mDisplay = DPY_UNUSED;
374a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah    mMixer = MIXER_UNUSED;
375d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}
376d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
377d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedvoid Overlay::PipeBook::destroy() {
378d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    if(mPipe) {
379d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        delete mPipe;
380d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed        mPipe = NULL;
381cb3da0a5e4313f55bd27514006c3ce64293ff8a2Ajay Dudani    }
382d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    mDisplay = DPY_UNUSED;
383a8c3d11acf21811ee74589d08dbcc037cd763526Saurabh Shah    mMixer = MIXER_UNUSED;
38429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
38529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
386d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer AhmedOverlay* Overlay::sInstance = 0;
3875ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shahint Overlay::sDpyFbMap[DPY_MAX] = {0, -1, -1};
3885fe3925fe5a04f1fe519f64e973a1e5da4932d03Saurabh Shahint Overlay::sDMAMode = DMA_LINE_MODE;
3894f4c03bfb459159490795165a191e01c564e5788Saurabh Shahint Overlay::sForceSetBitmap = 0;
390d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedint Overlay::PipeBook::NUM_PIPES = 0;
391d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedint Overlay::PipeBook::sPipeUsageBitmap = 0;
392d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedint Overlay::PipeBook::sLastUsageBitmap = 0;
393d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmedint Overlay::PipeBook::sAllocatedBitmap = 0;
39444d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shahutils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] =
39544d5282b252fa1db88472542c0b9d794fd915d54Saurabh Shah    {utils::OV_MDP_PIPE_ANY};
396d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
397d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed}; // namespace overlay
398