Merge "Async type creation."

This commit is contained in:
Jason Sams
2010-10-14 17:52:31 -07:00
committed by Android (Google) Code Review
14 changed files with 199 additions and 199 deletions

View File

@@ -178,17 +178,9 @@ public class RenderScript {
rsnElementGetSubElements(mContext, id, IDs, names);
}
native void rsnTypeBegin(int con, int elementID);
synchronized void nTypeBegin(int elementID) {
rsnTypeBegin(mContext, elementID);
}
native void rsnTypeAdd(int con, int dim, int val);
synchronized void nTypeAdd(int dim, int val) {
rsnTypeAdd(mContext, dim, val);
}
native int rsnTypeCreate(int con);
synchronized int nTypeCreate() {
return rsnTypeCreate(mContext);
native int rsnTypeCreate(int con, int eid, int[] dims, int[] vals);
synchronized int nTypeCreate(int eid, int[] dims, int[] vals) {
return rsnTypeCreate(mContext, eid, dims, vals);
}
native void rsnTypeGetNativeData(int con, int id, int[] typeData);
synchronized void nTypeGetNativeData(int id, int[] typeData) {

View File

@@ -132,7 +132,8 @@ public class Type extends BaseObj {
public static class Builder {
RenderScript mRS;
Entry[] mEntries;
Dimension[] mDimensions;
int[] mDimensionValues;
int mEntryCount;
Element mElement;
@@ -147,7 +148,8 @@ public class Type extends BaseObj {
}
mRS = rs;
mEntries = new Entry[4];
mDimensions = new Dimension[4];
mDimensionValues = new int[4];
mElement = e;
}
@@ -155,46 +157,45 @@ public class Type extends BaseObj {
if(value < 1) {
throw new IllegalArgumentException("Values of less than 1 for Dimensions are not valid.");
}
if(mEntries.length >= mEntryCount) {
Entry[] en = new Entry[mEntryCount + 8];
System.arraycopy(mEntries, 0, en, 0, mEntries.length);
mEntries = en;
if(mDimensions.length >= mEntryCount) {
Dimension[] dn = new Dimension[mEntryCount + 8];
System.arraycopy(mDimensions, 0, dn, 0, mEntryCount);
mDimensions = dn;
int[] in = new int[mEntryCount + 8];
System.arraycopy(mDimensionValues, 0, in, 0, mEntryCount);
mDimensionValues = in;
}
mEntries[mEntryCount] = new Entry();
mEntries[mEntryCount].mDim = d;
mEntries[mEntryCount].mValue = value;
mDimensions[mEntryCount] = d;
mDimensionValues[mEntryCount] = value;
mEntryCount++;
}
static synchronized Type internalCreate(RenderScript rs, Builder b) {
rs.nTypeBegin(b.mElement.mID);
for (int ct=0; ct < b.mEntryCount; ct++) {
Entry en = b.mEntries[ct];
rs.nTypeAdd(en.mDim.mID, en.mValue);
}
int id = rs.nTypeCreate();
return new Type(id, rs);
}
public Type create() {
Type t = internalCreate(mRS, this);
int dims[] = new int[mEntryCount];
for (int ct=0; ct < mEntryCount; ct++) {
dims[ct] = mDimensions[ct].mID;
}
int id = mRS.nTypeCreate(mElement.getID(), dims, mDimensionValues);
Type t = new Type(id, mRS);
t.mElement = mElement;
for(int ct=0; ct < mEntryCount; ct++) {
if(mEntries[ct].mDim == Dimension.X) {
t.mDimX = mEntries[ct].mValue;
if(mDimensions[ct] == Dimension.X) {
t.mDimX = mDimensionValues[ct];
}
if(mEntries[ct].mDim == Dimension.Y) {
t.mDimY = mEntries[ct].mValue;
if(mDimensions[ct] == Dimension.Y) {
t.mDimY = mDimensionValues[ct];
}
if(mEntries[ct].mDim == Dimension.Z) {
t.mDimZ = mEntries[ct].mValue;
if(mDimensions[ct] == Dimension.Z) {
t.mDimZ = mDimensionValues[ct];
}
if(mEntries[ct].mDim == Dimension.LOD) {
t.mDimLOD = mEntries[ct].mValue != 0;
if(mDimensions[ct] == Dimension.LOD) {
t.mDimLOD = mDimensionValues[ct] != 0;
}
if(mEntries[ct].mDim == Dimension.FACE) {
t.mDimFaces = mEntries[ct].mValue != 0;
if(mDimensions[ct] == Dimension.FACE) {
t.mDimFaces = mDimensionValues[ct] != 0;
}
}
t.calcElementCount();

View File

@@ -112,7 +112,7 @@ static void
nObjDestroy(JNIEnv *_env, jobject _this, RsContext con, jint obj)
{
LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
rsObjDestroy(con, (void *)obj);
rsObjDestroy(con, (uint32_t)obj);
}
@@ -336,25 +336,21 @@ nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id, jint
// -----------------------------------
static void
nTypeBegin(JNIEnv *_env, jobject _this, RsContext con, jint eID)
{
LOG_API("nTypeBegin, con(%p) e(%p)", con, (RsElement)eID);
rsTypeBegin(con, (RsElement)eID);
}
static void
nTypeAdd(JNIEnv *_env, jobject _this, RsContext con, jint dim, jint val)
{
LOG_API("nTypeAdd, con(%p) dim(%i), val(%i)", con, dim, val);
rsTypeAdd(con, (RsDimension)dim, val);
}
static jint
nTypeCreate(JNIEnv *_env, jobject _this, RsContext con)
static int
nTypeCreate(JNIEnv *_env, jobject _this, RsContext con, RsElement eid, jintArray _dims, jintArray _dimValues)
{
int count = _env->GetArrayLength(_dims);
LOG_API("nTypeCreate, con(%p)", con);
return (jint)rsTypeCreate(con);
jint *dimPtr = _env->GetIntArrayElements(_dims, NULL);
jint *dimValPtr = _env->GetIntArrayElements(_dimValues, NULL);
jint id = (jint)rsaTypeCreate(con, (RsElement)eid, count,
(RsDimension *)dimPtr, (uint32_t *)dimValPtr);
_env->ReleaseIntArrayElements(_dims, dimPtr, JNI_ABORT);
_env->ReleaseIntArrayElements(_dimValues, dimValPtr, JNI_ABORT);
return (jint)id;
}
static void
@@ -1261,9 +1257,7 @@ static JNINativeMethod methods[] = {
{"rsnElementGetNativeData", "(II[I)V", (void*)nElementGetNativeData },
{"rsnElementGetSubElements", "(II[I[Ljava/lang/String;)V", (void*)nElementGetSubElements },
{"rsnTypeBegin", "(II)V", (void*)nTypeBegin },
{"rsnTypeAdd", "(III)V", (void*)nTypeAdd },
{"rsnTypeCreate", "(I)I", (void*)nTypeCreate },
{"rsnTypeCreate", "(II[I[I)I", (void*)nTypeCreate },
{"rsnTypeGetNativeData", "(II[I)V", (void*)nTypeGetNativeData },
{"rsnAllocationCreateTyped", "(II)I", (void*)nAllocationCreateTyped },

View File

@@ -27,6 +27,8 @@ extern "C" {
//////////////////////////////////////////////////////
//
typedef void * RsAsyncVoidPtr;
typedef void * RsAdapter1D;
typedef void * RsAdapter2D;
typedef void * RsAllocation;
@@ -285,6 +287,11 @@ typedef struct {
} RsScriptCall;
// Async commands for returning new IDS
void * rsaTypeCreate(RsContext, RsElement, uint32_t dimCount,
const RsDimension *dims, const uint32_t *vals);
#ifndef NO_RS_FUNCS
#include "rsgApiFuncDecl.h"
#endif

View File

@@ -64,7 +64,7 @@ GetName {
}
ObjDestroy {
param void *obj
param RsAsyncVoidPtr objPtr
}
ElementCreate {
@@ -97,18 +97,6 @@ ElementGetSubElements {
param uint32_t dataSize
}
TypeBegin {
param RsElement type
}
TypeAdd {
param RsDimension dim
param size_t value
}
TypeCreate {
ret RsType
}
TypeGetNativeData {
param RsType type
@@ -135,8 +123,8 @@ AllocationUpdateFromBitmap {
AllocationCreateBitmapRef {
param RsType type
param void * bmpPtr
param void * callbackData
param RsAsyncVoidPtr bmpPtr
param RsAsyncVoidPtr callbackData
param RsBitmapCallback_t callback
ret RsAllocation
}

View File

@@ -794,13 +794,9 @@ RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h
const Element *dst = static_cast<const Element *>(_dst);
//LOGE("%p rsi_AllocationCreateFromBitmap %i %i %i", rsc, w, h, genMips);
rsi_TypeBegin(rsc, _dst);
rsi_TypeAdd(rsc, RS_DIMENSION_X, w);
rsi_TypeAdd(rsc, RS_DIMENSION_Y, h);
if (genMips) {
rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1);
}
RsType type = rsi_TypeCreate(rsc);
RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD};
uint32_t dimValues[] = {w, h, genMips};
RsType type = rsaTypeCreate(rsc, _dst, 3, dims, dimValues);
RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type);
Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);

View File

@@ -30,8 +30,6 @@ class Allocation : public ObjectBase
// The graphics equilivent of malloc. The allocation contains a structure of elements.
public:
// By policy this allocation will hold a pointer to the type
// but will not destroy it on destruction.
Allocation(Context *rsc, const Type *);
Allocation(Context *rsc, const Type *, void *bmp, void *callbackData, RsBitmapCallback_t callback);

View File

@@ -976,9 +976,9 @@ void rsi_GetName(Context *rsc, void * obj, const char **name)
(*name) = ob->getName();
}
void rsi_ObjDestroy(Context *rsc, void *obj)
void rsi_ObjDestroy(Context *rsc, void *optr)
{
ObjectBase *ob = static_cast<ObjectBase *>(obj);
ObjectBase *ob = static_cast<ObjectBase *>(optr);
rsc->removeName(ob);
ob->decUserRef();
}

View File

@@ -15,6 +15,8 @@
*/
#include "rsLocklessFifo.h"
#include "utils/Timers.h"
#include "utils/StopWatch.h"
using namespace android;
using namespace android::renderscript;
@@ -115,6 +117,10 @@ void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes)
if (mInShutdown) {
return;
}
//char buf[1024];
//sprintf(buf, "RenderScript LocklessCommandFifo::commitSync %p %i %i", this, command, sizeInBytes);
//StopWatch compileTimer(buf);
commit(command, sizeInBytes);
flush();
}

View File

@@ -25,16 +25,20 @@
using namespace android;
using namespace android::renderscript;
pthread_mutex_t ObjectBase::gObjectInitMutex = PTHREAD_MUTEX_INITIALIZER;
ObjectBase::ObjectBase(Context *rsc)
{
mUserRefCount = 0;
mSysRefCount = 0;
mRSC = NULL;
mRSC = rsc;
mNext = NULL;
mPrev = NULL;
mAllocFile = __FILE__;
mAllocLine = __LINE__;
setContext(rsc);
rsAssert(rsc);
add();
}
ObjectBase::~ObjectBase()
@@ -56,24 +60,19 @@ void ObjectBase::dumpLOGV(const char *op) const
}
}
void ObjectBase::setContext(Context *rsc)
{
if (mRSC) {
remove();
}
rsAssert(rsc);
mRSC = rsc;
if (rsc) {
add();
}
}
void ObjectBase::incUserRef() const
{
mUserRefCount ++;
lockUserRef();
mUserRefCount++;
unlockUserRef();
//LOGV("ObjectBase %p inc ref %i", this, mUserRefCount);
}
void ObjectBase::prelockedIncUserRef() const
{
mUserRefCount++;
}
void ObjectBase::incSysRef() const
{
mSysRefCount ++;
@@ -83,10 +82,20 @@ void ObjectBase::incSysRef() const
bool ObjectBase::checkDelete() const
{
if (!(mSysRefCount | mUserRefCount)) {
lockUserRef();
// Recheck the user ref count since it can be incremented from other threads.
if (mUserRefCount) {
unlockUserRef();
return false;
}
if (mRSC && mRSC->props.mLogObjects) {
dumpLOGV("checkDelete");
}
delete this;
unlockUserRef();
return true;
}
return false;
@@ -94,17 +103,25 @@ bool ObjectBase::checkDelete() const
bool ObjectBase::decUserRef() const
{
lockUserRef();
rsAssert(mUserRefCount > 0);
mUserRefCount --;
//dumpLOGV("decUserRef");
return checkDelete();
mUserRefCount--;
unlockUserRef();
bool ret = checkDelete();
return ret;
}
bool ObjectBase::zeroUserRef() const
{
lockUserRef();
// This can only happen during cleanup and is therefore
// thread safe.
mUserRefCount = 0;
//dumpLOGV("zeroUserRef");
return checkDelete();
unlockUserRef();
bool ret = checkDelete();
return ret;
}
bool ObjectBase::decSysRef() const
@@ -125,8 +142,20 @@ void ObjectBase::setName(const char *name, uint32_t len)
mName.setTo(name, len);
}
void ObjectBase::lockUserRef()
{
pthread_mutex_lock(&gObjectInitMutex);
}
void ObjectBase::unlockUserRef()
{
pthread_mutex_unlock(&gObjectInitMutex);
}
void ObjectBase::add() const
{
pthread_mutex_lock(&gObjectInitMutex);
rsAssert(!mNext);
rsAssert(!mPrev);
//LOGV("calling add rsc %p", mRSC);
@@ -135,16 +164,22 @@ void ObjectBase::add() const
mRSC->mObjHead->mPrev = this;
}
mRSC->mObjHead = this;
pthread_mutex_unlock(&gObjectInitMutex);
}
void ObjectBase::remove() const
{
// Should be within gObjectInitMutex lock
// lock will be from checkDelete a few levels up in the stack.
//LOGV("calling remove rsc %p", mRSC);
if (!mRSC) {
rsAssert(!mPrev);
rsAssert(!mNext);
return;
}
if (mRSC->mObjHead == this) {
mRSC->mObjHead = mNext;
}
@@ -160,6 +195,8 @@ void ObjectBase::remove() const
void ObjectBase::zeroAllUserRef(Context *rsc)
{
lockUserRef();
if (rsc->props.mLogObjects) {
LOGV("Forcing release of all outstanding user refs.");
}
@@ -182,10 +219,14 @@ void ObjectBase::zeroAllUserRef(Context *rsc)
LOGV("Objects remaining.");
dumpAll(rsc);
}
unlockUserRef();
}
void ObjectBase::dumpAll(Context *rsc)
{
lockUserRef();
LOGV("Dumping all objects");
const ObjectBase * o = rsc->mObjHead;
while (o) {
@@ -193,17 +234,23 @@ void ObjectBase::dumpAll(Context *rsc)
o->dumpLOGV(" ");
o = o->mNext;
}
unlockUserRef();
}
bool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj)
{
lockUserRef();
const ObjectBase * o = rsc->mObjHead;
while (o) {
if (o == obj) {
unlockUserRef();
return true;
}
o = o->mNext;
}
unlockUserRef();
return false;
}

View File

@@ -39,6 +39,7 @@ public:
void incUserRef() const;
bool decUserRef() const;
bool zeroUserRef() const;
void prelockedIncUserRef() const;
const char * getName() const {
return mName.string();
@@ -47,7 +48,6 @@ public:
void setName(const char *, uint32_t len);
Context * getContext() const {return mRSC;}
void setContext(Context *);
static void zeroAllUserRef(Context *rsc);
static void dumpAll(Context *rsc);
@@ -58,12 +58,17 @@ public:
static bool isValid(const Context *rsc, const ObjectBase *obj);
static void lockUserRef();
static void unlockUserRef();
protected:
const char *mAllocFile;
uint32_t mAllocLine;
Context *mRSC;
private:
static pthread_mutex_t gObjectInitMutex;
void add() const;
void remove() const;

View File

@@ -529,8 +529,6 @@ RsScript rsi_ScriptCCreate(Context * rsc)
ss->runCompiler(rsc, s.get());
s->incUserRef();
s->setContext(rsc);
ss->clear(rsc);
return s.get();
}

View File

@@ -381,88 +381,6 @@ Type * Type::cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const
namespace android {
namespace renderscript {
void rsi_TypeBegin(Context *rsc, RsElement vse)
{
TypeState * stc = &rsc->mStateType;
stc->mX = 0;
stc->mY = 0;
stc->mZ = 0;
stc->mLOD = false;
stc->mFaces = false;
stc->mElement.set(static_cast<const Element *>(vse));
}
void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
{
TypeState * stc = &rsc->mStateType;
if (dim < 0) {
//error
return;
}
switch (dim) {
case RS_DIMENSION_X:
stc->mX = value;
return;
case RS_DIMENSION_Y:
stc->mY = value;
return;
case RS_DIMENSION_Z:
stc->mZ = value;
return;
case RS_DIMENSION_FACE:
stc->mFaces = (value != 0);
return;
case RS_DIMENSION_LOD:
stc->mLOD = (value != 0);
return;
default:
break;
}
if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
LOGE("rsTypeAdd: Bad dimension");
//error
return;
}
// todo: implement array support
}
RsType rsi_TypeCreate(Context *rsc)
{
TypeState * stc = &rsc->mStateType;
for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
Type *t = stc->mTypes[ct];
if (t->getElement() != stc->mElement.get()) continue;
if (t->getDimX() != stc->mX) continue;
if (t->getDimY() != stc->mY) continue;
if (t->getDimZ() != stc->mZ) continue;
if (t->getDimLOD() != stc->mLOD) continue;
if (t->getDimFaces() != stc->mFaces) continue;
t->incUserRef();
return t;
}
Type * st = new Type(rsc);
st->incUserRef();
st->setDimX(stc->mX);
st->setDimY(stc->mY);
st->setDimZ(stc->mZ);
st->setElement(stc->mElement.get());
st->setDimLOD(stc->mLOD);
st->setDimFaces(stc->mFaces);
st->compute();
stc->mElement.clear();
stc->mTypes.push(st);
return st;
}
void rsi_TypeGetNativeData(Context *rsc, RsType type, uint32_t *typeData, uint32_t typeDataSize)
{
rsAssert(typeDataSize == 6);
@@ -483,3 +401,61 @@ void rsi_TypeGetNativeData(Context *rsc, RsType type, uint32_t *typeData, uint32
}
}
void * rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimCount,
const RsDimension *dims, const uint32_t *vals)
{
Context *rsc = static_cast<Context *>(con);
Element *e = static_cast<Element *>(_e);
TypeState * stc = &rsc->mStateType;
uint32_t dimX = 0;
uint32_t dimY = 0;
uint32_t dimZ = 0;
uint32_t dimLOD = 0;
uint32_t dimFaces = 0;
for (uint32_t ct=0; ct < dimCount; ct++) {
switch(dims[ct]) {
case RS_DIMENSION_X: dimX = vals[ct]; break;
case RS_DIMENSION_Y: dimY = vals[ct]; break;
case RS_DIMENSION_Z: dimZ = vals[ct]; break;
case RS_DIMENSION_LOD: dimLOD = vals[ct]; break;
case RS_DIMENSION_FACE: dimFaces = vals[ct]; break;
default:
LOGE("rsaTypeCreate: Bad dimension");
rsAssert(0);
}
}
ObjectBase::lockUserRef();
for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
Type *t = stc->mTypes[ct];
if (t->getElement() != e) continue;
if (t->getDimX() != dimX) continue;
if (t->getDimY() != dimY) continue;
if (t->getDimZ() != dimZ) continue;
if (t->getDimLOD() != dimLOD) continue;
if (t->getDimFaces() != dimFaces) continue;
t->prelockedIncUserRef();
ObjectBase::unlockUserRef();
return t;
}
ObjectBase::unlockUserRef();
Type * st = new Type(rsc);
st->incUserRef();
st->setDimX(dimX);
st->setDimY(dimY);
st->setDimZ(dimZ);
st->setElement(e);
st->setDimLOD(dimLOD);
st->setDimFaces(dimFaces);
st->compute();
ObjectBase::lockUserRef();
stc->mTypes.push(st);
ObjectBase::unlockUserRef();
return st;
}

View File

@@ -134,14 +134,6 @@ public:
TypeState();
~TypeState();
size_t mX;
size_t mY;
size_t mZ;
uint32_t mLOD;
bool mFaces;
ObjectBaseRef<const Element> mElement;
// Cache of all existing types.
Vector<Type *> mTypes;
};