Exemplo n.º 1
0
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MBOOL
IspDebug::
uninit()
{
	Mutex::Autolock lock(m_Lock);

	// If no more users, return directly and do nothing.
	if (m_Users <= 0)
	{
		return MTRUE;
	}

	// More than one user, so decrease one User.
	android_atomic_dec(&m_Users);

	if (m_Users == 0) // There is no more User after decrease one User
	{
        if (m_pIspDrv) {
            m_pIspDrv->uninit();
            }

        m_pIspReg = MNULL;
        m_pIspDrv = MNULL;
    }
	else	// There are still some users.
	{
		MY_LOG("Still %d users \n", m_Users);
	}

    return MTRUE;
}
Exemplo n.º 2
0
MBOOL
Ts_IT::
TS_Thread_UnInit()
{
    MY_LOGD("E");

    MBOOL ret = MTRUE;
    Mutex::Autolock lock(mLock);

    MY_LOGD("mInitCount(%d)\n",mInitCount);

    if(mInitCount <= 0)
    {
        // No more users
        MY_LOGD("no more user, X");
        return ret;
    }

    android_atomic_dec(&mInitCount);
    if(mInitCount > 0)
    {
        MY_LOGD("more than one user, X");
        return ret;
    }

    //pthread_cancel(m_TestEnDequethread);

    MY_LOGD("X");
    return ret;
}
//----------------------------------------------------------------------------
MBOOL PipeMgrDrvImp::Uninit(void)
{
    MBOOL Result = MTRUE;
    //
    Mutex::Autolock lock(mLock);
    //
    if(mUser <= 0)
    {
        LOG_WRN("No user(%d)",mUser);
        goto EXIT;
    }
    //
    android_atomic_dec(&mUser);
    //
    if(mUser == 0)
    {
        LOG_MSG("Last user(%d)",mUser);
    }
    else
    {
        LOG_MSG("More user(%d)",mUser);
        goto EXIT;
    }
    //
    if(mFd >= 0)
    {
        close(mFd);
        mFd = -1;
    }
    //
    EXIT:
    return Result;
}
ssize_t SharedBufferClient::DequeueUpdate::operator()() {
    if (android_atomic_dec(&stack.available) == 0) {
        LOGW("dequeue probably called from multiple threads!");
    }
    stack.numofbuffer = stack.available;
    return NO_ERROR;
}
Exemplo n.º 5
0
MBOOL
Ts_UT::
TS_Thread_UnInit()
{
    MBOOL ret = MTRUE;
    printf("[TS_Thread_UnInit] E\n");

    Mutex::Autolock lock(mLock);
    printf("[Thread_UnInit] mInitCount(%d)\n",mInitCount);
    //
    if(mInitCount <= 0)
    {
        // No more users
        printf("[TS_Thread_UnInit] no more user, X\n");
        return ret;
    }
    // More than one user
    android_atomic_dec(&mInitCount);
    //
    if(mInitCount > 0)
    {
        printf("[TS_Thread_UnInit] more than one user, X\n");
        return ret;
    }

//    pthread_cancel(m_TestEnDequethread);

    printf("[TS_Thread_UnInit] X\n");
    return ret;
}
Exemplo n.º 6
0
void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast<weakref_impl*>(this);
    impl->removeWeakRef(id);
    const int32_t c = android_atomic_dec(&impl->mWeak);
    ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
    if (c != 1) return;

    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
        // This is the regular lifetime case. The object is destroyed
        // when the last strong reference goes away. Since weakref_impl
        // outlive the object, it is not destroyed in the dtor, and
        // we'll have to do it here.
        if (impl->mStrong == INITIAL_STRONG_VALUE) {
            // Special case: we never had a strong reference, so we need to
            // destroy the object now.
            delete impl->mBase;
        } else {
            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
            delete impl;
        }
    } else {
        // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
        impl->mBase->onLastWeakRef(id);
        if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
            // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
            // is gone, we can destroy the object.
            delete impl->mBase;
        }
    }
}
int FlashlightDrv::uninitNoLock()
{
    DRV_DBG("uninitNoLock user=%d",mUsers);
    //MHAL_LOG("[halSTROBEUninit] \n");


    if (mUsers == 0)
    {
        DRV_DBG("[uninitNoLock] mUsers = %d\n", mUsers);
    }

     if (mUsers == 1)
     {
        if (m_fdSTROBE > 0)
        {
            close(m_fdSTROBE);
        }
        m_fdSTROBE = -1;
    }

    android_atomic_dec(&mUsers);
    m_bTempInit=0;

    return StrobeDrv::STROBE_NO_ERROR;
}
Exemplo n.º 8
0
//-----------------------------------------------------------------------------
MBOOL TdriMgrImp::uninit(void)
{
    MBOOL Result = MTRUE;
    int i;
    //
    GLOBAL_PROFILING_LOG_PRINT(__func__);
    GLOBAL_PROFILING_LOG_PRINT("Uninit TdriMgr");
    //
    Mutex::Autolock lock(mLock);
    //
    LOG_INF("mInitCount(%d)",mInitCount);
    //
    android_atomic_dec(&mInitCount);
    //
    if(mInitCount > 0) {
        goto EXIT;
    }


    for(i=TPIPE_DRV_CQ01; i<=TPIPE_DRV_CQ02; i++) {
        if(i == TPIPE_DRV_CQ01) {
            pIspDrv->lockSemaphoreCq1();
            tdriMgrInfo[i].pDescriptorArray = NULL;
            tdriMgrInfo[i].pDesriptorNum = 0;
            tdriMgrInfo[i].pTopCtlEn1 = 0;
            tdriMgrInfo[i].pTopCtlEn2 = 0;
            tdriMgrInfo[i].pTopCtlDma = 0;
            pIspDrv->unlockSemaphoreCq1();
        } else if (i == TPIPE_DRV_CQ02) {
            pIspDrv->lockSemaphoreCq2();
            tdriMgrInfo[i].pDescriptorArray = NULL;
            tdriMgrInfo[i].pDesriptorNum = 0;
            tdriMgrInfo[i].pTopCtlEn1 = 0;
            tdriMgrInfo[i].pTopCtlEn2 = 0;
            tdriMgrInfo[i].pTopCtlDma = 0;
            pIspDrv->unlockSemaphoreCq2();
        } else {
            LOG_ERR("[ERROR]not support this tdri cq(%d) number \n");
        }
    }


    //tpipe driver
    pTdriDri->uninit();
    pTdriDri->destroyInstance();
    pTdriDri = NULL;

    //isp drv
    pIspDrv->setCallbacks(NULL, NULL);
    pIspDrv->uninit();
    pIspDrv->destroyInstance();
    pIspDrv = NULL;

    LOG_INF("Release\n");

EXIT:
    return Result;
}
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    if (val == NULL) return NULL;

    if (val->checkSubclass(&gBinderOffsets)) {
        // One of our own!
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }

    // For the rest of the function we will hold this lock, to serialize
    // looking/creation of Java proxies for native Binder proxies.
    AutoMutex _l(mProxyLock);

    // Someone else's...  do we know about it?
    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    if (object != NULL) {
        jobject res = jniGetReferent(env, object);
        if (res != NULL) {
            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
            return res;
        }
        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
        android_atomic_dec(&gNumProxyRefs);
        val->detachObject(&gBinderProxyOffsets);
        env->DeleteGlobalRef(object);
    }

    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
        // The proxy holds a reference to the native object.
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        val->incStrong((void*)javaObjectForIBinder);

        // The native object needs to hold a weak reference back to the
        // proxy, so we can retrieve the same proxy if it is still active.
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);

        // Also remember the death recipients registered on this proxy
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));

        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }

    return object;
}
Exemplo n.º 10
0
int32_t SharedBuffer::release(uint32_t flags) const
{
    int32_t prev = 1;
    if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) {
        mRefs = 0;
        if ((flags & eKeepStorage) == 0) {
            free(const_cast<SharedBuffer*>(this));
        }
    }
    return prev;
}
MINT32
mHalCam::mHalCamReleaseVdoFrame(MVOID * a_pInBuffer)
{
    MINT32 *pIdx = (MINT32 *)a_pInBuffer; 

    android_atomic_dec(&mVdoBusyFrmCnt); 
    MCAM_DBG("[mHalCamReleaseVdoFrame] (pIdx, busyCnt, caller) = (%d, %d, %d) \n", *pIdx, mVdoBusyFrmCnt, gettid()); 

    //ICameraIO::BuffInfo_t rBufInfo; 
    //return mpCameraIOObj->releasePreviewFrame(ICameraIO::ePREVIEW_VIDEO_PORT, &rBufInfo); 
    return 0;
}
Exemplo n.º 12
0
/*
 * Exercise several of the atomic ops.
 */
