diff options
author | Jason Sams <rjsams@android.com> | 2010-02-17 15:38:10 -0800 |
---|---|---|
committer | Jason Sams <rjsams@android.com> | 2010-02-17 15:38:10 -0800 |
commit | e4c487a75282e8a38a8b3defd49e7799c8670881 (patch) | |
tree | cce081d45415dfe54bdd65761e85f13046c91a82 /libs | |
parent | 5bc54073186a83472963934d4325c3b9d968892f (diff) | |
download | frameworks_base-e4c487a75282e8a38a8b3defd49e7799c8670881.zip frameworks_base-e4c487a75282e8a38a8b3defd49e7799c8670881.tar.gz frameworks_base-e4c487a75282e8a38a8b3defd49e7799c8670881.tar.bz2 |
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.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/rs/rsElement.cpp | 56 | ||||
-rw-r--r-- | libs/rs/rsElement.h | 6 | ||||
-rw-r--r-- | libs/rs/rsObjectBase.cpp | 1 | ||||
-rw-r--r-- | libs/rs/rsObjectBase.h | 2 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 2 | ||||
-rw-r--r-- | libs/rs/rsType.cpp | 20 | ||||
-rw-r--r-- | libs/rs/rsType.h | 4 |
7 files changed, 79 insertions, 12 deletions
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index 207ad15..6288bc4 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/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/libs/rs/rsElement.h b/libs/rs/rsElement.h index 777e8ee..02a1ca2 100644 --- a/libs/rs/rsElement.h +++ b/libs/rs/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/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp index 89c5b00..677413e 100644 --- a/libs/rs/rsObjectBase.cpp +++ b/libs/rs/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/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h index f247022..bb03b87 100644 --- a/libs/rs/rsObjectBase.h +++ b/libs/rs/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/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 28f13d4..a2b2df4 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/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/libs/rs/rsType.cpp b/libs/rs/rsType.cpp index 22a267a..9d24c6c 100644 --- a/libs/rs/rsType.cpp +++ b/libs/rs/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/libs/rs/rsType.h b/libs/rs/rsType.h index 4fa4933..28e6274 100644 --- a/libs/rs/rsType.h +++ b/libs/rs/rsType.h @@ -137,6 +137,10 @@ public: uint32_t mLOD; bool mFaces; ObjectBaseRef<const Element> mElement; + + + // Cache of all existing types. + Vector<Type *> mTypes; }; |