void GuiExtPool::removePoolItemLocked(uint32_t poolId) { sp<GuiExtPoolItem> item = mPoolList.valueFor(poolId); if (item == NULL) { GUIEXT_LOGW(" remove a non-exist pool item, poolId=%d", poolId); return; } bool hasConsumerExist = false; for (uint32_t i = 0; i < GUI_EXT_USAGE_MAX; i++) { if (!item->mIsDisconnected[i]) { hasConsumerExist = true; GUIEXT_LOGV(" find poolId=%d exist consumer[%s]", poolId, szUsageName[i]); return; } } if (!hasConsumerExist && item->mProducerToken == NULL) { mPoolList.removeItem(poolId); GUIEXT_LOGV("remove pool item, id=%d", poolId); } else { GUIEXT_LOGV("remove pool item fail, id=%d, producer not free yet, token=%p, pid=%d", poolId, item->mProducerToken.get(), item->mProducerPid); } }
status_t GuiExtClientProducer::free(uint32_t poolId) { status_t err; Mutex::Autolock _l(mLock); err = assertStateLocked(); if (err != NO_ERROR) { GUIEXT_LOGE("[%s] assertStateLocked fail", __func__); return err; } GUIEXT_LOGV("free +, poolId=%d", poolId); err = mGuiExtService->free(poolId); GUIEXT_LOGV("free -, poolId=%d, ret=%d", poolId, err); return err; }
GuiExtPoolItem::GuiExtPoolItem(const sp<IBinder>& token, bool isHwcNeeded, uint32_t poolId, uint32_t /*w*/, uint32_t /*h*/, DefaultKeyedVector< uint32_t, sp<DispInfo> >& dispList, sp<IBinder::DeathRecipient> observer) : mConsumerDeathListener(NULL) //, mGPUUsedBq(NULL) , mGPUUsedProducer(NULL) , mGPUUsedConsumer(NULL) #if !SUPPORT_MULTIBQ_FOR_HWC , mHwcUsedBq(NULL) #endif , mId(poolId) , mIsHwcNeeded(isHwcNeeded) , mGpuUsedBufNum(MAX_GLES_DEQUEUED_NUM) , mProducerPid(-1) , mProducerToken(token) , mProducerDeathObserver(observer) { GUIEXT_LOGV("GuiExtPoolItem ctor, poolId=%d, isHwcNeeded=%d, token=%p", poolId, isHwcNeeded, token.get()); //String8 name(szUsageName[0]); //name.appendFormat("_%d", poolId); //mGPUUsedBq = createBufferQueue(w, h, mGpuUsedBufNum, name); //createBufferQueue(w, h, mGpuUsedBufNum, name, &mGPUUsedProducer, &mGPUUsedConsumer); #ifdef CONFIG_FOR_SOURCE_PQ setOverlaySessionMode(true); #endif if (mIsHwcNeeded) { String8 name(szUsageName[1]); name.appendFormat("_%d", poolId); #if SUPPORT_MULTIBQ_FOR_HWC uint32_t disp_size = dispList.size(); for (uint32_t i = 0; i < disp_size; i++) { uint32_t type = dispList[i]->type; String8 extname(name); extname.appendFormat("_%d", type); sp<HwcBqSlot> slot = new HwcBqSlot(); //slot->bq = createBufferQueue(dispList[i]->w, dispList[i]->h, dispList[i]->bufNum, extname); createBufferQueue(dispList[i]->w, dispList[i]->h, dispList[i]->bufNum, extname, &slot->mProducer, &slot->mConsumer); slot->type = type; slot->bufNum = dispList[i]->bufNum; mHwcUsedBqList.add(type, slot); } #else mHwcUsedBq = createBufferQueue(dispList[0]->w, dispList[0]->h, dispList[i]->bufNum, name); #endif } mProducerPid = (NULL != token->localBinder()) ? getpid() : IPCThreadState::self()->getCallingPid(); for (uint32_t i = 0; i < GUI_EXT_USAGE_MAX; i++) mIsDisconnected[i] = true; }
status_t GuiExtClientProducer::alloc(uint32_t gralloc_usage, uint32_t w, uint32_t h, uint32_t *poolId) { status_t err; Mutex::Autolock _l(mLock); err = assertStateLocked(); if (err != NO_ERROR) { GUIEXT_LOGE("[%s] assertStateLocked fail", __func__); return err; } GUIEXT_LOGV("alloc +, gralloc_usage=%x, w=%d, h=%d", gralloc_usage, w, h); static sp<BBinder> sLife = new BBinder(); err = mGuiExtService->alloc(sLife, gralloc_usage, w, h, poolId); GUIEXT_LOGV("alloc -, poolId=%d", *poolId); return err; }
virtual void binderDied(const wp<IBinder>& who) { uint32_t size = mItem.mConsumerList.size(); GUIEXT_LOGI("consumer died, list size=%d, binder ptr=[%p]", size, who.unsafe_get()); if (size == 0) { GUIEXT_LOGV("consumer died [%p], pool size is zero", who.unsafe_get()); } else { for (uint32_t i = 0 ; i < size ; i++) { GUIEXT_LOGV(" [c] compare index[%d], p=[%p], usage=%d, type=%d, id=%d", i, mItem.mConsumerList[i]->token.get(), mItem.mConsumerList[i]->usage, mItem.mConsumerList[i]->type, mItem.mConsumerList[i]->idx); if (mItem.mConsumerList[i]->token.get() == who.unsafe_get()) { GUIEXT_LOGW(" [c] found index[%d], p=[%p], usage=%d, type=%d, id=%d", i, mItem.mConsumerList[i]->token.get(), mItem.mConsumerList[i]->usage, mItem.mConsumerList[i]->type, mItem.mConsumerList[i]->idx); mItem.release(mItem.mConsumerList[i]->usage, mItem.mConsumerList[i]->type, mItem.mConsumerList[i]->idx); mItem.mConsumerList[i]->token = NULL; mItem.mConsumerList[i]->pid = -1; mItem.mConsumerList[i]->observer = NULL; } } for (uint32_t i = 0; i < GUI_EXT_USAGE_MAX; i++) { mItem.mIsDisconnected[i] = true; } bool isDisconnect = true; for (uint32_t i = 0 ; i < size ; i++) { if (mItem.mConsumerList[i]->token != NULL) { mItem.mIsDisconnected[mItem.mConsumerList[i]->usage] = false; isDisconnect = false; GUIEXT_LOGV(" [c] still have consumer, idx=%d, token=%p, pid=%d, usage=%d, type=%d, id=%d", i, mItem.mConsumerList[i]->token.get(), mItem.mConsumerList[i]->pid, mItem.mConsumerList[i]->usage, mItem.mConsumerList[i]->type, mItem.mConsumerList[i]->idx); } } if (isDisconnect) { mItem.mConsumerDeathListener->binderDied(mItem.mId); } GUIEXT_LOGV("consumer died done"); } }
status_t GuiExtPoolItem::prepareBuffer(uint32_t gralloc_usage) { status_t err = NO_ERROR; //err = prepareBuffer(mGPUUsedProducer, GUI_EXT_USAGE_GPU, 0, gralloc_usage, mGpuUsedBufNum); //GUIEXT_LOGV(" prepare %s buffer done", szUsageName[GUI_EXT_USAGE_GPU]); if (mIsHwcNeeded) { #if SUPPORT_MULTIBQ_FOR_HWC for (uint32_t i = 0; i < mHwcUsedBqList.size(); i++) { err = prepareBuffer(mHwcUsedBqList[i]->mProducer, GUI_EXT_USAGE_HWC, mHwcUsedBqList[i]->type, gralloc_usage, mHwcUsedBqList[i]->bufNum); GUIEXT_LOGV(" prepare %s buffer, type=%d done", szUsageName[GUI_EXT_USAGE_HWC], mHwcUsedBqList[i]->type); } #else err = prepareBuffer(mHwcUsedBq, GUI_EXT_USAGE_HWC, 0, gralloc_usage, mHwcUsedBqList[i]->bufNum); GUIEXT_LOGV(" prepare %s buffer done", szUsageName[GUI_EXT_USAGE_HWC]); #endif } return err; }
virtual void binderDied(const wp<IBinder>& who) { uint32_t size = mPool.mPoolList.size(); GUIEXT_LOGI("producer died, pool size=%d, binder ptr=[%p]", size, who.unsafe_get()); if (size == 0) { GUIEXT_LOGV("producer died [%p], pool size is zero", who.unsafe_get()); } else { for (uint32_t i = size-1 ;; i--) { GUIEXT_LOGV(" [p] compare index[%d], p=[%p]", i, mPool.mPoolList[i]->mProducerToken.get()); if (mPool.mPoolList[i]->mProducerToken.get() == who.unsafe_get()) { GUIEXT_LOGW(" [p] found index[%d], p=[%p], id=%d", i, mPool.mPoolList[i]->mProducerToken.get(), mPool.mPoolList[i]->mId); mPool.mPoolList[i]->mProducerToken = NULL; mPool.mPoolList[i]->mProducerPid = -1; mPool.removePoolItem(mPool.mPoolList[i]->mId); } if (i == 0) break; } GUIEXT_LOGV("producer died done"); } }
status_t GuiExtPoolItem::prepareBuffer(sp<IGraphicBufferProducer> producer, uint32_t usage, uint32_t type, uint32_t gralloc_usage, uint32_t bufNum) { status_t err = NO_ERROR; uint32_t usg = (gralloc_usage & GRALLOC_USAGE_SECURE) != 0 ? (LOCK_FOR_USAGE | GRALLOC_USAGE_SECURE) : LOCK_FOR_USAGE; uint32_t fmt = gAcquiredFormat[usage]; GUIEXT_LOGV("prepareBuffer, type=%d, fmt=%x, usage=%x, usg=%x, bufNum=%d", usage, fmt, gralloc_usage, usg, bufNum); for (uint32_t i = 0; i < bufNum; i++) { int buf = -1; sp<Fence> fence; producer->dequeueBuffer(&buf, &fence, false, 0, 0, fmt, usg); uint32_t combine_id = POOL_COMBINED_ID(usage, type, i); sp<ConsumerSlot> consumerSlot = mConsumerList.valueFor(combine_id); if (consumerSlot == 0) { sp<ConsumerSlot> slot = new ConsumerSlot(); slot->token = NULL; slot->pid = -1; slot->usage = usage; slot->type = type; slot->idx = i; mConsumerList.add(combine_id, slot); } #ifdef TOUCH_ION_BUFFER sp<GraphicBuffer> gb; producer->requestBuffer(buf, &gb); touchIonBuffer(gb); #endif } for (uint32_t i = 0; i < bufNum; i++) { sp<Fence> fence = Fence::NO_FENCE; producer->cancelBuffer(i, fence); } return err; }
virtual void binderDied(uint32_t poolId) { GUIEXT_LOGV(" [cb] all consumers has disconnected +, poolId=%d", poolId); mPool.removePoolItem(poolId); GUIEXT_LOGV(" [cb] consumer has died -"); }