static void doAtomicTest(int num) {
    int addVal = (num & 0x01) + 1;

    int i;
    for (i = 0; i < ITERATION_COUNT; i++) {
        if (USE_ATOMIC) {
            android_atomic_inc(&incTest);
            android_atomic_dec(&decTest);
            android_atomic_add(addVal, &addTest);

            int val;
            do {
                val = casTest;
            } while (android_atomic_release_cas(val, val + 3, &casTest) != 0);
            do {
                val = casTest;
            } while (android_atomic_acquire_cas(val, val - 1, &casTest) != 0);

            int64_t wval;
            do {
                wval = dvmQuasiAtomicRead64(&wideCasTest);
            } while (dvmQuasiAtomicCas64(wval,
                                         wval + 0x0000002000000001LL, &wideCasTest) != 0);
            do {
                wval = dvmQuasiAtomicRead64(&wideCasTest);
            } while (dvmQuasiAtomicCas64(wval,
                                         wval - 0x0000002000000001LL, &wideCasTest) != 0);
        } else {
            incr();
            decr();
            add(addVal);

            int val;
            do {
                val = casTest;
            } while (compareAndSwap(val, val + 3, &casTest) != 0);
            do {
                val = casTest;
            } while (compareAndSwap(val, val - 1, &casTest) != 0);

            int64_t wval;
            do {
                wval = wideCasTest;
            } while (compareAndSwapWide(wval,
                                        wval + 0x0000002000000001LL, &wideCasTest) != 0);
            do {
                wval = wideCasTest;
            } while (compareAndSwapWide(wval,
                                        wval - 0x0000002000000001LL, &wideCasTest) != 0);
        }
    }
}
Exemplo n.º 13
0
void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    refs->removeStrongRef(id);
    const int32_t c = android_atomic_dec(&refs->mStrong);
