Merge "even more logging"
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 2dceab9..9d9196e 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -764,13 +764,6 @@
env->ReleaseStringChars(text, textArray);
}
- static void logGlyphs(sp<TextLayoutCacheValue> value) {
- LOGD("drawTextWithGlyphs -- got glyphs - count=%d", value->getGlyphsCount());
- for (size_t i = 0; i < value->getGlyphsCount(); i++) {
- LOGD(" glyphs[%d]=%d", i, value->getGlyphs()[i]);
- }
- }
-
static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
int start, int end,
jfloat x, jfloat y, int flags, SkPaint* paint) {
@@ -779,7 +772,7 @@
sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue(
paint, textArray, start, count, count, flags);
if (value == NULL) {
- LOGE("drawTextWithGlyphs -- cannot get Cache value");
+ LOGE("Cannot get TextLayoutCache value");
return ;
}
#if DEBUG_GLYPHS
@@ -796,7 +789,7 @@
sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue(
paint, textArray, start, count, contextCount, flags);
if (value == NULL) {
- LOGE("drawTextWithGlyphs -- cannot get Cache value");
+ LOGE("Cannot get TextLayoutCache value");
return ;
}
#if DEBUG_GLYPHS
diff --git a/core/jni/android/graphics/TextLayout.h b/core/jni/android/graphics/TextLayout.h
index 9bb1b92..d197d04 100644
--- a/core/jni/android/graphics/TextLayout.h
+++ b/core/jni/android/graphics/TextLayout.h
@@ -64,6 +64,14 @@
kDirection_Mask = 0x1
};
+static void logGlyphs(sp<TextLayoutCacheValue> value) {
+ if (value == NULL) return;
+ LOGD("Got glyphs - count=%d", value->getGlyphsCount());
+ for (size_t i = 0; i < value->getGlyphsCount(); i++) {
+ LOGD(" glyphs[%d]=%d", i, value->getGlyphs()[i]);
+ }
+}
+
class TextLayout {
public:
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index d43a27f..e539cd2 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -419,6 +419,20 @@
static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
jfloat x, jfloat y, int flags, SkPaint* paint) {
+#if 0 // TODO: replace "0" by "RTL_USE_HARFBUZZ" when renderer->drawGlyphs() is implemented
+ sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue(
+ paint, text, 0, count, count, flags);
+ if (value == NULL) {
+ LOGE("Cannot get TextLayoutCache value");
+ return ;
+ }
+#if DEBUG_GLYPHS
+ logGlyphs(value);
+#endif
+ const jchar* glyphArray = value->getGlyphs();
+ int glyphCount = value->getGlyphsCount();
+ renderer->drawGlyphs((const char*) glyphArray, 0, glyphCount << 1, x, y, paint);
+#else
const jchar *workText;
jchar* buffer = NULL;
int32_t workBytes;
@@ -426,11 +440,26 @@
renderer->drawText((const char*) workText, workBytes, count, x, y, paint);
free(buffer);
}
+#endif
}
static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
jint start, jint count, jint contextCount, jfloat x, jfloat y,
int flags, SkPaint* paint) {
+#if 0 // TODO: replace "0" by "RTL_USE_HARFBUZZ" when renderer->drawGlyphs() is implemented
+ sp<TextLayoutCacheValue> value = gTextLayoutCache.getValue(
+ paint, text, start, count, contextCount, flags);
+ if (value == NULL) {
+ LOGE("Cannot get TextLayoutCache value");
+ return ;
+ }
+#if DEBUG_GLYPHS
+ logGlyphs(value);
+#endif
+ const jchar* glyphArray = value->getGlyphs();
+ int glyphCount = value->getGlyphsCount();
+ renderer->drawGlyphs((const char*) glyphArray, 0, glyphCount << 1, x, y, paint);
+#else
uint8_t rtl = flags & 0x1;
if (rtl) {
SkAutoSTMalloc<80, jchar> buffer(contextCount);
@@ -443,6 +472,7 @@
} else {
renderer->drawText((const char*) (text + start), count << 1, count, x, y, paint);
}
+#endif
}
static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index 2774809..7b3b73f 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -320,53 +320,55 @@
return tb.create();
}
- static synchronized Mesh internalCreate(RenderScript rs, Builder b) {
-
- int id = rs.nMeshCreate(b.mVertexTypeCount, b.mIndexTypes.size());
- Mesh newMesh = new Mesh(id, rs);
- newMesh.mIndexBuffers = new Allocation[b.mIndexTypes.size()];
- newMesh.mPrimitives = new Primitive[b.mIndexTypes.size()];
- newMesh.mVertexBuffers = new Allocation[b.mVertexTypeCount];
-
- for(int ct = 0; ct < b.mIndexTypes.size(); ct ++) {
- Allocation alloc = null;
- Entry entry = (Entry)b.mIndexTypes.elementAt(ct);
- if (entry.t != null) {
- alloc = Allocation.createTyped(rs, entry.t, b.mUsage);
- }
- else if(entry.e != null) {
- alloc = Allocation.createSized(rs, entry.e, entry.size, b.mUsage);
- }
- int allocID = (alloc == null) ? 0 : alloc.getID();
- rs.nMeshBindIndex(id, allocID, entry.prim.mID, ct);
- newMesh.mIndexBuffers[ct] = alloc;
- newMesh.mPrimitives[ct] = entry.prim;
- }
-
- for(int ct = 0; ct < b.mVertexTypeCount; ct ++) {
- Allocation alloc = null;
- Entry entry = b.mVertexTypes[ct];
- if (entry.t != null) {
- alloc = Allocation.createTyped(rs, entry.t, b.mUsage);
- } else if(entry.e != null) {
- alloc = Allocation.createSized(rs, entry.e, entry.size, b.mUsage);
- }
- rs.nMeshBindVertex(id, alloc.getID(), ct);
- newMesh.mVertexBuffers[ct] = alloc;
- }
- rs.nMeshInitVertexAttribs(id);
-
- return newMesh;
- }
-
/**
* Create a Mesh object from the current state of the builder
*
**/
public Mesh create() {
mRS.validate();
- Mesh sm = internalCreate(mRS, this);
- return sm;
+ int[] vtx = new int[mVertexTypeCount];
+ int[] idx = new int[mIndexTypes.size()];
+ int[] prim = new int[mIndexTypes.size()];
+
+ Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
+ Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
+ Primitive[] primitives = new Primitive[mIndexTypes.size()];
+
+ for(int ct = 0; ct < mVertexTypeCount; ct ++) {
+ Allocation alloc = null;
+ Entry entry = mVertexTypes[ct];
+ if (entry.t != null) {
+ alloc = Allocation.createTyped(mRS, entry.t, mUsage);
+ } else if(entry.e != null) {
+ alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
+ }
+ vertexBuffers[ct] = alloc;
+ vtx[ct] = alloc.getID();
+ }
+
+ for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
+ Allocation alloc = null;
+ Entry entry = (Entry)mIndexTypes.elementAt(ct);
+ if (entry.t != null) {
+ alloc = Allocation.createTyped(mRS, entry.t, mUsage);
+ } else if(entry.e != null) {
+ alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
+ }
+ int allocID = (alloc == null) ? 0 : alloc.getID();
+ indexBuffers[ct] = alloc;
+ primitives[ct] = entry.prim;
+
+ idx[ct] = allocID;
+ prim[ct] = entry.prim.mID;
+ }
+
+ int id = mRS.nMeshCreate(vtx, idx, prim);
+ Mesh newMesh = new Mesh(id, mRS);
+ newMesh.mVertexBuffers = vertexBuffers;
+ newMesh.mIndexBuffers = indexBuffers;
+ newMesh.mPrimitives = primitives;
+
+ return newMesh;
}
}
@@ -463,40 +465,44 @@
return this;
}
- static synchronized Mesh internalCreate(RenderScript rs, AllocationBuilder b) {
-
- int id = rs.nMeshCreate(b.mVertexTypeCount, b.mIndexTypes.size());
- Mesh newMesh = new Mesh(id, rs);
- newMesh.mIndexBuffers = new Allocation[b.mIndexTypes.size()];
- newMesh.mPrimitives = new Primitive[b.mIndexTypes.size()];
- newMesh.mVertexBuffers = new Allocation[b.mVertexTypeCount];
-
- for(int ct = 0; ct < b.mIndexTypes.size(); ct ++) {
- Entry entry = (Entry)b.mIndexTypes.elementAt(ct);
- int allocID = (entry.a == null) ? 0 : entry.a.getID();
- rs.nMeshBindIndex(id, allocID, entry.prim.mID, ct);
- newMesh.mIndexBuffers[ct] = entry.a;
- newMesh.mPrimitives[ct] = entry.prim;
- }
-
- for(int ct = 0; ct < b.mVertexTypeCount; ct ++) {
- Entry entry = b.mVertexTypes[ct];
- rs.nMeshBindVertex(id, entry.a.getID(), ct);
- newMesh.mVertexBuffers[ct] = entry.a;
- }
- rs.nMeshInitVertexAttribs(id);
-
- return newMesh;
- }
-
/**
* Create a Mesh object from the current state of the builder
*
**/
public Mesh create() {
mRS.validate();
- Mesh sm = internalCreate(mRS, this);
- return sm;
+
+ int[] vtx = new int[mVertexTypeCount];
+ int[] idx = new int[mIndexTypes.size()];
+ int[] prim = new int[mIndexTypes.size()];
+
+ Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
+ Primitive[] primitives = new Primitive[mIndexTypes.size()];
+ Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
+
+ for(int ct = 0; ct < mVertexTypeCount; ct ++) {
+ Entry entry = mVertexTypes[ct];
+ vertexBuffers[ct] = entry.a;
+ vtx[ct] = entry.a.getID();
+ }
+
+ for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
+ Entry entry = (Entry)mIndexTypes.elementAt(ct);
+ int allocID = (entry.a == null) ? 0 : entry.a.getID();
+ indexBuffers[ct] = entry.a;
+ primitives[ct] = entry.prim;
+
+ idx[ct] = allocID;
+ prim[ct] = entry.prim.mID;
+ }
+
+ int id = mRS.nMeshCreate(vtx, idx, prim);
+ Mesh newMesh = new Mesh(id, mRS);
+ newMesh.mVertexBuffers = vertexBuffers;
+ newMesh.mIndexBuffers = indexBuffers;
+ newMesh.mPrimitives = primitives;
+
+ return newMesh;
}
}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index feb74b8..41a29e6 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -527,25 +527,10 @@
return rsnProgramVertexCreate(mContext, shader, params);
}
- native int rsnMeshCreate(int con, int vtxCount, int indexCount);
- synchronized int nMeshCreate(int vtxCount, int indexCount) {
+ native int rsnMeshCreate(int con, int[] vtx, int[] idx, int[] prim);
+ synchronized int nMeshCreate(int[] vtx, int[] idx, int[] prim) {
validate();
- return rsnMeshCreate(mContext, vtxCount, indexCount);
- }
- native void rsnMeshBindVertex(int con, int id, int alloc, int slot);
- synchronized void nMeshBindVertex(int id, int alloc, int slot) {
- validate();
- rsnMeshBindVertex(mContext, id, alloc, slot);
- }
- native void rsnMeshBindIndex(int con, int id, int alloc, int prim, int slot);
- synchronized void nMeshBindIndex(int id, int alloc, int prim, int slot) {
- validate();
- rsnMeshBindIndex(mContext, id, alloc, prim, slot);
- }
- native void rsnMeshInitVertexAttribs(int con, int id);
- synchronized void nMeshInitVertexAttribs(int id) {
- validate();
- rsnMeshInitVertexAttribs(mContext, id);
+ return rsnMeshCreate(mContext, vtx, idx, prim);
}
native int rsnMeshGetVertexBufferCount(int con, int id);
synchronized int nMeshGetVertexBufferCount(int id) {
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 2eaedaa..26a6287 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -1075,35 +1075,28 @@
// ---------------------------------------------------------------------------
static jint
-nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jint vtxCount, jint idxCount)
+nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jintArray _vtx, jintArray _idx, jintArray _prim)
{
- LOG_API("nMeshCreate, con(%p), vtxCount(%i), idxCount(%i)", con, vtxCount, idxCount);
- int id = (int)rsMeshCreate(con, vtxCount, idxCount);
+ LOG_API("nMeshCreate, con(%p)", con);
+
+ jint vtxLen = _env->GetArrayLength(_vtx);
+ jint *vtxPtr = _env->GetIntArrayElements(_vtx, NULL);
+ jint idxLen = _env->GetArrayLength(_idx);
+ jint *idxPtr = _env->GetIntArrayElements(_idx, NULL);
+ jint primLen = _env->GetArrayLength(_prim);
+ jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
+
+ int id = (int)rsMeshCreate(con,
+ (RsAllocation *)vtxPtr, vtxLen,
+ (RsAllocation *)idxPtr, idxLen,
+ (uint32_t *)primPtr, primLen);
+
+ _env->ReleaseIntArrayElements(_vtx, vtxPtr, 0);
+ _env->ReleaseIntArrayElements(_idx, idxPtr, 0);
+ _env->ReleaseIntArrayElements(_prim, primPtr, 0);
return id;
}
-static void
-nMeshBindVertex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint slot)
-{
- LOG_API("nMeshBindVertex, con(%p), Mesh(%p), Alloc(%p), slot(%i)", con, (RsMesh)mesh, (RsAllocation)alloc, slot);
- rsMeshBindVertex(con, (RsMesh)mesh, (RsAllocation)alloc, slot);
-}
-
-static void
-nMeshBindIndex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint primID, jint slot)
-{
- LOG_API("nMeshBindIndex, con(%p), Mesh(%p), Alloc(%p)", con, (RsMesh)mesh, (RsAllocation)alloc);
- rsMeshBindIndex(con, (RsMesh)mesh, (RsAllocation)alloc, primID, slot);
-}
-
-static void
-nMeshInitVertexAttribs(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
-{
- LOG_API("nMeshInitVertexAttribs, con(%p), Mesh(%p)", con, (RsMesh)mesh);
- rsMeshInitVertexAttribs(con, (RsMesh)mesh);
-}
-
-
static jint
nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
{
@@ -1267,10 +1260,7 @@
{"rsnSamplerCreate", "(IIIIIIF)I", (void*)nSamplerCreate },
-{"rsnMeshCreate", "(III)I", (void*)nMeshCreate },
-{"rsnMeshBindVertex", "(IIII)V", (void*)nMeshBindVertex },
-{"rsnMeshBindIndex", "(IIIII)V", (void*)nMeshBindIndex },
-{"rsnMeshInitVertexAttribs", "(II)V", (void*)nMeshInitVertexAttribs },
+{"rsnMeshCreate", "(I[I[I[I)I", (void*)nMeshCreate },
{"rsnMeshGetVertexBufferCount", "(II)I", (void*)nMeshGetVertexBufferCount },
{"rsnMeshGetIndexCount", "(II)I", (void*)nMeshGetIndexCount },
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 5a86fe3..3232f6f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2059,6 +2059,11 @@
drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
}
+void OpenGLRenderer::drawGlyphs(const char* glyphs, int index, int count, float x, float y,
+ SkPaint* paint) {
+ // TODO
+}
+
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index ffacbfc..70abe88 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -123,6 +123,8 @@
virtual void drawPoints(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint);
+ virtual void drawGlyphs(const char* glyphs, int index, int count, float x, float y,
+ SkPaint* paint);
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 00e3a0a..1da00a5 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -403,25 +403,8 @@
}
MeshCreate {
+ param RsAllocation *vtx
+ param RsAllocation *idx
+ param uint32_t *primType
ret RsMesh
- param uint32_t vtxCount
- param uint32_t idxCount
}
-
-MeshBindIndex {
- param RsMesh mesh
- param RsAllocation idx
- param uint32_t primType
- param uint32_t slot
- }
-
-MeshBindVertex {
- param RsMesh mesh
- param RsAllocation vtx
- param uint32_t slot
- }
-
-MeshInitVertexAttribs {
- param RsMesh mesh
- }
-
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 35184c1..3d0342d 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -263,30 +263,25 @@
namespace android {
namespace renderscript {
-RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount) {
+RsMesh rsi_MeshCreate(Context *rsc,
+ RsAllocation *vtx, uint32_t vtxCount,
+ RsAllocation *idx, uint32_t idxCount,
+ uint32_t *primType, uint32_t primTypeCount) {
+ rsAssert(idxCount == primTypeCount);
Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
sm->incUserRef();
- return sm;
-}
+ for (uint32_t i = 0; i < vtxCount; i ++) {
+ sm->setVertexBuffer((Allocation*)vtx[i], i);
+ }
-void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot) {
- Mesh *sm = static_cast<Mesh *>(mv);
- rsAssert(slot < sm->mHal.state.vertexBuffersCount);
+ for (uint32_t i = 0; i < idxCount; i ++) {
+ sm->setPrimitive((Allocation*)idx[i], (RsPrimitive)primType[i], i);
+ }
- sm->setVertexBuffer((Allocation *)va, slot);
-}
-
-void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot) {
- Mesh *sm = static_cast<Mesh *>(mv);
- rsAssert(slot < sm->mHal.state.primitivesCount);
-
- sm->setPrimitive((Allocation *)va, (RsPrimitive)primType, slot);
-}
-
-void rsi_MeshInitVertexAttribs(Context *rsc, RsMesh mv) {
- Mesh *sm = static_cast<Mesh *>(mv);
sm->init();
+
+ return sm;
}
}}
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 1e279f4..ed1e93d 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -39,13 +39,6 @@
RsPrimitive mPrimitive;
};
- // compatibility to not break the build
- ObjectBaseRef<Allocation> *mVertexBuffers;
- uint32_t mVertexBufferCount;
- Primitive_t ** mPrimitives;
- uint32_t mPrimitivesCount;
- // end compatibility
-
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
static Mesh *createFromStream(Context *rsc, IStream *stream);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 10beee9..a6ba1a0 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1257,6 +1257,7 @@
LOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
track->setMainBuffer(chain->inBuffer());
chain->setStrategy(AudioSystem::getStrategyForStream((audio_stream_type_t)track->type()));
+ chain->incTrackCnt();
}
}
lStatus = NO_ERROR;
@@ -1340,7 +1341,7 @@
sp<EffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
LOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), track->sessionId());
- chain->startTrack();
+ chain->incActiveTrackCnt();
}
}
@@ -1358,8 +1359,17 @@
{
track->mState = TrackBase::TERMINATED;
if (mActiveTracks.indexOf(track) < 0) {
- mTracks.remove(track);
- deleteTrackName_l(track->name());
+ removeTrack_l(track);
+ }
+}
+
+void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)
+{
+ mTracks.remove(track);
+ deleteTrackName_l(track->name());
+ sp<EffectChain> chain = getEffectChain_l(track->sessionId());
+ if (chain != 0) {
+ chain->decTrackCnt();
}
}
@@ -1865,12 +1875,11 @@
chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
LOGV("stopping track on chain %p for session Id: %d", chain.get(), track->sessionId());
- chain->stopTrack();
+ chain->decActiveTrackCnt();
}
}
if (track->isTerminated()) {
- mTracks.remove(track);
- deleteTrackName_l(track->mName);
+ removeTrack_l(track);
}
}
}
@@ -1956,7 +1965,7 @@
if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
// when changing the audio output device, call addBatteryData to notify
// the change
- if (mDevice != value) {
+ if ((int)mDevice != value) {
uint32_t params = 0;
// check whether speaker is on
if (value & AUDIO_DEVICE_OUT_SPEAKER) {
@@ -2348,11 +2357,10 @@
if (!effectChains.isEmpty()) {
LOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(),
trackToRemove->sessionId());
- effectChains[0]->stopTrack();
+ effectChains[0]->decActiveTrackCnt();
}
if (trackToRemove->isTerminated()) {
- mTracks.remove(trackToRemove);
- deleteTrackName_l(trackToRemove->mName);
+ removeTrack_l(trackToRemove);
}
}
@@ -5150,6 +5158,7 @@
if (session == track->sessionId()) {
LOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), buffer);
track->setMainBuffer(buffer);
+ chain->incTrackCnt();
}
}
@@ -5159,7 +5168,7 @@
if (track == 0) continue;
if (session == track->sessionId()) {
LOGV("addEffectChain_l() activating track %p on session %d", track.get(), session);
- chain->startTrack();
+ chain->incActiveTrackCnt();
}
}
}
@@ -5195,11 +5204,23 @@
for (size_t i = 0; i < mEffectChains.size(); i++) {
if (chain == mEffectChains[i]) {
mEffectChains.removeAt(i);
+ // detach all active tracks from the chain
+ for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
+ sp<Track> track = mActiveTracks[i].promote();
+ if (track == 0) continue;
+ if (session == track->sessionId()) {
+ LOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d",
+ chain.get(), session);
+ chain->decActiveTrackCnt();
+ }
+ }
+
// detach all tracks with same session ID from this chain
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> track = mTracks[i];
if (session == track->sessionId()) {
track->setMainBuffer(mMixBuffer);
+ chain->decTrackCnt();
}
}
break;
@@ -5481,7 +5502,7 @@
// If an insert effect is idle and input buffer is different from output buffer,
// accumulate input onto output
sp<EffectChain> chain = mChain.promote();
- if (chain != 0 && chain->activeTracks() != 0) {
+ if (chain != 0 && chain->activeTrackCnt() != 0) {
size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2; //always stereo here
int16_t *in = mConfig.inputCfg.buffer.s16;
int16_t *out = mConfig.outputCfg.buffer.s16;
@@ -6157,9 +6178,9 @@
AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& wThread,
int sessionId)
- : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mOwnInBuffer(false),
- mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
- mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
+ : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0),
+ mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
+ mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
{
mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
}
@@ -6216,8 +6237,15 @@
(mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
bool tracksOnSession = false;
if (!isGlobalSession) {
- tracksOnSession =
- playbackThread->hasAudioSession(mSessionId) & PlaybackThread::TRACK_SESSION;
+ tracksOnSession = (trackCnt() != 0);
+ }
+
+ // if no track is active, input buffer must be cleared here as the mixer process
+ // will not do it
+ if (tracksOnSession &&
+ activeTrackCnt() == 0) {
+ size_t numSamples = playbackThread->frameCount() * playbackThread->channelCount();
+ memset(mInBuffer, 0, numSamples * sizeof(int16_t));
}
size_t size = mEffects.size();
@@ -6230,13 +6258,6 @@
for (size_t i = 0; i < size; i++) {
mEffects[i]->updateState();
}
- // if no track is active, input buffer must be cleared here as the mixer process
- // will not do it
- if (tracksOnSession &&
- activeTracks() == 0) {
- size_t numSamples = playbackThread->frameCount() * playbackThread->channelCount();
- memset(mInBuffer, 0, numSamples * sizeof(int16_t));
- }
}
// addEffect_l() must be called with PlaybackThread::mLock held
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 43be6fe..39314ad 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -684,6 +684,7 @@
status_t addTrack_l(const sp<Track>& track);
void destroyTrack_l(const sp<Track>& track);
+ void removeTrack_l(const sp<Track>& track);
void readOutputParameters();
@@ -1134,9 +1135,13 @@
return mOutBuffer;
}
- void startTrack() {mActiveTrackCnt++;}
- void stopTrack() {mActiveTrackCnt--;}
- int activeTracks() { return mActiveTrackCnt;}
+ void incTrackCnt() { android_atomic_inc(&mTrackCnt); }
+ void decTrackCnt() { android_atomic_dec(&mTrackCnt); }
+ int32_t trackCnt() { return mTrackCnt;}
+
+ void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); }
+ void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); }
+ int32_t activeTrackCnt() { return mActiveTrackCnt;}
uint32_t strategy() { return mStrategy; }
void setStrategy(uint32_t strategy)
@@ -1155,7 +1160,8 @@
int mSessionId; // audio session ID
int16_t *mInBuffer; // chain input buffer
int16_t *mOutBuffer; // chain output buffer
- int mActiveTrackCnt; // number of active tracks connected
+ volatile int32_t mActiveTrackCnt; // number of active tracks connected
+ volatile int32_t mTrackCnt; // number of tracks connected
bool mOwnInBuffer; // true if the chain owns its input buffer
int mVolumeCtrlIdx; // index of insert effect having control over volume
uint32_t mLeftVolume; // previous volume on left channel