Fix clear() operation for rsScriptC.
- This removes a memory leak where some elements were not getting tracked
properly (and then triggering an assert when a context is destroyed).
- Convert ScriptCState to use a tracked object reference for mScript.
- Add a missing clear to FontState.
- Clean up synchronization in RSTest so that our graphics context outlives
any subtest context.
Change-Id: I0d5768c4d2f8810dd1ae2f68b1edd7e150f382fd
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index dbc9133..835dea2 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -21,6 +21,8 @@
import android.util.Log;
import java.util.ArrayList;
import java.util.ListIterator;
+import java.util.Timer;
+import java.util.TimerTask;
public class RSTestCore {
@@ -42,12 +44,18 @@
private ArrayList<UnitTest> unitTests;
private ListIterator<UnitTest> test_iter;
private UnitTest activeTest;
+ private boolean stopTesting;
+
+ /* Periodic timer for ensuring future tests get scheduled */
+ private Timer mTimer;
+ public static final int RS_TIMER_PERIOD = 100;
public void init(RenderScriptGL rs, Resources res, int width, int height) {
mRS = rs;
mRes = res;
mWidth = width;
mHeight = height;
+ stopTesting = false;
mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist, true);
@@ -88,9 +96,17 @@
test_iter = unitTests.listIterator();
refreshTestResults(); /* Kick off the first test */
+
+ TimerTask pTask = new TimerTask() {
+ public void run() {
+ refreshTestResults();
+ }
+ };
+
+ mTimer = new Timer();
+ mTimer.schedule(pTask, RS_TIMER_PERIOD, RS_TIMER_PERIOD);
}
- static int count = 0;
public void checkAndRunNextTest() {
if (activeTest != null) {
if (!activeTest.isAlive()) {
@@ -104,7 +120,7 @@
}
}
- if (activeTest == null) {
+ if (!stopTesting && activeTest == null) {
if (test_iter.hasNext()) {
activeTest = test_iter.next();
activeTest.start();
@@ -112,8 +128,14 @@
* should start running. The message handler in UnitTest.java
* ensures this. */
}
+ else {
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer.purge();
+ mTimer = null;
+ }
+ }
}
- count++;
}
public void refreshTestResults() {
@@ -127,6 +149,29 @@
}
}
+ public void cleanup() {
+ stopTesting = true;
+ UnitTest t = activeTest;
+
+ /* Stop periodic refresh of testing */
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer.purge();
+ mTimer = null;
+ }
+
+ /* Wait to exit until we finish the current test */
+ if (t != null) {
+ try {
+ t.join();
+ }
+ catch (InterruptedException e) {
+ }
+ t = null;
+ }
+
+ }
+
public void newTouchPosition(float x, float y, float pressure, int id) {
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java
index ce99c6d..b811d48 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java
@@ -62,6 +62,7 @@
@Override
protected void onDetachedFromWindow() {
if(mRS != null) {
+ mRender.cleanup();
mRS = null;
destroyRenderScript();
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
index 8391fb3..9d57e90 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
@@ -33,6 +33,7 @@
pRS.mMessageCallback = mRsMessage;
s.invoke_fp_mad_test(0, 0);
pRS.finish();
+ waitForMessage();
pRS.destroy();
}
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
index bef6ec5..fb355dd 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
@@ -33,6 +33,7 @@
pRS.mMessageCallback = mRsMessage;
s.invoke_primitives_test(0, 0);
pRS.finish();
+ waitForMessage();
pRS.destroy();
}
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java
index 5eb0d67..c9d88a6 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java
@@ -23,6 +23,7 @@
public int result;
private ScriptField_ListAllocs_s.Item mItem;
private RSTestCore mRSTC;
+ private boolean msgHandled;
/* These constants must match those in shared.rsh */
public static final int RS_MSG_TEST_PASSED = 100;
@@ -35,6 +36,7 @@
super();
mRSTC = rstc;
name = n;
+ msgHandled = false;
result = initResult;
testID = numTests++;
}
@@ -67,6 +69,7 @@
if (mItem != null) {
mItem.result = result;
+ msgHandled = true;
try {
mRSTC.refreshTestResults();
}
@@ -79,6 +82,12 @@
}
};
+ public void waitForMessage() {
+ while (!msgHandled) {
+ yield();
+ }
+ }
+
public void setItem(ScriptField_ListAllocs_s.Item item) {
mItem = item;
}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index b4d5014..cfd6479 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -294,6 +294,7 @@
LOGE("pthread_setspecific %i", status);
}
+ rsc->mScriptC.init(rsc);
if (rsc->mIsGraphicsContext) {
rsc->mStateRaster.init(rsc);
rsc->setRaster(NULL);
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 4f8d8df..12dedac 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -743,6 +743,8 @@
{
mInitialized = false;
+ mFontShaderFConstant.clear();
+
mIndexBuffer.clear();
mVertexArray.clear();
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 48f1fee..713d61e 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -61,6 +61,7 @@
if (mRSC) {
remove();
}
+ rsAssert(rsc);
mRSC = rsc;
if (rsc) {
add();
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index e9621b9..c6418be 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -349,25 +349,29 @@
ScriptCState::ScriptCState()
{
- mScript = NULL;
- clear();
+ mScript.clear();
}
ScriptCState::~ScriptCState()
{
- delete mScript;
- mScript = NULL;
+ mScript.clear();
}
-void ScriptCState::clear()
+void ScriptCState::init(Context *rsc)
{
+ clear(rsc);
+}
+
+void ScriptCState::clear(Context *rsc)
+{
+ rsAssert(rsc);
for (uint32_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
mConstantBufferTypes[ct].clear();
mSlotWritable[ct] = false;
}
- delete mScript;
- mScript = new ScriptC(NULL);
+ mScript.clear();
+ mScript.set(new ScriptC(rsc));
}
static BCCvoid* symbolLookup(BCCvoid* pContext, const BCCchar* name)
@@ -503,7 +507,7 @@
void rsi_ScriptCBegin(Context * rsc)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->clear();
+ ss->clear(rsc);
}
void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
@@ -522,10 +526,10 @@
{
ScriptCState *ss = &rsc->mScriptC;
- ScriptC *s = ss->mScript;
- ss->mScript = NULL;
+ ObjectBaseRef<ScriptC> s = ss->mScript.get();
+ ss->mScript.clear();
- ss->runCompiler(rsc, s);
+ ss->runCompiler(rsc, s.get());
s->incUserRef();
s->setContext(rsc);
for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
@@ -533,8 +537,8 @@
s->mSlotWritable[ct] = ss->mSlotWritable[ct];
}
- ss->clear();
- return s;
+ ss->clear(rsc);
+ return s.get();
}
}
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 9d09b0b..7ec80aa 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -79,14 +79,16 @@
ScriptCState();
~ScriptCState();
- ScriptC *mScript;
+ ObjectBaseRef<ScriptC> mScript;
ObjectBaseRef<const Type> mConstantBufferTypes[MAX_SCRIPT_BANKS];
//String8 mSlotNames[MAX_SCRIPT_BANKS];
bool mSlotWritable[MAX_SCRIPT_BANKS];
//String8 mInvokableNames[MAX_SCRIPT_BANKS];
- void clear();
+ void init(Context *rsc);
+
+ void clear(Context *rsc);
void runCompiler(Context *rsc, ScriptC *s);
struct SymbolTable_t {