#if PRINT_REFS
    ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
    ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
    if (c == 1) {
        refs->mBase->onLastStrongRef(id);
        if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
            delete this;
        }
    }
    refs->decWeak(id);
}
Exemplo n.º 14
0
MBOOL
HdrHal::uninit()
{
	HDR_LOGD("- E. mUsers: %d.", mUsers);
    MBOOL   ret = MTRUE;

	Mutex::Autolock lock(mLock);

	// If no more users, return directly and do nothing.
	if (mUsers <= 0)
	{
		HDR_LOGD("- X. ret: %d.", ret);
		return ret;
	}

	// More than one user, so decrease one User.
	android_atomic_dec(&mUsers);

	if (mUsers == 0) // There is no more User after decrease one User, then destroy IspDrv instance.
	{
		// Destroy HdrDrv instance.
		if (m_pHdrDrv)
		{
			m_pHdrDrv->destroyInstance();
			m_pHdrDrv = NULL;
		}

		//#if EARLY_MAV_INIT
		// Destroy MavDrv instance.
		if (m_pMavDrv)
		{
			m_pMavDrv->MavReset();
			m_pMavDrv->destroyInstance();
			m_pMavDrv = NULL;
		}
		//#endif	// EARLY_MAV_INIT
	}
	else	// There are still some users.
	{
		HDR_LOGD("Still %d users.", mUsers);
	}

	HDR_LOGD("- X. ret: %d.", ret);
	return ret;

}
Exemplo n.º 15
0
int V4L2VideoNode::dqbuf(struct v4l2_buffer_info *buf)
{
    LOG2("@%s", __FUNCTION__);
    struct v4l2_buffer *v4l2_buf = &buf->vbuffer;
    int ret = 0;

    v4l2_buf->type = mInBufType;
    v4l2_buf->memory = V4L2_MEMORY_USERPTR;

    ret = pioctl(mFd, VIDIOC_DQBUF, v4l2_buf);
    if (ret < 0) {
        LOGE("VIDIOC_QBUF failed: %s", strerror(errno));
        return ret;
    }
    android_atomic_dec(&mBuffersInDevice);
    return ret;
}
//-----------------------------------------------------------------------------
MBOOL
ResourceLockImp::
Uninit(void)
{
    MBOOL Result = MTRUE;
    //
    Mutex::Autolock lock(mLock);
    //
    if(mUser <= 0)
    {
        MY_LOGW("No user(%d)",mUser);
        goto EXIT;
    }
    //
    android_atomic_dec(&mUser);
    //
    if(mUser == 0)
    {
        MY_LOGD("Last user(%d)",mUser);
    }
    else
    {
        MY_LOGD("More user(%d)",mUser);
        goto EXIT;
    }
    //
    if(mpResMgr != NULL)
    {
        mpResMgr->Uninit();
        mpResMgr->DestroyInstance();
        mpResMgr = NULL;
    }
    //
    if(mpPipeMgr != NULL)
    {
        mpPipeMgr->Uninit();
        mpPipeMgr->DestroyInstance();
        mpPipeMgr = NULL;    
    }
    //
    EXIT:
    return Result;
}
Exemplo n.º 17
0
int StrobeGlobalDriver::closekd_nolock()
{
	if(mUsers<=0)
	{
		logW("closekd_nolock user<=0");
		return 0;
	}
	if(mUsers == 1)
	{
		if (mStrobeHandle > 0)
		{
		    logI("close flash driver kd=%d", mStrobeHandle);
			close(mStrobeHandle);
		}
		mStrobeHandle = -1;
	}
	android_atomic_dec(&mUsers);
    return 0;
}
//----------------------------------------------------------------------------
MBOOL ResMgrHalImp::Uninit(void)
{
    MBOOL Result = MTRUE;
    //
    Mutex::Autolock lock(mLock);
    //
    LOG_MSG("mInitCount(%d)",mInitCount);
    //
    if(mInitCount <= 0)
    {
        goto EXIT;
    }
    //
    android_atomic_dec(&mInitCount);
    //
    if(mInitCount > 0)
    {
        goto EXIT;
    }
    //
    if(MdpDrvRelease() < 0)
    {
        LOG_ERR("MdpDrvRelease() fail");
    }
    //
    if(mpDrv != NULL)
    {
        LOG_MSG("unlock ISP");
        mpDrv->UnlockRes(RES_MGR_DRV_RES_ISP);
        mpDrv->Uninit();
        mpDrv->DestroyInstance();
        mpDrv = NULL;
    }
    //
    EXIT:
    return Result;
}
Exemplo n.º 19
0
void HeapCache::free_heap(const wp<IBinder>& binder)
{
    sp<IMemoryHeap> rel;
    {
        Mutex::Autolock _l(mHeapCacheLock);
        ssize_t i = mHeapCache.indexOfKey(binder);
        if (i>=0) {
            heap_info_t& info(mHeapCache.editValueAt(i));
            int32_t c = android_atomic_dec(&info.count);
            if (c == 1) {
                ALOGD_IF(VERBOSE,
                        "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d",
                        binder.unsafe_get(), info.heap.get(),
                        static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
                        static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
                        info.count);
                rel = mHeapCache.valueAt(i).heap;
                mHeapCache.removeItemsAt(i);
            }
        } else {
            ALOGE("free_heap binder=%p not found!!!", binder.unsafe_get());
        }
    }
}
Exemplo n.º 20
0
MINT32 EisHal::uninit()
{
    EIS_LOG("mUsers(%d)", mUsers);

    Mutex::Autolock lock(mLock);

    //====== Check Reference Count ======

    if(mUsers <= 0)
    {
        EIS_LOG("There is no more user");
        return EIS_RETURN_NO_ERROR;
    }

    //====== Uninitialize ======

    android_atomic_dec(&mUsers);    //decrease referebce count

    if(mUsers == 0)    // there is no user
    {
        MINT32 err = EIS_RETURN_NO_ERROR;

        //====== Dynamic Debug ======

        char value[PROPERTY_VALUE_MAX] = {'\0'};
        property_get("debug.eis.dump", value, "0");
        g_debugDump = atoi(value);

        if(g_debugDump >= 2)
        {
            EIS_SET_LOG_BUFFER_STRUCT pEisAlgoLogInfo;

            pEisAlgoLogInfo.Eis_Log_Buf_Addr = mEisAlgoIMemBuf.virtAddr;
            pEisAlgoLogInfo.Eis_Log_Buf_Size = mEisAlgoIMemBuf.size;

        	err = m_pEisAlg->EisFeatureCtrl(EIS_FEATURE_SAVE_LOG, &pEisAlgoLogInfo, NULL);
    	    if(err != S_EIS_OK)
    	    {
    	        EIS_ERR("EisFeatureCtrl(EIS_FEATURE_SAVE_LOG) fail(0x%x)",err);
    	    }
        }

        m_pEisDrv->enableEIS(0);

    	if(m_pEisDrv != NULL)
        {
        	m_pEisDrv->destroyInstance();
        	m_pEisDrv = NULL;
    	}

        if(m_pEisAlg != NULL)
        {
            m_pEisAlg->destroyInstance();
            m_pEisAlg = NULL;
        }

        if(g_debugDump >= 2)
        {
            //====== Free Memory ======

            destroyMemBuf(1,&mEisAlgoIMemBuf);

            mEisAlgoIMemBuf.memID = -5;
            mEisAlgoIMemBuf.virtAddr = mEisAlgoIMemBuf.phyAddr = mEisAlgoIMemBuf.size = 0;

            if(m_pIMemDrv != NULL)
            {
                m_pIMemDrv->destroyInstance();
                m_pIMemDrv = NULL;
            }
        }

        mFirstFlag = 0; // first frmae
        mConfigPass = MFALSE;
    }
    else
    {
        EIS_LOG("Still %d users", mUsers);
    }

    EIS_LOG("-");
    return EIS_RETURN_NO_ERROR;
}
Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
    ATRACE_CALL();

    Region outDirtyRegion;
    if (mQueuedFrames > 0) {

        // if we've already called updateTexImage() without going through
        // a composition step, we have to skip this layer at this point
        // because we cannot call updateTeximage() without a corresponding
        // compositionComplete() call.
        // we'll trigger an update in onPreComposition().
        if (mRefreshPending) {
            return outDirtyRegion;
        }

        // Capture the old state of the layer for comparisons later
        const bool oldOpacity = isOpaque();
        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;

        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
            Layer::State& front;
            Layer::State& current;
            bool& recomputeVisibleRegions;
            Reject(Layer::State& front, Layer::State& current,
                    bool& recomputeVisibleRegions)
                : front(front), current(current),
                  recomputeVisibleRegions(recomputeVisibleRegions) {
            }

            virtual bool reject(const sp<GraphicBuffer>& buf,
                    const IGraphicBufferConsumer::BufferItem& item) {
                if (buf == NULL) {
                    return false;
                }

                uint32_t bufWidth  = buf->getWidth();
                uint32_t bufHeight = buf->getHeight();

                // check that we received a buffer of the right size
                // (Take the buffer's orientation into account)
                if (item.mTransform & Transform::ROT_90) {
                    swap(bufWidth, bufHeight);
                }

                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
                if (front.active != front.requested) {

                    if (isFixedSize ||
                            (bufWidth == front.requested.w &&
                             bufHeight == front.requested.h))
                    {
                        // Here we pretend the transaction happened by updating the
                        // current and drawing states. Drawing state is only accessed
                        // in this thread, no need to have it locked
                        front.active = front.requested;

                        // We also need to update the current state so that
                        // we don't end-up overwriting the drawing state with
                        // this stale current state during the next transaction
                        //
                        // NOTE: We don't need to hold the transaction lock here
                        // because State::active is only accessed from this thread.
                        current.active = front.active;

                        // recompute visible region
                        recomputeVisibleRegions = true;
                    }

                    ALOGD_IF(DEBUG_RESIZE,
                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
                            front.active.w, front.active.h,
                            front.active.crop.left,
                            front.active.crop.top,
                            front.active.crop.right,
                            front.active.crop.bottom,
                            front.active.crop.getWidth(),
                            front.active.crop.getHeight(),
                            front.requested.w, front.requested.h,
                            front.requested.crop.left,
                            front.requested.crop.top,
                            front.requested.crop.right,
                            front.requested.crop.bottom,
                            front.requested.crop.getWidth(),
                            front.requested.crop.getHeight());
                }

                if (!isFixedSize) {
                    if (front.active.w != bufWidth ||
                        front.active.h != bufHeight) {
                        // reject this buffer
                        //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
                        //        bufWidth, bufHeight, front.active.w, front.active.h);
                        return true;
                    }
                }

                // if the transparent region has changed (this test is
                // conservative, but that's fine, worst case we're doing
                // a bit of extra work), we latch the new one and we
                // trigger a visible-region recompute.
                if (!front.activeTransparentRegion.isTriviallyEqual(
                        front.requestedTransparentRegion)) {
                    front.activeTransparentRegion = front.requestedTransparentRegion;

                    // We also need to update the current state so that
                    // we don't end-up overwriting the drawing state with
                    // this stale current state during the next transaction
                    //
                    // NOTE: We don't need to hold the transaction lock here
                    // because State::active is only accessed from this thread.
                    current.activeTransparentRegion = front.activeTransparentRegion;

                    // recompute visible region
                    recomputeVisibleRegions = true;
                }

                return false;
            }
        };


        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);

        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
        if (updateResult == BufferQueue::PRESENT_LATER) {
            // Producer doesn't want buffer to be displayed yet.  Signal a
            // layer update so we check again at the next opportunity.
            mFlinger->signalLayerUpdate();
            return outDirtyRegion;
        }

        // Decrement the queued-frames count.  Signal another event if we
        // have more frames pending.
        if (android_atomic_dec(&mQueuedFrames) > 1) {
            mFlinger->signalLayerUpdate();
        }

        if (updateResult != NO_ERROR) {
            // something happened!
            recomputeVisibleRegions = true;
            return outDirtyRegion;
        }

        // update the active buffer
        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
        if (mActiveBuffer == NULL) {
            // this can only happen if the very first buffer was rejected.
            return outDirtyRegion;
        }

        mRefreshPending = true;
        mFrameLatencyNeeded = true;
        if (oldActiveBuffer == NULL) {
             // the first time we receive a buffer, we need to trigger a
             // geometry invalidation.
            recomputeVisibleRegions = true;
         }

        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
        if ((crop != mCurrentCrop) ||
            (transform != mCurrentTransform) ||
            (scalingMode != mCurrentScalingMode))
        {
            mCurrentCrop = crop;
            mCurrentTransform = transform;
            mCurrentScalingMode = scalingMode;
            recomputeVisibleRegions = true;
        }

        if (oldActiveBuffer != NULL) {
            uint32_t bufWidth  = mActiveBuffer->getWidth();
            uint32_t bufHeight = mActiveBuffer->getHeight();
            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
                bufHeight != uint32_t(oldActiveBuffer->height)) {
                recomputeVisibleRegions = true;
            }
        }

        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
        if (oldOpacity != isOpaque()) {
            recomputeVisibleRegions = true;
        }

        // FIXME: postedRegion should be dirty & bounds
        const Layer::State& s(getDrawingState());
        Region dirtyRegion(Rect(s.active.w, s.active.h));

        // transform the dirty region to window-manager space
        outDirtyRegion = (s.transform.transform(dirtyRegion));
    }
    return outDirtyRegion;
}
Exemplo n.º 22
0
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////
///We do decrease global and local count first, then judge we have to uninit m4uDrv/ion_dev and m4uPort according
///   local count and global count repectively.
MBOOL IMemDrvImp::uninit(void)
{
    MBOOL Result = MTRUE;
    MINT32 ret = 0;
    ISP_REF_CNT_CTRL_STRUCT ref_cnt;
    //
    Mutex::Autolock lock(mLock);
    //
#if defined(_use_kernel_ref_cnt_)
    if(mIspFd < 0)
    {
        IMEM_ERR("mIspFd < 0 \n");
		goto EXIT;
    }
    ///////////////////////////////////////////////
    //decrease global and local count first  
    // More than one user
    ref_cnt.ctrl = ISP_REF_CNT_DEC;
    ref_cnt.id = ISP_REF_CNT_ID_IMEM;
    ref_cnt.data_ptr = (MUINT32)&mInitCount;
    ret = ioctl(mIspFd,ISP_REF_CNT_CTRL,&ref_cnt);
    if(ret < 0)
    {
        IMEM_ERR("ISP_REF_CNT_DEC fail(%d)[errno(%d):%s] \n",ret, errno, strerror(errno));
        Result = MFALSE;
		goto EXIT;
    }
    android_atomic_dec(&mLocal_InitCount);
    //
#else
    ///IMEM_DBG("mInitCount(%d)",mInitCount);  
    // More than one user
    android_atomic_dec(&mInitCount);
    //IMEM_INF("-flag2- mInitCount(%d)\n",mInitCount);
#endif    
    IMEM_INF("mInitCount(%d),mLocal_InitCount(%d)\n",mInitCount,mLocal_InitCount);

#if defined (__ISP_USE_PMEM__)
    //
#elif defined (__ISP_USE_STD_M4U__) || defined (__ISP_USE_ION__)
    //////////////////////////////////////////////////////
    // we delete m4udrv and close ion device when local count is 1,
    // and unconfig m4v ports when global count is 1
    if ( mLocal_InitCount <= 0 ) 
	{
       #if defined (__ISP_USE_ION__)
	      // we have to handle local ion drv here
          // if process A open ionID, then process B open ionID before process A call ImemDrv_uninit,
          // process A would not do close ionID.
          if (mIonDrv)  
          {
		    IMEM_INF("close ion id(%d).\n", mIonDrv);
            ion_close(mIonDrv);
          }
	   #endif
	   //IMEM_INF("-!!!- mInitCount(%d)\n", mInitCount);
	   //if(mInitCount<=0)
       {
           IMEM_INF("disable config dma port using mva");
           M4U_PORT_STRUCT port;
           port.Virtuality = 0;
           port.Security = 0;
           port.domain = 3;
           port.Distance = 1;
           port.Direction = 0; //M4U_DMA_READ_WRITE
           //
	      port.ePortID = M4U_PORT_CAM_IMGO;
          ret = mpM4UDrv->m4u_config_port(&port);

	      port.ePortID = M4U_PORT_CAM_IMG2O;
          ret = mpM4UDrv->m4u_config_port(&port);

	      port.ePortID = M4U_PORT_CAM_LSCI;
          ret = mpM4UDrv->m4u_config_port(&port);

	      port.ePortID = M4U_PORT_CAM_IMGI;
          ret = mpM4UDrv->m4u_config_port(&port);

	      port.ePortID = M4U_PORT_CAM_ESFKO;
          ret = mpM4UDrv->m4u_config_port(&port);

	      port.ePortID = M4U_PORT_CAM_AAO;
          ret = mpM4UDrv->m4u_config_port(&port);
       }
	   delete mpM4UDrv;
       mpM4UDrv = NULL;
    }
#endif

    EXIT:

#if defined(_use_kernel_ref_cnt_)    
    //local ==0, global !=0 del m4u object only
    if ( mLocal_InitCount <= 0 ) {
        if ( mIspFd >= 0 ) {
            close(mIspFd);
            mIspFd = -1;
            IMEM_DBG("mIspFd(%d)",mIspFd);            
        }
    }
#endif
    return Result;
}
int FlashlightDrv::init(unsigned long sensorDev)
{
	DRV_DBG("init line=%d",__LINE__);
    int err = 0;
    unsigned long flashlightIdx = 0; //default dummy driver


    //MHAL_LOG("[halSTROBEInit]: %s \n\n", __TIME__);
    DRV_DBG("[init] mUsers = %d\n", mUsers);
    Mutex::Autolock lock(mLock);

	int preSensorDev;
    preSensorDev = m_sensorDev;
	m_sensorDev = sensorDev;

	int bOpenTest=1;
    if(m_bTempInit==1)
    {
		if(preSensorDev==m_sensorDev)
        {
	        android_atomic_dec(&mUsers);
	        bOpenTest=0;
	    }
    	else
    	{
    		uninitNoLock();
    	}
        m_bTempInit=0;
    }

    if (mUsers == 0 && bOpenTest==1)
    {
        if (m_fdSTROBE == -1)
        {
        	 int ta;
        	 int tb;
        		ta = getMs();

            m_fdSTROBE = open(STROBE_DEV_NAME, O_RDWR);

            tb = getMs();



            DRV_DBG("[init] m_fdSTROBE = %d t=%d\n", m_fdSTROBE,tb-ta);

            if (m_fdSTROBE < 0)
            {
                DRV_ERR("error opening %s: %s", STROBE_DEV_NAME, strerror(errno));
                 return StrobeDrv::STROBE_UNKNOWN_ERROR;
            }

            //set flashlight driver
            DRV_DBG("[init] sensorDev = %ld\n", sensorDev);

            err = ioctl(m_fdSTROBE,FLASHLIGHTIOC_X_SET_DRIVER,sensorDev);
            if (err < 0)
            {
                DRV_ERR("FLASHLIGHTIOC_X_SET_DRIVER error\n");
                return err ;
            }
            m_isOn=0;
            m_duty=0;
    		m_step=0;
            m_preOnTime=-1;
        }
    }
    android_atomic_inc(&mUsers);
    return StrobeDrv::STROBE_NO_ERROR;
}
static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
{
    android_atomic_dec(&gNumProxyRefs);
    JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
    env->DeleteGlobalRef((jobject)obj);
}
Exemplo n.º 25
0
bool FastThread::threadLoop()
{
    for (;;) {

        // either nanosleep, sched_yield, or busy wait
        if (sleepNs >= 0) {
            if (sleepNs > 0) {
                ALOG_ASSERT(sleepNs < 1000000000);
                const struct timespec req = {0, sleepNs};
                nanosleep(&req, NULL);
            } else {
                sched_yield();
            }
        }
        // default to long sleep for next cycle
        sleepNs = FAST_DEFAULT_NS;

        // poll for state change
        const FastThreadState *next = poll();
        if (next == NULL) {
            // continue to use the default initial state until a real state is available
            // FIXME &initial not available, should save address earlier
            //ALOG_ASSERT(current == &initial && previous == &initial);
            next = current;
        }

        command = next->mCommand;
        if (next != current) {

            // As soon as possible of learning of a new dump area, start using it
            dumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
            logWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &dummyLogWriter;
            setLog(logWriter);

            // We want to always have a valid reference to the previous (non-idle) state.
            // However, the state queue only guarantees access to current and previous states.
            // So when there is a transition from a non-idle state into an idle state, we make a
            // copy of the last known non-idle state so it is still available on return from idle.
            // The possible transitions are:
            //  non-idle -> non-idle    update previous from current in-place
            //  non-idle -> idle        update previous from copy of current
            //  idle     -> idle        don't update previous
            //  idle     -> non-idle    don't update previous
            if (!(current->mCommand & FastThreadState::IDLE)) {
                if (command & FastThreadState::IDLE) {
                    onIdle();
                    oldTsValid = false;
#ifdef FAST_MIXER_STATISTICS
                    oldLoadValid = false;
#endif
                    ignoreNextOverrun = true;
                }
                previous = current;
            }
            current = next;
        }
#if !LOG_NDEBUG
        next = NULL;    // not referenced again
#endif

        dumpState->mCommand = command;

        // << current, previous, command, dumpState >>

        switch (command) {
        case FastThreadState::INITIAL:
        case FastThreadState::HOT_IDLE:
            sleepNs = FAST_HOT_IDLE_NS;
            continue;
        case FastThreadState::COLD_IDLE:
            // only perform a cold idle command once
            // FIXME consider checking previous state and only perform if previous != COLD_IDLE
            if (current->mColdGen != coldGen) {
                int32_t *coldFutexAddr = current->mColdFutexAddr;
                ALOG_ASSERT(coldFutexAddr != NULL);
                int32_t old = android_atomic_dec(coldFutexAddr);
                if (old <= 0) {
                    syscall(__NR_futex, coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);
                }
                int policy = sched_getscheduler(0);
                if (!(policy == SCHED_FIFO || policy == SCHED_RR)) {
                    ALOGE("did not receive expected priority boost");
                }
                // This may be overly conservative; there could be times that the normal mixer
                // requests such a brief cold idle that it doesn't require resetting this flag.
                isWarm = false;
                measuredWarmupTs.tv_sec = 0;
                measuredWarmupTs.tv_nsec = 0;
                warmupCycles = 0;
                sleepNs = -1;
                coldGen = current->mColdGen;
#ifdef FAST_MIXER_STATISTICS
                bounds = 0;
                full = false;
#endif
                oldTsValid = !clock_gettime(CLOCK_MONOTONIC, &oldTs);
                timestampStatus = INVALID_OPERATION;
            } else {
                sleepNs = FAST_HOT_IDLE_NS;
            }
            continue;
        case FastThreadState::EXIT:
            onExit();
            return false;
        default:
            LOG_ALWAYS_FATAL_IF(!isSubClassCommand(command));
            break;
        }

        // there is a non-idle state available to us; did the state change?
        if (current != previous) {
            onStateChange();
#if 1   // FIXME shouldn't need this
            // only process state change once
            previous = current;
#endif
        }

        // do work using current state here
        attemptedWrite = false;
        onWork();

        // To be exactly periodic, compute the next sleep time based on current time.
        // This code doesn't have long-term stability when the sink is non-blocking.
        // FIXME To avoid drift, use the local audio clock or watch the sink's fill status.
        struct timespec newTs;
        int rc = clock_gettime(CLOCK_MONOTONIC, &newTs);
        if (rc == 0) {
            //logWriter->logTimestamp(newTs);
            if (oldTsValid) {
                time_t sec = newTs.tv_sec - oldTs.tv_sec;
                long nsec = newTs.tv_nsec - oldTs.tv_nsec;
                ALOGE_IF(sec < 0 || (sec == 0 && nsec < 0),
                        "clock_gettime(CLOCK_MONOTONIC) failed: was %ld.%09ld but now %ld.%09ld",
                        oldTs.tv_sec, oldTs.tv_nsec, newTs.tv_sec, newTs.tv_nsec);
                if (nsec < 0) {
                    --sec;
                    nsec += 1000000000;
                }
                // To avoid an initial underrun on fast tracks after exiting standby,
                // do not start pulling data from tracks and mixing until warmup is complete.
                // Warmup is considered complete after the earlier of:
                //      MIN_WARMUP_CYCLES write() attempts and last one blocks for at least warmupNs
                //      MAX_WARMUP_CYCLES write() attempts.
                // This is overly conservative, but to get better accuracy requires a new HAL API.
                if (!isWarm && attemptedWrite) {
                    measuredWarmupTs.tv_sec += sec;
                    measuredWarmupTs.tv_nsec += nsec;
                    if (measuredWarmupTs.tv_nsec >= 1000000000) {
                        measuredWarmupTs.tv_sec++;
                        measuredWarmupTs.tv_nsec -= 1000000000;
                    }
                    ++warmupCycles;
                    if ((nsec > warmupNs && warmupCycles >= MIN_WARMUP_CYCLES) ||
                            (warmupCycles >= MAX_WARMUP_CYCLES)) {
                        isWarm = true;
                        dumpState->mMeasuredWarmupTs = measuredWarmupTs;
                        dumpState->mWarmupCycles = warmupCycles;
                    }
                }
                sleepNs = -1;
                if (isWarm) {
                    if (sec > 0 || nsec > underrunNs) {
                        ATRACE_NAME("underrun");
                        // FIXME only log occasionally
                        ALOGV("underrun: time since last cycle %d.%03ld sec",
                                (int) sec, nsec / 1000000L);
                        dumpState->mUnderruns++;
                        ignoreNextOverrun = true;
                    } else if (nsec < overrunNs) {
                        if (ignoreNextOverrun) {
                            ignoreNextOverrun = false;
                        } else {
                            // FIXME only log occasionally
                            ALOGV("overrun: time since last cycle %d.%03ld sec",
                                    (int) sec, nsec / 1000000L);
                            dumpState->mOverruns++;
                        }
                        // This forces a minimum cycle time. It:
                        //  - compensates for an audio HAL with jitter due to sample rate conversion
                        //  - works with a variable buffer depth audio HAL that never pulls at a
                        //    rate < than overrunNs per buffer.
                        //  - recovers from overrun immediately after underrun
                        // It doesn't work with a non-blocking audio HAL.
                        sleepNs = forceNs - nsec;
                    } else {
                        ignoreNextOverrun = false;
                    }
                }
#ifdef FAST_MIXER_STATISTICS
                if (isWarm) {
                    // advance the FIFO queue bounds
                    size_t i = bounds & (dumpState->mSamplingN - 1);
                    bounds = (bounds & 0xFFFF0000) | ((bounds + 1) & 0xFFFF);
                    if (full) {
                        bounds += 0x10000;
                    } else if (!(bounds & (dumpState->mSamplingN - 1))) {
                        full = true;
                    }
                    // compute the delta value of clock_gettime(CLOCK_MONOTONIC)
                    uint32_t monotonicNs = nsec;
                    if (sec > 0 && sec < 4) {
                        monotonicNs += sec * 1000000000;
                    }
                    // compute raw CPU load = delta value of clock_gettime(CLOCK_THREAD_CPUTIME_ID)
                    uint32_t loadNs = 0;
                    struct timespec newLoad;
                    rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &newLoad);
                    if (rc == 0) {
                        if (oldLoadValid) {
                            sec = newLoad.tv_sec - oldLoad.tv_sec;
                            nsec = newLoad.tv_nsec - oldLoad.tv_nsec;
                            if (nsec < 0) {
                                --sec;
                                nsec += 1000000000;
                            }
                            loadNs = nsec;
                            if (sec > 0 && sec < 4) {
                                loadNs += sec * 1000000000;
                            }
                        } else {
                            // first time through the loop
                            oldLoadValid = true;
                        }
                        oldLoad = newLoad;
                    }
#ifdef CPU_FREQUENCY_STATISTICS
                    // get the absolute value of CPU clock frequency in kHz
                    int cpuNum = sched_getcpu();
                    uint32_t kHz = tcu.getCpukHz(cpuNum);
                    kHz = (kHz << 4) | (cpuNum & 0xF);
#endif
                    // save values in FIFO queues for dumpsys
                    // these stores #1, #2, #3 are not atomic with respect to each other,
                    // or with respect to store #4 below
                    dumpState->mMonotonicNs[i] = monotonicNs;
                    dumpState->mLoadNs[i] = loadNs;
#ifdef CPU_FREQUENCY_STATISTICS
                    dumpState->mCpukHz[i] = kHz;
#endif
                    // this store #4 is not atomic with respect to stores #1, #2, #3 above, but
                    // the newest open & oldest closed halves are atomic with respect to each other
                    dumpState->mBounds = bounds;
                    ATRACE_INT("cycle_ms", monotonicNs / 1000000);
                    ATRACE_INT("load_us", loadNs / 1000);
                }
#endif
            } else {
                // first time through the loop
                oldTsValid = true;
                sleepNs = periodNs;
                ignoreNextOverrun = true;
            }
            oldTs = newTs;
        } else {
            // monotonic clock is broken
            oldTsValid = false;
            sleepNs = periodNs;
        }

    }   // for (;;)

    // never return 'true'; Thread::_threadLoop() locks mutex which can result in priority inversion
}
Exemplo n.º 26
0
status_t AudioFlinger::ReadLLBTCommand()
{   
    ALOGD("AudioFlinger::ReadLosslessBTCommand()");

    char value[PROPERTY_VALUE_MAX];
    mIsLosslessBTOn = (property_get(LOSSLESS_BT_PROP_NAME, value, "0") > 0) && (atoi(value) == 1);
    SetLosslessBTStatus(mIsLosslessBTOn);

    mIsLosslessBTVolumeSatisfied = false;
    mIsLosslessBTPlaying = false;
    mIsLosslessBTWorking = false;
    mIsLosslessBTSupport = false;
    mIsLosslessBTAbsoluteVolume = false;
    mIsLosslessBTVaild = 1;
    
    int error_count = 0;

    //waiting for boot
    while(!isBootComplete()){
        ALOGD("boot_completed NOT READY, sleep 1s");
        usleep(1000*1000);
    }

    while(1){
        int new_status = false;
        const char *cmd;

        ALOGD("On:%d, Support:%d, VolumeSatisfied:%d, Playing:%d, Working:%d, valid %d", 
                 mIsLosslessBTOn, mIsLosslessBTSupport, mIsLosslessBTVolumeSatisfied,
                 mIsLosslessBTPlaying, mIsLosslessBTWorking, mIsLosslessBTVaild);

        if(mIsLosslessBTVaild <= 0){
            ALOGD("mIsLosslessBTVaild<=0");
            mLLBroadcastMutex.lock();
            mLLWaitWorkCV.wait(mLLBroadcastMutex);
            mLLBroadcastMutex.unlock();
            ALOGD("mLLWaitWorkCV.wait(mLLBroadcastMutex) DONE");
            continue;
        }

        if(mIsLosslessBTOn){
            if(mIsLosslessBTSupport){
                if(mIsLosslessBTVolumeSatisfied || mIsLosslessBTAbsoluteVolume){
                    cmd = LOSSLESS_BT_UI_CMD_PLAYING;
                    new_status = true;
                }else{
                    cmd = LOSSLESS_BT_UI_CMD_STOP;                
                }
            }else{
                cmd = LOSSLESS_BT_UI_CMD_NOT_SUPPORT;
            }    
        }else{
            cmd = LOSSLESS_BT_UI_CMD_CLOSE;
        }

        bool result = sendBroadcastMessage(String16(cmd), 1);
        ALOGD("run: %s, result=%d", cmd, result);
        if(result){
            error_count = 0;
            if(new_status != mIsLosslessBTWorking)
            {
                RestartAudioPlayer(new_status);
                mIsLosslessBTWorking = new_status;
                ALOGD("mIsLosslessBTWorking = %d", mIsLosslessBTWorking);
            }
        }else{
            if(++error_count > LOSSLSSS_BT_FAILED_MAX){
                ALOGE("LosslessBT::ReadLLBTCommand AM broadcasting failed");
                error_count = 0;
            }else{
                usleep(1000*1000);
                continue;
            }
        }

        int new_vaild_value = android_atomic_dec(&mIsLosslessBTVaild);
        ALOGD("android_atomic_dec(&mIsLosslessBTVaild) = %d", new_vaild_value);
    }
    
    return NO_ERROR;
}
Exemplo n.º 27
0
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
    if (mQueuedFrames > 0) {
        // Capture the old state of the layer for comparisons later
        const bool oldOpacity = isOpaque();
        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;

        // signal another event if we have more frames pending
        if (android_atomic_dec(&mQueuedFrames) > 1) {
            mFlinger->signalEvent();
        }

        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
            // something happened!
            recomputeVisibleRegions = true;
            return;
        }

        // update the active buffer
        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
		hasmixed=false;
        const Rect crop(mSurfaceTexture->getCurrentCrop());
        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
        if ((crop != mCurrentCrop) ||
            (transform != mCurrentTransform) ||
            (scalingMode != mCurrentScalingMode))
        {
            mCurrentCrop = crop;
            mCurrentTransform = transform;
            mCurrentScalingMode = scalingMode;
            mFlinger->invalidateHwcGeometry();
        }

        GLfloat textureMatrix[16];
        mSurfaceTexture->getTransformMatrix(textureMatrix);
        if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) {
            memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix));
            mFlinger->invalidateHwcGeometry();
        }

        uint32_t bufWidth  = mActiveBuffer->getWidth();
        uint32_t bufHeight = mActiveBuffer->getHeight();
        if (oldActiveBuffer != NULL) {
            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
                bufHeight != uint32_t(oldActiveBuffer->height)) {
                mFlinger->invalidateHwcGeometry();
            }
        }

        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
        if (oldOpacity != isOpaque()) {
            recomputeVisibleRegions = true;
        }

        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // update the layer size if needed
        const Layer::State& front(drawingState());

        // FIXME: mPostedDirtyRegion = dirty & bounds
        mPostedDirtyRegion.set(front.w, front.h);

        if ((front.w != front.requested_w) ||
            (front.h != front.requested_h))
        {
            // check that we received a buffer of the right size
            // (Take the buffer's orientation into account)
            if (mCurrentTransform & Transform::ROT_90) {
                swap(bufWidth, bufHeight);
            }

            if (isFixedSize() ||
                    (bufWidth == front.requested_w &&
                    bufHeight == front.requested_h))
            {
                // Here we pretend the transaction happened by updating the
                // current and drawing states. Drawing state is only accessed
                // in this thread, no need to have it locked
                Layer::State& editDraw(mDrawingState);
                editDraw.w = editDraw.requested_w;
                editDraw.h = editDraw.requested_h;

                // We also need to update the current state so that we don't
                // end-up doing too much work during the next transaction.
                // NOTE: We actually don't need hold the transaction lock here
                // because State::w and State::h are only accessed from
                // this thread
                Layer::State& editTemp(currentState());
                editTemp.w = editDraw.w;
                editTemp.h = editDraw.h;

                // recompute visible region
                recomputeVisibleRegions = true;
            }

            LOGD_IF(DEBUG_RESIZE,
                    "lockPageFlip : "
                    "       (layer=%p), buffer (%ux%u, tr=%02x), "
                    "requested (%dx%d)",
                    this,
                    bufWidth, bufHeight, mCurrentTransform,
                    front.requested_w, front.requested_h);
        }
    }
}
Exemplo n.º 28
0
void Assembly::decStrong(const void*) const
{
    if (android_atomic_dec(&mCount) == 1) {
        delete this;
    }
}
Exemplo n.º 29
0
Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
    ATRACE_CALL();

    Region outDirtyRegion;
    if (mQueuedFrames > 0) {

        // if we've already called updateTexImage() without going through
        // a composition step, we have to skip this layer at this point
        // because we cannot call updateTeximage() without a corresponding
        // compositionComplete() call.
        // we'll trigger an update in onPreComposition().
        if (mRefreshPending) {
            return outDirtyRegion;
        }

        // Capture the old state of the layer for comparisons later
        const bool oldOpacity = isOpaque();
        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;

        // signal another event if we have more frames pending
        if (android_atomic_dec(&mQueuedFrames) > 1) {
            mFlinger->signalLayerUpdate();
        }

        struct Reject : public SurfaceTexture::BufferRejecter {
            Layer::State& front;
            Layer::State& current;
            bool& recomputeVisibleRegions;
            Reject(Layer::State& front, Layer::State& current,
                    bool& recomputeVisibleRegions)
                : front(front), current(current),
                  recomputeVisibleRegions(recomputeVisibleRegions) {
            }

            virtual bool reject(const sp<GraphicBuffer>& buf,
                    const BufferQueue::BufferItem& item) {
                if (buf == NULL) {
                    return false;
                }

                uint32_t bufWidth  = buf->getWidth();
                uint32_t bufHeight = buf->getHeight();

                // check that we received a buffer of the right size
                // (Take the buffer's orientation into account)
                if (item.mTransform & Transform::ROT_90) {
                    swap(bufWidth, bufHeight);
                }


                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
                if (front.active != front.requested) {

                    if (isFixedSize ||
                            (bufWidth == front.requested.w &&
                             bufHeight == front.requested.h))
                    {
                        // Here we pretend the transaction happened by updating the
                        // current and drawing states. Drawing state is only accessed
                        // in this thread, no need to have it locked
                        front.active = front.requested;

                        // We also need to update the current state so that
                        // we don't end-up overwriting the drawing state with
                        // this stale current state during the next transaction
                        //
                        // NOTE: We don't need to hold the transaction lock here
                        // because State::active is only accessed from this thread.
                        current.active = front.active;

                        // recompute visible region
                        recomputeVisibleRegions = true;
                    }

                    ALOGD_IF(DEBUG_RESIZE,
                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
                            front.active.w, front.active.h,
                            front.active.crop.left,
                            front.active.crop.top,
                            front.active.crop.right,
                            front.active.crop.bottom,
                            front.active.crop.getWidth(),
                            front.active.crop.getHeight(),
                            front.requested.w, front.requested.h,
                            front.requested.crop.left,
                            front.requested.crop.top,
                            front.requested.crop.right,
                            front.requested.crop.bottom,
                            front.requested.crop.getWidth(),
                            front.requested.crop.getHeight());
                }

                if (!isFixedSize) {
                    if (front.active.w != bufWidth ||
                        front.active.h != bufHeight) {
                        // reject this buffer
                        return true;
                    }
                }
                return false;
            }
        };


        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);

