diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/audioflinger/AudioFlinger.cpp | 203 | ||||
-rw-r--r-- | libs/rs/rsContext.cpp | 4 | ||||
-rw-r--r-- | libs/rs/rsScriptC_Lib.cpp | 14 | ||||
-rw-r--r-- | libs/surfaceflinger/Layer.cpp | 4 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.cpp | 21 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.h | 3 | ||||
-rw-r--r-- | libs/utils/ResourceTypes.cpp | 12 |
7 files changed, 154 insertions, 107 deletions
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp index e534447..6500791 100644 --- a/libs/audioflinger/AudioFlinger.cpp +++ b/libs/audioflinger/AudioFlinger.cpp @@ -1227,44 +1227,46 @@ bool AudioFlinger::MixerThread::threadLoop() enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove); } - - // output audio to hardware - if (mSuspended) { - usleep(kMaxBufferRecoveryInUsecs); + if (LIKELY(enabledTracks)) { + // mix buffers... + mAudioMixer->process(curBuf); + sleepTime = 0; + standbyTime = systemTime() + kStandbyTimeInNsecs; } else { - if (LIKELY(enabledTracks)) { - // mix buffers... - mAudioMixer->process(curBuf); + sleepTime += kBufferRecoveryInUsecs; + if (sleepTime > kMaxBufferRecoveryInUsecs) { + sleepTime = kMaxBufferRecoveryInUsecs; + } + // There was nothing to mix this round, which means all + // active tracks were late. Sleep a little bit to give + // them another chance. If we're too late, write 0s to audio + // hardware to avoid underrun. + if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) { + memset (curBuf, 0, mixBufferSize); sleepTime = 0; - standbyTime = systemTime() + kStandbyTimeInNsecs; - } else { - sleepTime += kBufferRecoveryInUsecs; - // There was nothing to mix this round, which means all - // active tracks were late. Sleep a little bit to give - // them another chance. If we're too late, write 0s to audio - // hardware to avoid underrun. - if (mBytesWritten == 0 || sleepTime < kMaxBufferRecoveryInUsecs) { - usleep(kBufferRecoveryInUsecs); - } else { - memset (curBuf, 0, mixBufferSize); - sleepTime = 0; - } } - // sleepTime == 0 means PCM data were written to mMixBuffer[] - if (sleepTime == 0) { - mLastWriteTime = systemTime(); - mInWrite = true; - int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize); - if (bytesWritten > 0) mBytesWritten += bytesWritten; - mNumWrites++; - mInWrite = false; - mStandby = false; - nsecs_t delta = systemTime() - mLastWriteTime; - if (delta > maxPeriod) { - LOGW("write blocked for %llu msecs", ns2ms(delta)); - mNumDelayedWrites++; - } + } + + if (mSuspended) { + sleepTime = kMaxBufferRecoveryInUsecs; + } + // sleepTime == 0 means we must write to audio hardware + if (sleepTime == 0) { + mLastWriteTime = systemTime(); + mInWrite = true; + LOGV("mOutput->write() thread %p frames %d", this, mFrameCount); + int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize); + if (bytesWritten > 0) mBytesWritten += bytesWritten; + mNumWrites++; + mInWrite = false; + mStandby = false; + nsecs_t delta = systemTime() - mLastWriteTime; + if (delta > maxPeriod) { + LOGW("write blocked for %llu msecs, thread %p", ns2ms(delta), this); + mNumDelayedWrites++; } + } else { + usleep(sleepTime); } // finally let go of all our tracks, without the lock held @@ -1718,50 +1720,55 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } } - // output audio to hardware - if (mSuspended) { - usleep(kMaxBufferRecoveryInUsecs); - } else { - if (activeTrack != 0) { - AudioBufferProvider::Buffer buffer; - size_t frameCount = mFrameCount; - curBuf = (int8_t *)mMixBuffer; - // output audio to hardware - while(frameCount) { - buffer.frameCount = frameCount; - activeTrack->getNextBuffer(&buffer); - if (UNLIKELY(buffer.raw == 0)) { - memset(curBuf, 0, frameCount * mFrameSize); - break; - } - memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize); - frameCount -= buffer.frameCount; - curBuf += buffer.frameCount * mFrameSize; - activeTrack->releaseBuffer(&buffer); + if (activeTrack != 0) { + AudioBufferProvider::Buffer buffer; + size_t frameCount = mFrameCount; + curBuf = (int8_t *)mMixBuffer; + // output audio to hardware + while(frameCount) { + buffer.frameCount = frameCount; + activeTrack->getNextBuffer(&buffer); + if (UNLIKELY(buffer.raw == 0)) { + memset(curBuf, 0, frameCount * mFrameSize); + break; } + memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize); + frameCount -= buffer.frameCount; + curBuf += buffer.frameCount * mFrameSize; + activeTrack->releaseBuffer(&buffer); + } + sleepTime = 0; + standbyTime = systemTime() + kStandbyTimeInNsecs; + } else { + sleepTime += kBufferRecoveryInUsecs; + if (sleepTime > kMaxBufferRecoveryInUsecs) { + sleepTime = kMaxBufferRecoveryInUsecs; + } + // There was nothing to mix this round, which means all + // active tracks were late. Sleep a little bit to give + // them another chance. If we're too late, write 0s to audio + // hardware to avoid underrun. + if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs && + AudioSystem::isLinearPCM(mFormat)) { + memset (mMixBuffer, 0, mFrameCount * mFrameSize); sleepTime = 0; - standbyTime = systemTime() + kStandbyTimeInNsecs; - } else { - sleepTime += kBufferRecoveryInUsecs; - if (mBytesWritten == 0 || !AudioSystem::isLinearPCM(mFormat) || - sleepTime < kMaxBufferRecoveryInUsecs) { - usleep(kBufferRecoveryInUsecs); - } else { - memset (mMixBuffer, 0, mFrameCount * mFrameSize); - sleepTime = 0; - } } + } - // sleepTime == 0 means PCM data were written to mMixBuffer[] - if (sleepTime == 0) { - mLastWriteTime = systemTime(); - mInWrite = true; - int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize); - if (bytesWritten) mBytesWritten += bytesWritten; - mNumWrites++; - mInWrite = false; - mStandby = false; - } + if (mSuspended) { + sleepTime = kMaxBufferRecoveryInUsecs; + } + // sleepTime == 0 means we must write to audio hardware + if (sleepTime == 0) { + mLastWriteTime = systemTime(); + mInWrite = true; + int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize); + if (bytesWritten) mBytesWritten += bytesWritten; + mNumWrites++; + mInWrite = false; + mStandby = false; + } else { + usleep(sleepTime); } // finally let go of removed track, without the lock held @@ -1913,38 +1920,40 @@ bool AudioFlinger::DuplicatingThread::threadLoop() } enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove); - } + } - bool mustSleep = true; if (LIKELY(enabledTracks)) { // mix buffers... mAudioMixer->process(curBuf); - if (!mSuspended) { - for (size_t i = 0; i < outputTracks.size(); i++) { - outputTracks[i]->write(curBuf, mFrameCount); - mustSleep = false; - } - mStandby = false; - mBytesWritten += mixBufferSize; - } + sleepTime = 0; + standbyTime = systemTime() + kStandbyTimeInNsecs; } else { - // flush remaining overflow buffers in output tracks - for (size_t i = 0; i < outputTracks.size(); i++) { - if (outputTracks[i]->isActive()) { - outputTracks[i]->write(curBuf, 0); - standbyTime = systemTime() + kStandbyTimeInNsecs; - mustSleep = false; - } + sleepTime += kBufferRecoveryInUsecs; + if (sleepTime > kMaxBufferRecoveryInUsecs) { + sleepTime = kMaxBufferRecoveryInUsecs; + } + // There was nothing to mix this round, which means all + // active tracks were late. Sleep a little bit to give + // them another chance. If we're too late, write 0s to audio + // hardware to avoid underrun. + if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) { + memset (curBuf, 0, mixBufferSize); + sleepTime = 0; } } - if (mustSleep) { -// LOGV("threadLoop() sleeping %d", sleepTime); - usleep(sleepTime); - if (sleepTime < kMaxBufferRecoveryInUsecs) { - sleepTime += kBufferRecoveryInUsecs; + + if (mSuspended) { + sleepTime = kMaxBufferRecoveryInUsecs; + } + // sleepTime == 0 means we must write to audio hardware + if (sleepTime == 0) { + for (size_t i = 0; i < outputTracks.size(); i++) { + outputTracks[i]->write(curBuf, mFrameCount); } + mStandby = false; + mBytesWritten += mixBufferSize; } else { - sleepTime = kBufferRecoveryInUsecs; + usleep(sleepTime); } // finally let go of all our tracks, without the lock held diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 04f6e07..3e4c9af 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -112,8 +112,8 @@ bool Context::runRootScript() #endif rsAssert(mRootScript->mEnviroment.mIsRoot); - //glColor4f(1,1,1,1); - //glEnable(GL_LIGHT0); + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight); glViewport(0, 0, mEGL.mWidth, mEGL.mHeight); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glEnable(GL_POINT_SMOOTH); diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index d10076b..6dc3e8b 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -321,6 +321,16 @@ static int SC_sqr(int v) return v * v; } +static float SC_fracf(float v) +{ + return v - floorf(v); +} + +static float SC_roundf(float v) +{ + return floorf(v + 0.4999999999); +} + static float SC_distf2(float x1, float y1, float x2, float y2) { float x = x2 - x1; @@ -1014,8 +1024,12 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { "float", "(float, float)" }, { "floorf", (void *)&floorf, "float", "(float)" }, + { "fracf", (void *)&SC_fracf, + "float", "(float)" }, { "ceilf", (void *)&ceilf, "float", "(float)" }, + { "roundf", (void *)&SC_roundf, + "float", "(float)" }, { "expf", (void *)&expf, "float", "(float)" }, { "logf", (void *)&logf, diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 8dfc2cf..5ff9284 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -88,7 +88,6 @@ void Layer::destroy() mBuffers[i].clear(); mWidth = mHeight = 0; } - mSurface.clear(); } sp<LayerBaseClient::Surface> Layer::createSurface() const @@ -99,7 +98,8 @@ sp<LayerBaseClient::Surface> Layer::createSurface() const status_t Layer::ditch() { // the layer is not on screen anymore. free as much resources as possible - destroy(); + //destroy(); + mSurface.clear(); return NO_ERROR; } diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index e87b563..831c446 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -1084,9 +1084,12 @@ status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) { - // remove the layer from the main list (through a transaction). + // First add the layer to the purgatory list, which makes sure it won't + // go away, then remove it from the main list (through a transaction). ssize_t err = removeLayer_l(layerBase); - + if (err >= 0) { + mLayerPurgatory.add(layerBase); + } // it's possible that we don't find a layer, because it might // have been destroyed already -- this is not technically an error // from the user because there is a race between BClient::destroySurface(), @@ -1359,8 +1362,18 @@ status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer) * to use the purgatory. */ status_t err = flinger->removeLayer_l(l); - LOGE_IF(err<0 && err != NAME_NOT_FOUND, - "error removing layer=%p (%s)", l.get(), strerror(-err)); + if (err == NAME_NOT_FOUND) { + // The surface wasn't in the current list, which means it was + // removed already, which means it is in the purgatory, + // and need to be removed from there. + // This needs to happen from the main thread since its dtor + // must run from there (b/c of OpenGL ES). Additionally, we + // can't really acquire our internal lock from + // destroySurface() -- see postMessage() below. + ssize_t idx = flinger->mLayerPurgatory.remove(l); + LOGE_IF(idx < 0, + "layer=%p is not in the purgatory list", l.get()); + } return true; } }; diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index f207f85..493e777 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -250,7 +250,9 @@ private: GraphicPlane& graphicPlane(int dpy); void waitForEvent(); +public: // hack to work around gcc 4.0.3 bug void signalEvent(); +private: void signalDelayedEvent(nsecs_t delay); void handleConsoleEvents(); @@ -312,6 +314,7 @@ private: volatile int32_t mTransactionCount; Condition mTransactionCV; bool mResizeTransationPending; + SortedVector< sp<LayerBase> > mLayerPurgatory; // protected by mStateLock (but we could use another lock) Tokenizer mTokens; diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index f80843d..a5a8cc9 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -1740,7 +1740,11 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const const int e = Res_GETENTRY(resID); if (p < 0) { - LOGW("No package identifier when getting name for resource number 0x%08x", resID); + if (Res_GETPACKAGE(resID)+1 == 0) { + LOGW("No package identifier when getting name for resource number 0x%08x", resID); + } else { + LOGW("Resources don't contain pacakge for resource number 0x%08x", resID); + } return false; } if (t < 0) { @@ -1786,7 +1790,11 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag const int e = Res_GETENTRY(resID); if (p < 0) { - LOGW("No package identifier when getting value for resource number 0x%08x", resID); + if (Res_GETPACKAGE(resID)+1 == 0) { + LOGW("No package identifier when getting name for resource number 0x%08x", resID); + } else { + LOGW("Resources don't contain pacakge for resource number 0x%08x", resID); + } return BAD_INDEX; } if (t < 0) { |