diff options
author | Jason Sams <rjsams@android.com> | 2010-08-09 18:13:33 -0700 |
---|---|---|
committer | Jason Sams <rjsams@android.com> | 2010-08-09 18:13:33 -0700 |
commit | b28ca96fd69be0d3d12106f81c415439d185b017 (patch) | |
tree | 827b9e5aced31b103fdacb7d01d14fbc9f966b34 /libs/rs | |
parent | 05716aa0a1f42b72e04a2f41d565f3ca6c3aea1e (diff) | |
download | frameworks_base-b28ca96fd69be0d3d12106f81c415439d185b017.zip frameworks_base-b28ca96fd69be0d3d12106f81c415439d185b017.tar.gz frameworks_base-b28ca96fd69be0d3d12106f81c415439d185b017.tar.bz2 |
Refcounting in allocations.
Change-Id: Ida2dfb404b2cd832e622d981d73a938d5bc5b821
Diffstat (limited to 'libs/rs')
-rw-r--r-- | libs/rs/rsAllocation.cpp | 42 | ||||
-rw-r--r-- | libs/rs/rsAllocation.h | 3 | ||||
-rw-r--r-- | libs/rs/rsComponent.cpp | 4 | ||||
-rw-r--r-- | libs/rs/rsComponent.h | 2 | ||||
-rw-r--r-- | libs/rs/rsElement.cpp | 59 | ||||
-rw-r--r-- | libs/rs/rsElement.h | 12 |
6 files changed, 111 insertions, 11 deletions
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 6560101..d62fa55 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -234,6 +234,12 @@ void Allocation::data(const void *data, uint32_t sizeBytes) LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes); return; } + + if (mType->getElement()->getHasReferences()) { + incRefs(data, sizeBytes / mType->getElement()->getSizeBytes()); + decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes()); + } + memcpy(mPtr, data, size); sendDirty(); mUploadDefered = true; @@ -256,6 +262,12 @@ void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32 mType->dumpLOGV("type info"); return; } + + if (mType->getElement()->getHasReferences()) { + incRefs(data, count); + decRefs(ptr, count); + } + memcpy(ptr, data, size); sendDirty(); mUploadDefered = true; @@ -279,6 +291,10 @@ void Allocation::subData(uint32_t xoff, uint32_t yoff, for (uint32_t line=yoff; line < (yoff+h); line++) { uint8_t * ptr = static_cast<uint8_t *>(mPtr); + if (mType->getElement()->getHasReferences()) { + incRefs(src, w); + decRefs(dst, w); + } memcpy(dst, src, lineSize); src += lineSize; dst += destW * eSize; @@ -387,6 +403,32 @@ void Allocation::sendDirty() const } } +void Allocation::incRefs(const void *ptr, size_t ct) const +{ + const uint8_t *p = static_cast<const uint8_t *>(ptr); + const Element *e = mType->getElement(); + uint32_t stride = e->getSizeBytes(); + + while (ct > 0) { + e->incRefs(p); + ct --; + p += stride; + } +} + +void Allocation::decRefs(const void *ptr, size_t ct) const +{ + const uint8_t *p = static_cast<const uint8_t *>(ptr); + const Element *e = mType->getElement(); + uint32_t stride = e->getSizeBytes(); + + while (ct > 0) { + e->decRefs(p); + ct --; + p += stride; + } +} + ///////////////// // diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index 8273165..177d5a4 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -81,6 +81,9 @@ public: bool getIsTexture() const {return mIsTexture;} bool getIsBufferObject() const {return mIsVertexBuffer;} + void incRefs(const void *ptr, size_t ct) const; + void decRefs(const void *ptr, size_t ct) const; + protected: void sendDirty() const; diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp index 8e509ad..fbaa75f 100644 --- a/libs/rs/rsComponent.cpp +++ b/libs/rs/rsComponent.cpp @@ -161,6 +161,10 @@ void Component::set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize) mBits = mTypeBits * mVectorSize; } +bool Component::isReference() const +{ + return (mType >= RS_TYPE_ELEMENT); +} diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h index 15fd5dd..a775051 100644 --- a/libs/rs/rsComponent.h +++ b/libs/rs/rsComponent.h @@ -51,6 +51,8 @@ public: void serialize(OStream *stream) const; void loadFromStream(IStream *stream); + bool isReference() const; + protected: RsDataType mType; RsDataKind mKind; diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index 37b8bd6..05902f9 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/rsElement.cpp @@ -34,6 +34,7 @@ Element::Element(Context *rsc) : ObjectBase(rsc) mAllocLine = __LINE__; mFields = NULL; mFieldCount = 0; + mHasReference = false; } @@ -53,6 +54,7 @@ void Element::clear() delete [] mFields; mFields = NULL; mFieldCount = 0; + mHasReference = false; } size_t Element::getSizeBits() const @@ -68,15 +70,6 @@ size_t Element::getSizeBits() const return total; } -size_t Element::getFieldOffsetBits(uint32_t componentNumber) const -{ - size_t offset = 0; - for (uint32_t ct = 0; ct < componentNumber; ct++) { - offset += mFields[ct].e->mBits; - } - return offset; -} - void Element::dumpLOGV(const char *prefix) const { ObjectBase::dumpLOGV(prefix); @@ -124,11 +117,14 @@ Element *Element::createFromStream(Context *rsc, IStream *stream) elem->mFieldCount = stream->loadU32(); if(elem->mFieldCount) { + uint32_t offset = 0; elem->mFields = new ElementField_t [elem->mFieldCount]; for(uint32_t ct = 0; ct < elem->mFieldCount; ct ++) { stream->loadString(&elem->mFields[ct].name); Element *fieldElem = Element::createFromStream(rsc, stream); elem->mFields[ct].e.set(fieldElem); + elem->mFields[ct].offsetBits = offset; + offset += fieldElem->getSizeBits(); } } @@ -193,6 +189,7 @@ const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk, Element *e = new Element(rsc); e->mComponent.set(dt, dk, isNorm, vecSize); e->mBits = e->mComponent.getBits(); + e->mHasReference = e->mComponent.isReference(); rsc->mStateElement.mElements.push(e); return e; } @@ -223,9 +220,16 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein, Element *e = new Element(rsc); e->mFields = new ElementField_t [count]; e->mFieldCount = count; + size_t bits = 0; for (size_t ct=0; ct < count; ct++) { e->mFields[ct].e.set(ein[ct]); e->mFields[ct].name.setTo(nin[ct], lengths[ct]); + e->mFields[ct].offsetBits = bits; + bits += ein[ct]->getSizeBits(); + + if (ein[ct]->mHasReference) { + e->mHasReference = true; + } } rsc->mStateElement.mElements.push(e); @@ -251,6 +255,43 @@ String8 Element::getGLSLType(uint32_t indent) const return s; } +void Element::incRefs(const void *ptr) const +{ + if (!mFieldCount) { + if (mComponent.isReference()) { + ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); + ObjectBase *ob = obp[0]; + ob->incSysRef(); + } + return; + } + + const uint8_t *p = static_cast<const uint8_t *>(ptr); + for (uint32_t i=0; i < mFieldCount; i++) { + if (mFields[i].e->mHasReference) { + mFields[i].e->incRefs(&p[mFields[i].offsetBits >> 3]); + } + } +} + +void Element::decRefs(const void *ptr) const +{ + if (!mFieldCount) { + if (mComponent.isReference()) { + ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); + ObjectBase *ob = obp[0]; + ob->decSysRef(); + } + return; + } + + const uint8_t *p = static_cast<const uint8_t *>(ptr); + for (uint32_t i=0; i < mFieldCount; i++) { + if (mFields[i].e->mHasReference) { + mFields[i].e->decRefs(&p[mFields[i].offsetBits >> 3]); + } + } +} ElementState::ElementState() diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h index 90e7cc8..b5dad7a 100644 --- a/libs/rs/rsElement.h +++ b/libs/rs/rsElement.h @@ -40,9 +40,11 @@ public: return (getSizeBits() + 7) >> 3; } - size_t getFieldOffsetBits(uint32_t componentNumber) const; + size_t getFieldOffsetBits(uint32_t componentNumber) const { + return mFields[componentNumber].offsetBits; + } size_t getFieldOffsetBytes(uint32_t componentNumber) const { - return (getFieldOffsetBits(componentNumber) + 7) >> 3; + return mFields[componentNumber].offsetBits >> 3; } uint32_t getFieldCount() const {return mFieldCount;} @@ -66,6 +68,10 @@ public: static const Element * create(Context *rsc, size_t count, const Element **, const char **, const size_t * lengths); + void incRefs(const void *) const; + void decRefs(const void *) const; + bool getHasReferences() const {return mHasReference;} + protected: // deallocate any components that are part of this element. void clear(); @@ -73,9 +79,11 @@ protected: typedef struct { String8 name; ObjectBaseRef<const Element> e; + uint32_t offsetBits; } ElementField_t; ElementField_t *mFields; size_t mFieldCount; + bool mHasReference; Element(Context *); |