#ifndef STE_HARDWARE
        if (mSurfaceTexture->updateTexImage(&r, true) < NO_ERROR) {
#else
        if (mSurfaceTexture->updateTexImage(&r, true, true) < NO_ERROR) {
#endif
            // something happened!
            recomputeVisibleRegions = true;
            return outDirtyRegion;
        }

        // update the active buffer
        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
        if (mActiveBuffer == NULL) {
            // this can only happen if the very first buffer was rejected.
            return outDirtyRegion;
        }

        mRefreshPending = true;
        mFrameLatencyNeeded = true;
        if (oldActiveBuffer == NULL) {
             // the first time we receive a buffer, we need to trigger a
             // geometry invalidation.
            recomputeVisibleRegions = true;
         }

        Rect crop(mSurfaceTexture->getCurrentCrop());
        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
        if ((crop != mCurrentCrop) ||
            (transform != mCurrentTransform) ||
            (scalingMode != mCurrentScalingMode))
        {
            mCurrentCrop = crop;
            mCurrentTransform = transform;
            mCurrentScalingMode = scalingMode;
            recomputeVisibleRegions = true;
        }

        if (oldActiveBuffer != NULL) {
            uint32_t bufWidth  = mActiveBuffer->getWidth();
            uint32_t bufHeight = mActiveBuffer->getHeight();
            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
                bufHeight != uint32_t(oldActiveBuffer->height)) {
                recomputeVisibleRegions = true;
            }
        }

        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
        if (oldOpacity != isOpaque()) {
            recomputeVisibleRegions = true;
        }

        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // FIXME: postedRegion should be dirty & bounds
        const Layer::State& front(drawingState());
        Region dirtyRegion(Rect(front.active.w, front.active.h));

        // transform the dirty region to window-manager space
        outDirtyRegion = (front.transform.transform(dirtyRegion));
    }
    return outDirtyRegion;
}

