summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Sams <rjsams@android.com>2010-02-17 15:38:10 -0800
committerJason Sams <rjsams@android.com>2010-02-17 15:38:10 -0800
commit8154954868694e1f233d87d4933a474518b1cb81 (patch)
tree589a853c307533891684c168004512ce88724564
parenta33166c0bf203a25b9a2408c6854d6beb9ffcc77 (diff)
downloadandroid_frameworks_rs-8154954868694e1f233d87d4933a474518b1cb81.tar.gz
android_frameworks_rs-8154954868694e1f233d87d4933a474518b1cb81.tar.bz2
android_frameworks_rs-8154954868694e1f233d87d4933a474518b1cb81.zip
Implement type collapsing for Elements and Types. Now if a user creates two or more identical objects we simply reuse the existing object rather than create a new one.
-rw-r--r--rsElement.cpp56
-rw-r--r--rsElement.h6
-rw-r--r--rsObjectBase.cpp1
-rw-r--r--rsObjectBase.h2
-rw-r--r--rsProgramVertex.cpp2
-rw-r--r--rsType.cpp20
-rw-r--r--rsType.h4
7 files changed, 79 insertions, 12 deletions
diff --git a/rsElement.cpp b/rsElement.cpp
index 207ad15e..6288bc42 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -34,6 +34,12 @@ Element::Element(Context *rsc) : ObjectBase(rsc)
Element::~Element()
{
+ for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
+ if (mRSC->mStateElement.mElements[ct] == this) {
+ mRSC->mStateElement.mElements.removeAt(ct);
+ break;
+ }
+ }
clear();
}
@@ -78,27 +84,62 @@ void Element::dumpLOGV(const char *prefix) const
}
-Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
+const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
bool isNorm, uint32_t vecSize)
{
+ // Look for an existing match.
+ for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
+ const Element *ee = rsc->mStateElement.mElements[ct];
+ if (!ee->getFieldCount() &&
+ (ee->getComponent().getType() == dt) &&
+ (ee->getComponent().getKind() == dk) &&
+ (ee->getComponent().getIsNormalized() == isNorm) &&
+ (ee->getComponent().getVectorSize() == vecSize)) {
+ // Match
+ ee->incUserRef();
+ return ee;
+ }
+ }
+
Element *e = new Element(rsc);
e->mComponent.set(dt, dk, isNorm, vecSize);
e->mBits = e->mComponent.getBits();
+ rsc->mStateElement.mElements.push(e);
return e;
}
-Element * Element::create(Context *rsc, size_t count, const Element **ein,
+const Element * Element::create(Context *rsc, size_t count, const Element **ein,
const char **nin, const size_t * lengths)
{
+ // Look for an existing match.
+ for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
+ const Element *ee = rsc->mStateElement.mElements[ct];
+ if (ee->getFieldCount() == count) {
+ bool match = true;
+ for (uint32_t i=0; i < count; i++) {
+ if ((ee->mFields[i].e.get() != ein[i]) ||
+ (ee->mFields[i].name.length() != lengths[i]) ||
+ (ee->mFields[i].name != nin[i])) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ ee->incUserRef();
+ return ee;
+ }
+ }
+ }
+
Element *e = new Element(rsc);
e->mFields = new ElementField_t [count];
e->mFieldCount = count;
-
for (size_t ct=0; ct < count; ct++) {
e->mFields[ct].e.set(ein[ct]);
e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
}
+ rsc->mStateElement.mElements.push(e);
return e;
}
@@ -168,6 +209,7 @@ ElementState::ElementState()
ElementState::~ElementState()
{
+ rsAssert(!mElements.size());
}
@@ -184,9 +226,9 @@ RsElement rsi_ElementCreate(Context *rsc,
uint32_t vecSize)
{
//LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize);
- Element *e = Element::create(rsc, dt, dk, norm, vecSize);
+ const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
e->incUserRef();
- return e;
+ return (RsElement)e;
}
RsElement rsi_ElementCreate2(Context *rsc,
@@ -196,9 +238,9 @@ RsElement rsi_ElementCreate2(Context *rsc,
const size_t * nameLengths)
{
//LOGE("rsi_ElementCreate2 %i", count);
- Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
+ const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
e->incUserRef();
- return e;
+ return (RsElement)e;
}
diff --git a/rsElement.h b/rsElement.h
index 777e8ee9..02a1ca2f 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -60,9 +60,9 @@ public:
void dumpLOGV(const char *prefix) const;
- static Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
+ static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
bool isNorm, uint32_t vecSize);
- static Element * create(Context *rsc, size_t count, const Element **,
+ static const Element * create(Context *rsc, size_t count, const Element **,
const char **, const size_t * lengths);
protected:
@@ -89,6 +89,8 @@ public:
ElementState();
~ElementState();
+ // Cache of all existing elements.
+ Vector<const Element *> mElements;
};
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
index 89c5b000..677413e1 100644
--- a/rsObjectBase.cpp
+++ b/rsObjectBase.cpp
@@ -191,6 +191,7 @@ void ObjectBase::dumpAll(Context *rsc)
LOGV("Dumping all objects");
const ObjectBase * o = rsc->mObjHead;
while (o) {
+ LOGV(" Object %p", o);
o->dumpLOGV(" ");
o = o->mNext;
}
diff --git a/rsObjectBase.h b/rsObjectBase.h
index f2470221..bb03b871 100644
--- a/rsObjectBase.h
+++ b/rsObjectBase.h
@@ -56,6 +56,7 @@ public:
protected:
const char *mAllocFile;
uint32_t mAllocLine;
+ Context *mRSC;
private:
void add() const;
@@ -64,7 +65,6 @@ private:
bool checkDelete() const;
char * mName;
- Context *mRSC;
mutable int32_t mSysRefCount;
mutable int32_t mUserRefCount;
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index 28f13d4e..a2b2df4d 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -364,7 +364,7 @@ ProgramVertexState::~ProgramVertexState()
void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
{
- RsElement e = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
+ RsElement e = (RsElement) Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
rsi_TypeBegin(rsc, e);
rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
diff --git a/rsType.cpp b/rsType.cpp
index 22a267a7..9d24c6cb 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -31,6 +31,12 @@ Type::Type(Context *rsc) : ObjectBase(rsc)
Type::~Type()
{
+ for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
+ if (mRSC->mStateType.mTypes[ct] == this) {
+ mRSC->mStateType.mTypes.removeAt(ct);
+ break;
+ }
+ }
if (mLODs) {
delete [] mLODs;
}
@@ -341,6 +347,18 @@ 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);
@@ -351,7 +369,7 @@ RsType rsi_TypeCreate(Context *rsc)
st->setDimFaces(stc->mFaces);
st->compute();
stc->mElement.clear();
-
+ stc->mTypes.push(st);
return st;
}
diff --git a/rsType.h b/rsType.h
index 4fa49335..28e62745 100644
--- a/rsType.h
+++ b/rsType.h
@@ -137,6 +137,10 @@ public:
uint32_t mLOD;
bool mFaces;
ObjectBaseRef<const Element> mElement;
+
+
+ // Cache of all existing types.
+ Vector<Type *> mTypes;
};