1/* 2* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. 3* 4* Redistribution and use in source and binary forms, with or without 5* modification, are permitted provided that the following conditions are 6* met: 7* * Redistributions of source code must retain the above copyright 8* notice, this list of conditions and the following disclaimer. 9* * Redistributions in binary form must reproduce the above 10* copyright notice, this list of conditions and the following 11* disclaimer in the documentation and/or other materials provided 12* with the distribution. 13* * Neither the name of The Linux Foundation nor the names of its 14* contributors may be used to endorse or promote products derived 15* from this software without specific prior written permission. 16* 17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*/ 29 30#include <dlfcn.h> 31#include "overlay.h" 32#include "pipes/overlayGenPipe.h" 33#include "mdp_version.h" 34#include "qdMetaData.h" 35#include "qd_utils.h" 36 37namespace overlay { 38using namespace utils; 39using namespace qdutils; 40 41Overlay::Overlay() { 42 int numPipes = qdutils::MDPVersion::getInstance().getTotalPipes(); 43 PipeBook::NUM_PIPES = (numPipes <= utils::OV_MAX)? numPipes : utils::OV_MAX; 44 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 45 mPipeBook[i].init(); 46 } 47 48 initScalar(); 49 setDMAMultiplexingSupported(); 50#ifdef USES_POST_PROCESSING 51 initPostProc(); 52#endif 53} 54 55Overlay::~Overlay() { 56 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 57 mPipeBook[i].destroy(); 58 } 59 destroyScalar(); 60#ifdef USES_POST_PROCESSING 61 destroyPostProc(); 62#endif 63} 64 65void Overlay::configBegin() { 66 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 67 //Mark as available for this round. 68 PipeBook::resetUse(i); 69 PipeBook::resetAllocation(i); 70 } 71} 72 73void Overlay::configDone() { 74 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 75 if((PipeBook::isNotUsed(i) && !sessionInProgress((eDest)i)) || 76 isSessionEnded((eDest)i)) { 77 //Forces UNSET on pipes, flushes rotator memory and session, closes 78 //fds 79 mPipeBook[i].destroy(); 80 } 81 } 82 PipeBook::save(); 83} 84 85int Overlay::getPipeId(utils::eDest dest) { 86 return mPipeBook[(int)dest].mPipe->getPipeId(); 87} 88 89eDest Overlay::getDest(int pipeid) { 90 eDest dest = OV_INVALID; 91 // finding the dest corresponding to the given pipe 92 for(int i=0; i < PipeBook::NUM_PIPES; ++i) { 93 if(mPipeBook[i].valid() && mPipeBook[i].mPipe->getPipeId() == pipeid) { 94 return (eDest)i; 95 } 96 } 97 return dest; 98} 99 100eDest Overlay::reservePipe(int pipeid) { 101 eDest dest = getDest(pipeid); 102 PipeBook::setAllocation((int)dest); 103 return dest; 104} 105 106eDest Overlay::nextPipe(eMdpPipeType type, const PipeSpecs& pipeSpecs) { 107 eDest dest = OV_INVALID; 108 int dpy = pipeSpecs.dpy; 109 int mixer = pipeSpecs.mixer; 110 int formatType = pipeSpecs.formatClass; 111 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 112 if( (type == OV_MDP_PIPE_ANY || //Pipe type match 113 type == PipeBook::getPipeType((eDest)i)) && 114 (mPipeBook[i].mDisplay == DPY_UNUSED || //Free or same display 115 mPipeBook[i].mDisplay == dpy) && 116 (mPipeBook[i].mMixer == MIXER_UNUSED || //Free or same mixer 117 mPipeBook[i].mMixer == mixer) && 118 (mPipeBook[i].mFormatType == FORMAT_NONE || //Free or same format 119 mPipeBook[i].mFormatType == formatType) && 120 PipeBook::isNotAllocated(i) && //Free pipe 121 ( (sDMAMultiplexingSupported && dpy) || 122 !(sDMAMode == DMA_BLOCK_MODE && //DMA pipe in Line mode 123 PipeBook::getPipeType((eDest)i) == OV_MDP_PIPE_DMA)) ){ 124 //DMA-Multiplexing is only supported for WB on 8x26 125 dest = (eDest)i; 126 PipeBook::setAllocation(i); 127 break; 128 } 129 } 130 131 if(dest != OV_INVALID) { 132 int index = (int)dest; 133 mPipeBook[index].mDisplay = dpy; 134 mPipeBook[index].mMixer = mixer; 135 mPipeBook[index].mFormatType = formatType; 136 if(not mPipeBook[index].valid()) { 137 mPipeBook[index].mPipe = new GenericPipe(dpy); 138 mPipeBook[index].mSession = PipeBook::NONE; 139 } 140 } 141 142 return dest; 143} 144 145utils::eDest Overlay::getPipe(const PipeSpecs& pipeSpecs) { 146 if(MDPVersion::getInstance().is8x26()) { 147 return getPipe_8x26(pipeSpecs); 148 } else if(MDPVersion::getInstance().is8x16()) { 149 return getPipe_8x16(pipeSpecs); 150 } else if(MDPVersion::getInstance().is8x39()) { 151 return getPipe_8x39(pipeSpecs); 152 } else if(MDPVersion::getInstance().is8994()) { 153 return getPipe_8994(pipeSpecs); 154 } 155 156 eDest dest = OV_INVALID; 157 158 //The default behavior is to assume RGB and VG pipes have scalars 159 if(pipeSpecs.formatClass == FORMAT_YUV) { 160 return nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 161 } else if(pipeSpecs.fb == false) { //RGB App layers 162 if(not pipeSpecs.needsScaling) { 163 dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs); 164 } 165 if(dest == OV_INVALID) { 166 dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs); 167 } 168 if(dest == OV_INVALID) { 169 dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 170 } 171 } else { //FB layer 172 dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs); 173 if(dest == OV_INVALID) { 174 dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 175 } 176 //Some features can cause FB to have scaling as well. 177 //If we ever come to this block with FB needing scaling, 178 //the screen will be black for a frame, since the FB won't get a pipe 179 //but atleast this will prevent a hang 180 if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) { 181 dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs); 182 } 183 } 184 return dest; 185} 186 187utils::eDest Overlay::getPipe_8x26(const PipeSpecs& pipeSpecs) { 188 //Use this to hide all the 8x26 requirements that cannot be humanly 189 //described in a generic way 190 eDest dest = OV_INVALID; 191 if(pipeSpecs.formatClass == FORMAT_YUV) { //video 192 return nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 193 } else if(pipeSpecs.fb == false) { //RGB app layers 194 if((not pipeSpecs.needsScaling) and 195 (not (pipeSpecs.numActiveDisplays > 1 && 196 pipeSpecs.dpy == DPY_PRIMARY))) { 197 dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs); 198 } 199 if(dest == OV_INVALID) { 200 dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs); 201 } 202 if(dest == OV_INVALID) { 203 dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 204 } 205 } else { //FB layer 206 //For 8x26 Secondary we use DMA always for FB for inline rotation 207 if(pipeSpecs.dpy == DPY_PRIMARY) { 208 dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs); 209 if(dest == OV_INVALID) { 210 dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 211 } 212 } 213 if(dest == OV_INVALID and (not pipeSpecs.needsScaling) and 214 (not (pipeSpecs.numActiveDisplays > 1 && 215 pipeSpecs.dpy == DPY_PRIMARY))) { 216 dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs); 217 } 218 } 219 return dest; 220} 221 222utils::eDest Overlay::getPipe_8x16(const PipeSpecs& pipeSpecs) { 223 //Having such functions help keeping the interface generic but code specific 224 //and rife with assumptions 225 eDest dest = OV_INVALID; 226 if(pipeSpecs.formatClass == FORMAT_YUV or pipeSpecs.needsScaling) { 227 return nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 228 } else { 229 //Since this is a specific func, we can assume stuff like RGB pipe not 230 //having scalar blocks 231 dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs); 232 if(dest == OV_INVALID) { 233 dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs); 234 } 235 if(dest == OV_INVALID) { 236 dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 237 } 238 } 239 return dest; 240} 241 242utils::eDest Overlay::getPipe_8x39(const PipeSpecs& pipeSpecs) { 243 //8x16 & 8x36 has same number of pipes, pipe-types & scaling capabilities. 244 //Rely on 8x16 until we see a need to change. 245 return getPipe_8x16(pipeSpecs); 246} 247 248utils::eDest Overlay::getPipe_8994(const PipeSpecs& pipeSpecs) { 249 //If DMA pipes need to be used in block mode for downscale, there could be 250 //cases where consecutive rounds need separate modes, which cannot be 251 //supported since we at least need 1 round in between where the DMA is 252 //unused 253 eDest dest = OV_INVALID; 254 if(pipeSpecs.formatClass == FORMAT_YUV) { 255 return nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 256 } else { 257 dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs); 258 if(dest == OV_INVALID) { 259 dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs); 260 } 261 if(dest == OV_INVALID and not pipeSpecs.needsScaling) { 262 dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs); 263 } 264 } 265 return dest; 266} 267 268void Overlay::endAllSessions() { 269 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 270 if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START) 271 mPipeBook[i].mSession = PipeBook::END; 272 } 273} 274 275bool Overlay::isPipeTypeAttached(eMdpPipeType type) { 276 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 277 if(type == PipeBook::getPipeType((eDest)i) && 278 mPipeBook[i].mDisplay != DPY_UNUSED) { 279 return true; 280 } 281 } 282 return false; 283} 284 285bool Overlay::needsPrioritySwap(utils::eDest pipe1Index, 286 utils::eDest pipe2Index) { 287 validate((int)pipe1Index); 288 validate((int)pipe2Index); 289 290 uint8_t pipe1Prio = mPipeBook[(int)pipe1Index].mPipe->getPriority(); 291 uint8_t pipe2Prio = mPipeBook[(int)pipe2Index].mPipe->getPriority(); 292 293 int pipe1Id = mPipeBook[(int)pipe1Index].mPipe->getPipeId(); 294 int pipe2Id = mPipeBook[(int)pipe2Index].mPipe->getPipeId(); 295 296 utils::eMdpPipeType leftType = PipeBook::getPipeType(pipe1Index); 297 utils::eMdpPipeType rightType = PipeBook::getPipeType(pipe2Index); 298 299 if(pipe1Id >=0 && pipe2Id >=0) { 300 // LEFT priority should be higher then RIGHT 301 return (pipe1Prio > pipe2Prio); 302 } else if(pipe1Id < 0 && pipe2Id < 0) { 303 // If we are here, Source Split is enabled and both pipes are 304 // new requests. In this case left type should be of higher prio 305 // than right type 306 if(leftType == rightType) { 307 //Safe. Onus on driver to assign correct pipes within same type 308 return false; 309 } else { 310 //This check takes advantage of having only 3 types and avoids 3 311 //different failure combination checks. 312 // Swap IF: 313 // ---------------- 314 // | Left | Right | 315 // ================ 316 // | DMA | ViG | 317 // ---------------- 318 // | DMA | RGB | 319 // ---------------- 320 // | RGB | ViG | 321 // ---------------- 322 return (leftType == OV_MDP_PIPE_DMA or rightType == OV_MDP_PIPE_VG); 323 } 324 } else if(pipe1Id < 0) { 325 //LEFT needs new allocation. 326 if(leftType == rightType) { 327 // If RIGHT has highest priority(lowest id), swap it. 328 return (pipe2Id == PipeBook::pipeMinID[leftType]); 329 } else { 330 return (leftType == OV_MDP_PIPE_DMA or rightType == OV_MDP_PIPE_VG); 331 } 332 } else { /* if (pipe2Id < 0) */ 333 // RIGHT needs new allocation. 334 if(leftType == rightType) { 335 // If LEFT has lowest priority(highest id), swap it. 336 return (pipe1Id == PipeBook::pipeMaxID[leftType]); 337 } else { 338 return (leftType == OV_MDP_PIPE_DMA or rightType == OV_MDP_PIPE_VG); 339 } 340 } 341} 342 343bool Overlay::commit(utils::eDest dest) { 344 bool ret = false; 345 validate((int)dest); 346 347 if(mPipeBook[dest].mPipe->commit()) { 348 ret = true; 349 PipeBook::setUse((int)dest); 350 } else { 351 clear(mPipeBook[dest].mDisplay); 352 } 353 return ret; 354} 355 356bool Overlay::queueBuffer(int fd, uint32_t offset, 357 utils::eDest dest) { 358 bool ret = false; 359 validate((int)dest); 360 //Queue only if commit() has succeeded (and the bit set) 361 if(PipeBook::isUsed((int)dest)) { 362 ret = mPipeBook[dest].mPipe->queueBuffer(fd, offset); 363 } 364 return ret; 365} 366 367void Overlay::setCrop(const utils::Dim& d, 368 utils::eDest dest) { 369 validate((int)dest); 370 mPipeBook[dest].mPipe->setCrop(d); 371} 372 373void Overlay::setColor(const uint32_t color, 374 utils::eDest dest) { 375 validate((int)dest); 376 mPipeBook[dest].mPipe->setColor(color); 377} 378 379void Overlay::setPosition(const utils::Dim& d, 380 utils::eDest dest) { 381 validate((int)dest); 382 mPipeBook[dest].mPipe->setPosition(d); 383} 384 385void Overlay::setTransform(const int orient, 386 utils::eDest dest) { 387 validate((int)dest); 388 389 utils::eTransform transform = 390 static_cast<utils::eTransform>(orient); 391 mPipeBook[dest].mPipe->setTransform(transform); 392 393} 394 395void Overlay::setSource(const utils::PipeArgs args, 396 utils::eDest dest) { 397 validate((int)dest); 398 399 setPipeType(dest, PipeBook::getPipeType(dest)); 400 mPipeBook[dest].mPipe->setSource(args); 401} 402 403void Overlay::setVisualParams(const MetaData_t& metadata, utils::eDest dest) { 404 validate((int)dest); 405 mPipeBook[dest].mPipe->setVisualParams(metadata); 406} 407 408void Overlay::setPipeType(utils::eDest pipeIndex, 409 const utils::eMdpPipeType pType) { 410 mPipeBook[pipeIndex].mPipe->setPipeType(pType); 411} 412 413Overlay* Overlay::getInstance() { 414 if(sInstance == NULL) { 415 sInstance = new Overlay(); 416 } 417 return sInstance; 418} 419 420// Clears any VG pipes allocated to the fb devices 421// Generates a LUT for pipe types. 422int Overlay::initOverlay() { 423 int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); 424 int numPipesXType[OV_MDP_PIPE_ANY] = {0}; 425 numPipesXType[OV_MDP_PIPE_RGB] = 426 qdutils::MDPVersion::getInstance().getRGBPipes(); 427 numPipesXType[OV_MDP_PIPE_VG] = 428 qdutils::MDPVersion::getInstance().getVGPipes(); 429 numPipesXType[OV_MDP_PIPE_DMA] = 430 qdutils::MDPVersion::getInstance().getDMAPipes(); 431 432 int index = 0; 433 for(int X = 0; X < (int)OV_MDP_PIPE_ANY; X++) { //iterate over types 434 for(int j = 0; j < numPipesXType[X]; j++) { //iterate over num 435 PipeBook::pipeTypeLUT[index] = (utils::eMdpPipeType)X; 436 index++; 437 } 438 } 439 440 PipeBook::pipeMinID[OV_MDP_PIPE_RGB] = 8; 441 PipeBook::pipeMaxID[OV_MDP_PIPE_RGB] = (numPipesXType[OV_MDP_PIPE_RGB] == 3)? 32 : 512; 442 PipeBook::pipeMinID[OV_MDP_PIPE_VG] = 1; 443 PipeBook::pipeMaxID[OV_MDP_PIPE_VG] = (numPipesXType[OV_MDP_PIPE_VG] == 3)? 4 : 256; 444 PipeBook::pipeMinID[OV_MDP_PIPE_DMA] = 64; 445 PipeBook::pipeMaxID[OV_MDP_PIPE_DMA] = 128; 446 447 FILE *displayDeviceFP = NULL; 448 char fbType[MAX_FRAME_BUFFER_NAME_SIZE]; 449 char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE]; 450 const char *strDtvPanel = "dtv panel"; 451 const char *strWbPanel = "writeback panel"; 452 453 for(int num = 1; num < MAX_FB_DEVICES; num++) { 454 snprintf (msmFbTypePath, sizeof(msmFbTypePath), 455 "/sys/class/graphics/fb%d/msm_fb_type", num); 456 displayDeviceFP = fopen(msmFbTypePath, "r"); 457 458 if(displayDeviceFP){ 459 fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE, 460 displayDeviceFP); 461 462 if(strncmp(fbType, strDtvPanel, strlen(strDtvPanel)) == 0) { 463 sDpyFbMap[DPY_EXTERNAL] = num; 464 } else if(strncmp(fbType, strWbPanel, strlen(strWbPanel)) == 0) { 465 sDpyFbMap[DPY_WRITEBACK] = num; 466 } 467 468 fclose(displayDeviceFP); 469 } 470 } 471 472 return 0; 473} 474 475bool Overlay::displayCommit(const int& fd) { 476 utils::Dim lRoi, rRoi; 477 return displayCommit(fd, lRoi, rRoi); 478} 479 480bool Overlay::displayCommit(const int& fd, const utils::Dim& lRoi, 481 const utils::Dim& rRoi) { 482 //Commit 483 struct mdp_display_commit info; 484 memset(&info, 0, sizeof(struct mdp_display_commit)); 485 info.flags = MDP_DISPLAY_COMMIT_OVERLAY; 486 info.l_roi.x = lRoi.x; 487 info.l_roi.y = lRoi.y; 488 info.l_roi.w = lRoi.w; 489 info.l_roi.h = lRoi.h; 490 info.r_roi.x = rRoi.x; 491 info.r_roi.y = rRoi.y; 492 info.r_roi.w = rRoi.w; 493 info.r_roi.h = rRoi.h; 494 495 if(!mdp_wrapper::displayCommit(fd, info)) { 496 ALOGE("%s: commit failed", __func__); 497 return false; 498 } 499 return true; 500} 501 502void Overlay::getDump(char *buf, size_t len) { 503 int totalPipes = 0; 504 const char *str = "\nOverlay State\n\n"; 505 strlcat(buf, str, len); 506 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 507 if(mPipeBook[i].valid()) { 508 mPipeBook[i].mPipe->getDump(buf, len); 509 char str[64] = {'\0'}; 510 snprintf(str, 64, "Display=%d\n\n", mPipeBook[i].mDisplay); 511 strlcat(buf, str, len); 512 totalPipes++; 513 } 514 } 515 char str_pipes[64] = {'\0'}; 516 snprintf(str_pipes, 64, "Pipes=%d\n\n", totalPipes); 517 strlcat(buf, str_pipes, len); 518} 519 520void Overlay::clear(int dpy) { 521 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 522 if (mPipeBook[i].mDisplay == dpy) { 523 // Mark as available for this round 524 PipeBook::resetUse(i); 525 PipeBook::resetAllocation(i); 526 if(getPipeId((utils::eDest)i) == -1) { 527 mPipeBook[i].destroy(); 528 } 529 } 530 } 531} 532 533bool Overlay::validateAndSet(const int& dpy, const int& fbFd) { 534 GenericPipe* pipeArray[PipeBook::NUM_PIPES]; 535 memset(pipeArray, 0, sizeof(GenericPipe*)*(PipeBook::NUM_PIPES)); 536 537 int num = 0; 538 for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 539 if(PipeBook::isUsed(i) && mPipeBook[i].valid() && 540 mPipeBook[i].mDisplay == dpy) { 541 pipeArray[num++] = mPipeBook[i].mPipe; 542 } 543 } 544 545 //Protect against misbehaving clients 546 return num ? GenericPipe::validateAndSet(pipeArray, num, fbFd) : true; 547} 548 549void Overlay::initScalar() { 550 if(sLibScaleHandle == NULL) { 551 sLibScaleHandle = dlopen("libscale.so", RTLD_NOW); 552 if(sLibScaleHandle) { 553 *(void **) &sFnProgramScale = 554 dlsym(sLibScaleHandle, "programScale"); 555 } 556 } 557} 558 559void Overlay::destroyScalar() { 560 if(sLibScaleHandle) { 561 dlclose(sLibScaleHandle); 562 sLibScaleHandle = NULL; 563 } 564} 565 566void Overlay::initPostProc() { 567 sLibAblHandle = dlopen("libmm-abl.so", RTLD_NOW); 568 if (sLibAblHandle) { 569 *(void **)&sFnppParams = dlsym(sLibAblHandle, 570 "display_pp_compute_params"); 571 } else { 572 ALOGE("%s: Not able to load libmm-abl.so", __FUNCTION__); 573 } 574} 575 576void Overlay::destroyPostProc() { 577 if (sLibAblHandle) { 578 dlclose(sLibAblHandle); 579 sLibAblHandle = NULL; 580 } 581} 582 583void Overlay::PipeBook::init() { 584 mPipe = NULL; 585 mDisplay = DPY_UNUSED; 586 mMixer = MIXER_UNUSED; 587 mFormatType = FORMAT_NONE; 588} 589 590void Overlay::PipeBook::destroy() { 591 if(mPipe) { 592 delete mPipe; 593 mPipe = NULL; 594 } 595 mDisplay = DPY_UNUSED; 596 mMixer = MIXER_UNUSED; 597 mFormatType = FORMAT_NONE; 598 mSession = NONE; 599} 600 601Overlay* Overlay::sInstance = 0; 602int Overlay::sDpyFbMap[DPY_MAX] = {0, -1, -1}; 603int Overlay::sDMAMode = DMA_LINE_MODE; 604bool Overlay::sDMAMultiplexingSupported = false; 605bool Overlay::sDebugPipeLifecycle = false; 606int Overlay::PipeBook::NUM_PIPES = 0; 607int Overlay::PipeBook::sPipeUsageBitmap = 0; 608int Overlay::PipeBook::sLastUsageBitmap = 0; 609int Overlay::PipeBook::sAllocatedBitmap = 0; 610utils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] = 611 {utils::OV_MDP_PIPE_ANY}; 612int Overlay::PipeBook::pipeMinID[utils::OV_MDP_PIPE_ANY] = {0}; 613int Overlay::PipeBook::pipeMaxID[utils::OV_MDP_PIPE_ANY] = {0}; 614void *Overlay::sLibScaleHandle = NULL; 615int (*Overlay::sFnProgramScale)(struct mdp_overlay_list *) = NULL; 616/* Dynamically link ABL library */ 617void *Overlay::sLibAblHandle = NULL; 618int (*Overlay::sFnppParams)(const struct compute_params *, 619 struct mdp_overlay_pp_params *) = NULL; 620 621}; // namespace overlay 622