void Layer::dump(String8& result, char* buffer, size_t SIZE) const
{
    LayerBaseClient::dump(result, buffer, SIZE);

    sp<const GraphicBuffer> buf0(mActiveBuffer);
    uint32_t w0=0, h0=0, s0=0, f0=0;
    if (buf0 != 0) {
        w0 = buf0->getWidth();
        h0 = buf0->getHeight();
        s0 = buf0->getStride();
        f0 = buf0->format;
    }
    snprintf(buffer, SIZE,
            "      "
            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
            " queued-frames=%d, mRefreshPending=%d\n",
            mFormat, w0, h0, s0,f0,
            mQueuedFrames, mRefreshPending);

    result.append(buffer);

    if (mSurfaceTexture != 0) {
        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
    }
}
Exemplo n.º 30
0
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
    ATRACE_CALL();

    if (mQueuedFrames > 0) {

        // if we've already called updateTexImage() without going through
        // a composition step, we have to skip this layer at this point
        // because we cannot call updateTeximage() without a corresponding
        // compositionComplete() call.
        // we'll trigger an update in onPreComposition().
        if (mRefreshPending) {
            mPostedDirtyRegion.clear();
            return;
        }

        // Capture the old state of the layer for comparisons later
        const bool oldOpacity = isOpaque();
        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;

        // signal another event if we have more frames pending
        if (android_atomic_dec(&mQueuedFrames) > 1) {
            mFlinger->signalLayerUpdate();
        }

        struct Reject : public SurfaceTexture::BufferRejecter {
            Layer::State& front;
            Layer::State& current;
            bool& recomputeVisibleRegions;
            Reject(Layer::State& front, Layer::State& current,
                    bool& recomputeVisibleRegions)
                : front(front), current(current),
                  recomputeVisibleRegions(recomputeVisibleRegions) {
            }

            virtual bool reject(const sp<GraphicBuffer>& buf,
                    const BufferQueue::BufferItem& item) {
                if (buf == NULL) {
                    return false;
                }

                uint32_t bufWidth  = buf->getWidth();
                uint32_t bufHeight = buf->getHeight();

                // check that we received a buffer of the right size
                // (Take the buffer's orientation into account)
                if (item.mTransform & Transform::ROT_90) {
                    swap(bufWidth, bufHeight);
                }


                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
                if (front.active != front.requested) {

                    if (isFixedSize ||
                            (bufWidth == front.requested.w &&
                             bufHeight == front.requested.h))
                    {
                        // Here we pretend the transaction happened by updating the
                        // current and drawing states. Drawing state is only accessed
                        // in this thread, no need to have it locked
                        front.active = front.requested;

                        // We also need to update the current state so that
                        // we don't end-up overwriting the drawing state with
                        // this stale current state during the next transaction
                        //
                        // NOTE: We don't need to hold the transaction lock here
                        // because State::active is only accessed from this thread.
                        current.active = front.active;

                        // recompute visible region
                        recomputeVisibleRegions = true;
                    }

                    ALOGD_IF(DEBUG_RESIZE,
                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
                            front.active.w, front.active.h,
                            front.active.crop.left,
                            front.active.crop.top,
                            front.active.crop.right,
                            front.active.crop.bottom,
                            front.active.crop.getWidth(),
                            front.active.crop.getHeight(),
                            front.requested.w, front.requested.h,
                            front.requested.crop.left,
                            front.requested.crop.top,
                            front.requested.crop.right,
                            front.requested.crop.bottom,
                            front.requested.crop.getWidth(),
                            front.requested.crop.getHeight());
                }

                if (!isFixedSize) {
                    if (front.active.w != bufWidth ||
                        front.active.h != bufHeight) {
                        // reject this buffer
                        return true;
                    }
                }
                return false;
            }
        };


        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);

#ifdef DECIDE_TEXTURE_TARGET
        // While calling updateTexImage() from SurfaceFlinger, let it know
        // by passing an extra parameter
        // This will be true always.

        bool isComposition = true;

        if (mSurfaceTexture->updateTexImage(&r, isComposition) < NO_ERROR) {
#else
        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
#endif
            // something happened!
            recomputeVisibleRegions = true;
            return;
        }

        // update the active buffer
        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
        if (mActiveBuffer == NULL) {
            // this can only happen if the very first buffer was rejected.
            return;
        }

        mRefreshPending = true;
        mFrameLatencyNeeded = true;
        if (oldActiveBuffer == NULL) {
             // the first time we receive a buffer, we need to trigger a
             // geometry invalidation.
             mFlinger->invalidateHwcGeometry();
         }

        Rect crop(mSurfaceTexture->getCurrentCrop());
        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
        if ((crop != mCurrentCrop) ||
            (transform != mCurrentTransform) ||
            (scalingMode != mCurrentScalingMode))
        {
            mCurrentCrop = crop;
            mCurrentTransform = transform;
            mCurrentScalingMode = scalingMode;
            mFlinger->invalidateHwcGeometry();
        }

        if (oldActiveBuffer != NULL) {
            uint32_t bufWidth  = mActiveBuffer->getWidth();
            uint32_t bufHeight = mActiveBuffer->getHeight();
            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
                bufHeight != uint32_t(oldActiveBuffer->height)) {
                mFlinger->invalidateHwcGeometry();
            }
        }

        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
        if (oldOpacity != isOpaque()) {
            recomputeVisibleRegions = true;
        }

        // FIXME: mPostedDirtyRegion = dirty & bounds
        const Layer::State& front(drawingState());
        mPostedDirtyRegion.set(front.active.w, front.active.h);

        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    }
}

void Layer::unlockPageFlip(
        const Transform& planeTransform, Region& outDirtyRegion)
{
    ATRACE_CALL();

    Region postedRegion(mPostedDirtyRegion);
    if (!postedRegion.isEmpty()) {
        mPostedDirtyRegion.clear();
        if (!visibleRegionScreen.isEmpty()) {
            // The dirty region is given in the layer's coordinate space
            // transform the dirty region by the surface's transformation
            // and the global transformation.
            const Layer::State& s(drawingState());
            const Transform tr(planeTransform * s.transform);
            postedRegion = tr.transform(postedRegion);

            // At this point, the dirty region is in screen space.
            // Make sure it's constrained by the visible region (which
            // is in screen space as well).
            postedRegion.andSelf(visibleRegionScreen);
            outDirtyRegion.orSelf(postedRegion);
        }
    }
}