summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorAlex Sakhartchouk <alexst@google.com>2011-08-17 13:29:24 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-08-17 13:29:24 -0700
commit4270295ae8ffea9888c3bf881c07ba53d5e6f9c2 (patch)
tree24a63b455a529b2ea29052a9a46976697dbc798d /libs
parent5a9ffaa4cb58be595ba57d4078988d0496781063 (diff)
parent117abdbc67123654d0754b686c5bbdee6b44bcdd (diff)
downloadframeworks_base-4270295ae8ffea9888c3bf881c07ba53d5e6f9c2.zip
frameworks_base-4270295ae8ffea9888c3bf881c07ba53d5e6f9c2.tar.gz
frameworks_base-4270295ae8ffea9888c3bf881c07ba53d5e6f9c2.tar.bz2
Merge "Fixing asynchronous performance issues."
Diffstat (limited to 'libs')
-rw-r--r--libs/rs/rs.spec7
-rw-r--r--libs/rs/rsAllocation.cpp7
-rw-r--r--libs/rs/rsComponent.cpp30
-rw-r--r--libs/rs/rsComponent.h2
-rw-r--r--libs/rs/rsContext.cpp2
-rw-r--r--libs/rs/rsElement.cpp178
-rw-r--r--libs/rs/rsElement.h53
-rw-r--r--libs/rs/rsFileA3D.cpp4
-rw-r--r--libs/rs/rsFont.cpp70
-rw-r--r--libs/rs/rsFont.h1
-rw-r--r--libs/rs/rsObjectBase.h5
-rw-r--r--libs/rs/rsProgram.cpp2
-rw-r--r--libs/rs/rsProgramFragment.cpp14
-rw-r--r--libs/rs/rsProgramRaster.cpp59
-rw-r--r--libs/rs/rsProgramRaster.h28
-rw-r--r--libs/rs/rsProgramStore.cpp82
-rw-r--r--libs/rs/rsProgramStore.h25
-rw-r--r--libs/rs/rsProgramVertex.cpp50
-rw-r--r--libs/rs/rsSampler.cpp47
-rw-r--r--libs/rs/rsSampler.h36
-rw-r--r--libs/rs/rsType.cpp48
-rw-r--r--libs/rs/rsType.h20
22 files changed, 480 insertions, 290 deletions
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 0dea971..f277582 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -127,6 +127,7 @@ ObjDestroy {
}
ElementCreate {
+ direct
param RsDataType mType
param RsDataKind mKind
param bool mNormalized
@@ -135,6 +136,7 @@ ElementCreate {
}
ElementCreate2 {
+ direct
param const RsElement * elements
param const char ** names
param const uint32_t * arraySize
@@ -226,6 +228,7 @@ AllocationCopy2DRange {
}
SamplerCreate {
+ direct
param RsSamplerValue magFilter
param RsSamplerValue minFilter
param RsSamplerValue wrapS
@@ -311,6 +314,7 @@ ScriptCCreate {
ProgramStoreCreate {
+ direct
param bool colorMaskR
param bool colorMaskG
param bool colorMaskB
@@ -324,6 +328,7 @@ ProgramStoreCreate {
}
ProgramRasterCreate {
+ direct
param bool pointSmooth
param bool lineSmooth
param bool pointSprite
@@ -352,12 +357,14 @@ ProgramBindSampler {
}
ProgramFragmentCreate {
+ direct
param const char * shaderText
param const uint32_t * params
ret RsProgramFragment
}
ProgramVertexCreate {
+ direct
param const char * shaderText
param const uint32_t * params
ret RsProgramVertex
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index b59ade8..a366d49 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -252,6 +252,7 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
alloc->setName(name.string(), name.size());
+ type->decUserRef();
uint32_t count = dataSize / type->getElementSizeBytes();
@@ -307,12 +308,12 @@ void Allocation::resize1D(Context *rsc, uint32_t dimX) {
return;
}
- Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
+ ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX);
if (dimX < oldDimX) {
decRefs(getPtr(), oldDimX - dimX, dimX);
}
- rsc->mHal.funcs.allocation.resize(rsc, this, t, mHal.state.hasReferences);
- mHal.state.type.set(t);
+ rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
+ mHal.state.type.set(t.get());
updateCache();
}
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index e65febb..ce06306 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -176,36 +176,6 @@ bool Component::isReference() const {
return (mType >= RS_TYPE_ELEMENT);
}
-String8 Component::getGLSLType() const {
- if (mType == RS_TYPE_SIGNED_32) {
- switch (mVectorSize) {
- case 1: return String8("int");
- case 2: return String8("ivec2");
- case 3: return String8("ivec3");
- case 4: return String8("ivec4");
- }
- }
- if (mType == RS_TYPE_FLOAT_32) {
- switch (mVectorSize) {
- case 1: return String8("float");
- case 2: return String8("vec2");
- case 3: return String8("vec3");
- case 4: return String8("vec4");
- }
- }
- if ((mType == RS_TYPE_MATRIX_4X4) && (mVectorSize == 1)) {
- return String8("mat4");
- }
- if ((mType == RS_TYPE_MATRIX_3X3) && (mVectorSize == 1)) {
- return String8("mat3");
- }
- if ((mType == RS_TYPE_MATRIX_2X2) && (mVectorSize == 1)) {
- return String8("mat2");
- }
- return String8();
-}
-
-
static const char * gTypeBasicStrings[] = {
"NONE",
"F16",
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index a448f0e..6ddc990 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -32,10 +32,8 @@ public:
void set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize=1);
- String8 getGLSLType() const;
void dumpLOGV(const char *prefix) const;
-
RsDataType getType() const {return mType;}
RsDataKind getKind() const {return mKind;}
bool getIsNormalized() const {return mNormalized;}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index bffe3c0..f65dd47 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -240,6 +240,7 @@ void * Context::threadProc(void *vrsc) {
rsc->setProgramStore(NULL);
rsc->mStateFont.init(rsc);
rsc->setFont(NULL);
+ rsc->mStateSampler.init(rsc);
rsc->mFBOCache.init(rsc);
}
@@ -307,6 +308,7 @@ void Context::destroyWorkerThreadResources() {
mStateFragment.deinit(this);
mStateFragmentStore.deinit(this);
mStateFont.deinit(this);
+ mStateSampler.deinit(this);
mFBOCache.deinit(this);
}
//LOGV("destroyWorkerThreadResources 2");
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index b77b18a..36bbdf0 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -29,13 +29,16 @@ Element::Element(Context *rsc) : ObjectBase(rsc) {
}
Element::~Element() {
+ clear();
+}
+
+void Element::preDestroy() const {
for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
if (mRSC->mStateElement.mElements[ct] == this) {
mRSC->mStateElement.mElements.removeAt(ct);
break;
}
}
- clear();
}
void Element::clear() {
@@ -60,6 +63,7 @@ size_t Element::getSizeBits() const {
void Element::dumpLOGV(const char *prefix) const {
ObjectBase::dumpLOGV(prefix);
LOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes());
+ mComponent.dumpLOGV(prefix);
for (uint32_t ct = 0; ct < mFieldCount; ct++) {
LOGV("%s Element field index: %u ------------------", prefix, ct);
LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
@@ -97,60 +101,46 @@ Element *Element::createFromStream(Context *rsc, IStream *stream) {
String8 name;
stream->loadString(&name);
- Element *elem = new Element(rsc);
- elem->mComponent.loadFromStream(stream);
-
- elem->mFieldCount = stream->loadU32();
- if (elem->mFieldCount) {
- elem->mFields = new ElementField_t [elem->mFieldCount];
- for (uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
- stream->loadString(&elem->mFields[ct].name);
- elem->mFields[ct].arraySize = stream->loadU32();
- Element *fieldElem = Element::createFromStream(rsc, stream);
- elem->mFields[ct].e.set(fieldElem);
- }
- }
+ Component component;
+ component.loadFromStream(stream);
- // We need to check if this already exists
- for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
- Element *ee = rsc->mStateElement.mElements[ct];
- if (ee->isEqual(elem)) {
- ObjectBase::checkDelete(elem);
- ee->incUserRef();
- return ee;
- }
+ uint32_t fieldCount = stream->loadU32();
+ if (!fieldCount) {
+ return (Element *)Element::create(rsc,
+ component.getType(),
+ component.getKind(),
+ component.getIsNormalized(),
+ component.getVectorSize());;
}
- elem->compute();
- rsc->mStateElement.mElements.push(elem);
- return elem;
-}
-
-bool Element::isEqual(const Element *other) const {
- if (other == NULL) {
- return false;
+ const Element **subElems = new const Element *[fieldCount];
+ const char **subElemNames = new const char *[fieldCount];
+ size_t *subElemNamesLengths = new size_t[fieldCount];
+ uint32_t *arraySizes = new uint32_t[fieldCount];
+
+ String8 elemName;
+ for (uint32_t ct = 0; ct < fieldCount; ct ++) {
+ stream->loadString(&elemName);
+ subElemNamesLengths[ct] = elemName.length();
+ char *tmpName = new char[subElemNamesLengths[ct]];
+ memcpy(tmpName, elemName.string(), subElemNamesLengths[ct]);
+ subElemNames[ct] = tmpName;
+ arraySizes[ct] = stream->loadU32();
+ subElems[ct] = Element::createFromStream(rsc, stream);
}
- if (!other->getFieldCount() && !mFieldCount) {
- if ((other->getType() == getType()) &&
- (other->getKind() == getKind()) &&
- (other->getComponent().getIsNormalized() == getComponent().getIsNormalized()) &&
- (other->getComponent().getVectorSize() == getComponent().getVectorSize())) {
- return true;
- }
- return false;
- }
- if (other->getFieldCount() == mFieldCount) {
- for (uint32_t i=0; i < mFieldCount; i++) {
- if ((!other->mFields[i].e->isEqual(mFields[i].e.get())) ||
- (other->mFields[i].name.length() != mFields[i].name.length()) ||
- (other->mFields[i].name != mFields[i].name) ||
- (other->mFields[i].arraySize != mFields[i].arraySize)) {
- return false;
- }
- }
- return true;
+
+ const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames,
+ subElemNamesLengths, arraySizes);
+ for (uint32_t ct = 0; ct < fieldCount; ct ++) {
+ delete [] subElemNames[ct];
+ subElems[ct]->decUserRef();
}
- return false;
+ delete[] subElems;
+ delete[] subElemNames;
+ delete[] subElemNamesLengths;
+ delete[] arraySizes;
+
+ return (Element *)elem;
}
void Element::compute() {
@@ -172,9 +162,11 @@ void Element::compute() {
}
-const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
+ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk,
bool isNorm, uint32_t vecSize) {
+ ObjectBaseRef<const Element> returnRef;
// Look for an existing match.
+ ObjectBase::asyncLock();
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
const Element *ee = rsc->mStateElement.mElements[ct];
if (!ee->getFieldCount() &&
@@ -183,21 +175,31 @@ const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
(ee->getComponent().getIsNormalized() == isNorm) &&
(ee->getComponent().getVectorSize() == vecSize)) {
// Match
- ee->incUserRef();
+ returnRef.set(ee);
+ ObjectBase::asyncUnlock();
return ee;
}
}
+ ObjectBase::asyncUnlock();
Element *e = new Element(rsc);
+ returnRef.set(e);
e->mComponent.set(dt, dk, isNorm, vecSize);
e->compute();
+
+ ObjectBase::asyncLock();
rsc->mStateElement.mElements.push(e);
- return e;
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
}
-const Element * Element::create(Context *rsc, size_t count, const Element **ein,
+ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein,
const char **nin, const size_t * lengths, const uint32_t *asin) {
+
+ ObjectBaseRef<const Element> returnRef;
// Look for an existing match.
+ ObjectBase::asyncLock();
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
const Element *ee = rsc->mStateElement.mElements[ct];
if (ee->getFieldCount() == count) {
@@ -212,13 +214,16 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein,
}
}
if (match) {
- ee->incUserRef();
- return ee;
+ returnRef.set(ee);
+ ObjectBase::asyncUnlock();
+ return returnRef;
}
}
}
+ ObjectBase::asyncUnlock();
Element *e = new Element(rsc);
+ returnRef.set(e);
e->mFields = new ElementField_t [count];
e->mFieldCount = count;
for (size_t ct=0; ct < count; ct++) {
@@ -228,26 +233,11 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein,
}
e->compute();
+ ObjectBase::asyncLock();
rsc->mStateElement.mElements.push(e);
- return e;
-}
-
-String8 Element::getGLSLType(uint32_t indent) const {
- String8 s;
- for (uint32_t ct=0; ct < indent; ct++) {
- s.append(" ");
- }
+ ObjectBase::asyncUnlock();
- if (!mFieldCount) {
- // Basic component.
- s.append(mComponent.getGLSLType());
- } else {
- rsAssert(0);
- //s.append("struct ");
- //s.append(getCStructBody(indent));
- }
-
- return s;
+ return returnRef;
}
void Element::incRefs(const void *ptr) const {
@@ -294,6 +284,23 @@ void Element::decRefs(const void *ptr) const {
}
}
+void Element::Builder::add(const Element *e, const char *nameStr, uint32_t arraySize) {
+ mBuilderElementRefs.push(ObjectBaseRef<const Element>(e));
+ mBuilderElements.push(e);
+ mBuilderNameStrings.push(nameStr);
+ mBuilderNameLengths.push(strlen(nameStr));
+ mBuilderArrays.push(arraySize);
+
+}
+
+ObjectBaseRef<const Element> Element::Builder::create(Context *rsc) {
+ return Element::createRef(rsc, mBuilderElements.size(),
+ &(mBuilderElements.editArray()[0]),
+ &(mBuilderNameStrings.editArray()[0]),
+ mBuilderNameLengths.editArray(),
+ mBuilderArrays.editArray());
+}
+
ElementState::ElementState() {
const uint32_t initialCapacity = 32;
@@ -324,10 +331,10 @@ void ElementState::elementBuilderAdd(const Element *e, const char *nameStr, uint
const Element *ElementState::elementBuilderCreate(Context *rsc) {
return Element::create(rsc, mBuilderElements.size(),
- &(mBuilderElements.editArray()[0]),
- &(mBuilderNameStrings.editArray()[0]),
- mBuilderNameLengths.editArray(),
- mBuilderArrays.editArray());
+ &(mBuilderElements.editArray()[0]),
+ &(mBuilderNameStrings.editArray()[0]),
+ mBuilderNameLengths.editArray(),
+ mBuilderArrays.editArray());
}
@@ -342,9 +349,7 @@ RsElement rsi_ElementCreate(Context *rsc,
RsDataKind dk,
bool norm,
uint32_t vecSize) {
- const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
- e->incUserRef();
- return (RsElement)e;
+ return (RsElement)Element::create(rsc, dt, dk, norm, vecSize);
}
@@ -358,15 +363,15 @@ RsElement rsi_ElementCreate2(Context *rsc,
const uint32_t * arraySizes,
size_t arraySizes_length) {
- const Element *e = Element::create(rsc, ein_length, (const Element **)ein, names, nameLengths, arraySizes);
- e->incUserRef();
- return (RsElement)e;
+ return (RsElement)Element::create(rsc, ein_length, (const Element **)ein,
+ names, nameLengths, arraySizes);
}
}
}
-void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) {
+void rsaElementGetNativeData(RsContext con, RsElement elem,
+ uint32_t *elemData, uint32_t elemDataSize) {
rsAssert(elemDataSize == 5);
// we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
Element *e = static_cast<Element *>(elem);
@@ -378,7 +383,8 @@ void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData,
(*elemData++) = e->getFieldCount();
}
-void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) {
+void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids,
+ const char **names, uint32_t dataSize) {
Element *e = static_cast<Element *>(elem);
rsAssert(e->getFieldCount() == dataSize);
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 26e2760..c3ef250 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -28,8 +28,17 @@ namespace renderscript {
// An element is a group of Components that occupies one cell in a structure.
class Element : public ObjectBase {
public:
- ~Element();
-
+ class Builder {
+ public:
+ void add(const Element *e, const char *nameStr, uint32_t arraySize);
+ ObjectBaseRef<const Element> create(Context *rsc);
+ private:
+ Vector<ObjectBaseRef<const Element> > mBuilderElementRefs;
+ Vector<const Element *> mBuilderElements;
+ Vector<const char*> mBuilderNameStrings;
+ Vector<size_t> mBuilderNameLengths;
+ Vector<uint32_t> mBuilderArrays;
+ };
uint32_t getGLType() const;
uint32_t getGLFormat() const;
@@ -55,24 +64,45 @@ public:
RsDataKind getKind() const {return mComponent.getKind();}
uint32_t getBits() const {return mBits;}
- String8 getGLSLType(uint32_t indent=0) const;
-
void dumpLOGV(const char *prefix) const;
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_ELEMENT; }
static Element *createFromStream(Context *rsc, IStream *stream);
- static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
- bool isNorm, uint32_t vecSize);
- static const Element * create(Context *rsc, size_t count, const Element **,
- const char **, const size_t * lengths, const uint32_t *asin);
+ static ObjectBaseRef<const Element> createRef(Context *rsc,
+ RsDataType dt,
+ RsDataKind dk,
+ bool isNorm,
+ uint32_t vecSize);
+ static ObjectBaseRef<const Element> createRef(Context *rsc, size_t count,
+ const Element **,
+ const char **,
+ const size_t * lengths,
+ const uint32_t *asin);
+
+ static const Element* create(Context *rsc,
+ RsDataType dt,
+ RsDataKind dk,
+ bool isNorm,
+ uint32_t vecSize) {
+ ObjectBaseRef<const Element> elem = createRef(rsc, dt, dk, isNorm, vecSize);
+ elem->incUserRef();
+ return elem.get();
+ }
+ static const Element* create(Context *rsc, size_t count,
+ const Element **ein,
+ const char **nin,
+ const size_t * lengths,
+ const uint32_t *asin) {
+ ObjectBaseRef<const Element> elem = createRef(rsc, count, ein, nin, lengths, asin);
+ elem->incUserRef();
+ return elem.get();
+ }
void incRefs(const void *) const;
void decRefs(const void *) const;
bool getHasReferences() const {return mHasReference;}
- bool isEqual(const Element *other) const;
-
protected:
// deallocate any components that are part of this element.
void clear();
@@ -88,12 +118,15 @@ protected:
bool mHasReference;
+ virtual ~Element();
Element(Context *);
Component mComponent;
uint32_t mBits;
void compute();
+
+ virtual void preDestroy() const;
};
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index cd02c24..df5dc12 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -68,7 +68,7 @@ void FileA3D::parseHeader(IStream *headerStream) {
for (uint32_t i = 0; i < numIndexEntries; i ++) {
A3DIndexEntry *entry = new A3DIndexEntry();
headerStream->loadString(&entry->mObjectName);
- LOGV("Header data, entry name = %s", entry->mObjectName.string());
+ //LOGV("Header data, entry name = %s", entry->mObjectName.string());
entry->mType = (RsA3DClassID)headerStream->loadU32();
if (mUse64BitOffsets){
entry->mOffset = headerStream->loadOffset();
@@ -369,7 +369,7 @@ RsObjectBase rsaFileA3DGetEntryByIndex(RsContext con, uint32_t index, RsFile fil
}
ObjectBase *obj = fa3d->initializeFromEntry(index);
- LOGV("Returning object with name %s", obj->getName());
+ //LOGV("Returning object with name %s", obj->getName());
return obj;
}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 3917ca1..7efed9d 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -490,49 +490,47 @@ void FontState::initRenderState() {
shaderString.append(" gl_FragColor = col;\n");
shaderString.append("}\n");
- const Element *colorElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
- const Element *gammaElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
- mRSC->mStateElement.elementBuilderBegin();
- mRSC->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
- mRSC->mStateElement.elementBuilderAdd(gammaElem, "Gamma", 1);
- const Element *constInput = mRSC->mStateElement.elementBuilderCreate(mRSC);
+ ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
+ Element::Builder builder;
+ builder.add(colorElem.get(), "Color", 1);
+ builder.add(gammaElem.get(), "Gamma", 1);
+ ObjectBaseRef<const Element> constInput = builder.create(mRSC);
- Type *inputType = Type::getType(mRSC, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(mRSC, constInput.get(), 1, 0, 0, false, false);
uint32_t tmp[4];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
tmp[2] = RS_PROGRAM_PARAM_TEXTURE_TYPE;
tmp[3] = RS_TEXTURE_2D;
- mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType,
+ mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS));
ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(),
shaderString.length(), tmp, 4);
mFontShaderF.set(pf);
mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0);
- Sampler *sampler = new Sampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
- RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP);
- mFontSampler.set(sampler);
- mFontShaderF->bindSampler(mRSC, 0, sampler);
-
- ProgramStore *fontStore = new ProgramStore(mRSC, true, true, true, true,
- false, false,
- RS_BLEND_SRC_SRC_ALPHA,
- RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
- RS_DEPTH_FUNC_ALWAYS);
- mFontProgramStore.set(fontStore);
+ mFontSampler.set(Sampler::getSampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
+ RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP).get());
+ mFontShaderF->bindSampler(mRSC, 0, mFontSampler.get());
+
+ mFontProgramStore.set(ProgramStore::getProgramStore(mRSC, true, true, true, true,
+ false, false,
+ RS_BLEND_SRC_SRC_ALPHA,
+ RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
+ RS_DEPTH_FUNC_ALWAYS).get());
mFontProgramStore->init();
}
void FontState::initTextTexture() {
- const Element *alphaElem = Element::create(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
+ ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
// We will allocate a texture to initially hold 32 character bitmaps
- Type *texType = Type::getType(mRSC, alphaElem, 1024, 256, 0, false, false);
+ ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), 1024, 256, 0, false, false);
- Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType,
+ Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE);
mTextTexture.set(cacheAlloc);
mTextTexture->syncAll(mRSC, RS_ALLOCATION_USAGE_SCRIPT);
@@ -557,11 +555,11 @@ void FontState::initTextTexture() {
// Avoid having to reallocate memory and render quad by quad
void FontState::initVertexArrayBuffers() {
// Now lets write index data
- const Element *indexElem = Element::create(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
+ ObjectBaseRef<const Element> indexElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
uint32_t numIndicies = mMaxNumberOfQuads * 6;
- Type *indexType = Type::getType(mRSC, indexElem, numIndicies, 0, 0, false, false);
+ ObjectBaseRef<Type> indexType = Type::getTypeRef(mRSC, indexElem.get(), numIndicies, 0, 0, false, false);
- Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType,
+ Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType.get(),
RS_ALLOCATION_USAGE_SCRIPT |
RS_ALLOCATION_USAGE_GRAPHICS_VERTEX);
uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr();
@@ -582,19 +580,19 @@ void FontState::initVertexArrayBuffers() {
indexAlloc->sendDirty(mRSC);
- const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
- const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
+ ObjectBaseRef<const Element> posElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
+ ObjectBaseRef<const Element> texElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
- mRSC->mStateElement.elementBuilderBegin();
- mRSC->mStateElement.elementBuilderAdd(posElem, "position", 1);
- mRSC->mStateElement.elementBuilderAdd(texElem, "texture0", 1);
- const Element *vertexDataElem = mRSC->mStateElement.elementBuilderCreate(mRSC);
+ Element::Builder builder;
+ builder.add(posElem.get(), "position", 1);
+ builder.add(texElem.get(), "texture0", 1);
+ ObjectBaseRef<const Element> vertexDataElem = builder.create(mRSC);
- Type *vertexDataType = Type::getType(mRSC, vertexDataElem,
- mMaxNumberOfQuads * 4,
- 0, 0, false, false);
+ ObjectBaseRef<Type> vertexDataType = Type::getTypeRef(mRSC, vertexDataElem.get(),
+ mMaxNumberOfQuads * 4,
+ 0, 0, false, false);
- Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType,
+ Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType.get(),
RS_ALLOCATION_USAGE_SCRIPT);
mTextMeshPtr = (float*)vertexAlloc->getPtr();
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index b0e1430..679591c 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -146,7 +146,6 @@ public:
void deinit(Context *rsc);
ObjectBaseRef<Font> mDefault;
- ObjectBaseRef<Font> mLast;
void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
uint32_t startIndex = 0, int numGlyphs = -1,
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index 01850f1..c7cfb0e 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -114,7 +114,10 @@ public:
}
ObjectBaseRef & operator= (const ObjectBaseRef &ref) {
- return ObjectBaseRef(ref);
+ if (&ref != this) {
+ set(ref);
+ }
+ return *this;
}
~ObjectBaseRef() {
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index b1d8f48..33eb422 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -116,7 +116,7 @@ void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
return;
}
- if (!alloc->getType()->isEqual(mHal.state.constantTypes[slot].get())) {
+ if (alloc->getType() != mHal.state.constantTypes[slot].get()) {
LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
slot, (uint32_t)this);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 356ff77..ff29520 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -97,18 +97,18 @@ void ProgramFragmentState::init(Context *rsc) {
shaderString.append(" gl_FragColor = col;\n");
shaderString.append("}\n");
- const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
- const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
+ ObjectBaseRef<const Element> colorElem = Element::createRef(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ Element::Builder builder;
+ builder.add(colorElem.get(), "Color", 1);
+ ObjectBaseRef<const Element> constInput = builder.create(rsc);
- Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false);
uint32_t tmp[2];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
- Allocation *constAlloc = Allocation::createAllocation(rsc, inputType,
+ Allocation *constAlloc = Allocation::createAllocation(rsc, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
shaderString.length(), tmp, 2);
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
index 435561d..945b5ec 100644
--- a/libs/rs/rsProgramRaster.cpp
+++ b/libs/rs/rsProgramRaster.cpp
@@ -37,6 +37,15 @@ ProgramRaster::ProgramRaster(Context *rsc, bool pointSmooth,
rsc->mHal.funcs.raster.init(rsc, this);
}
+void ProgramRaster::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateRaster.mRasterPrograms.size(); ct++) {
+ if (mRSC->mStateRaster.mRasterPrograms[ct] == this) {
+ mRSC->mStateRaster.mRasterPrograms.removeAt(ct);
+ break;
+ }
+ }
+}
+
ProgramRaster::~ProgramRaster() {
mRSC->mHal.funcs.raster.destroy(mRSC, this);
}
@@ -65,8 +74,8 @@ ProgramRasterState::~ProgramRasterState() {
}
void ProgramRasterState::init(Context *rsc) {
- ProgramRaster *pr = new ProgramRaster(rsc, false, false, false, 1.f, RS_CULL_BACK);
- mDefault.set(pr);
+ mDefault.set(ProgramRaster::getProgramRaster(rsc, false, false,
+ false, 1.f, RS_CULL_BACK).get());
}
void ProgramRasterState::deinit(Context *rsc) {
@@ -74,19 +83,47 @@ void ProgramRasterState::deinit(Context *rsc) {
mLast.clear();
}
-namespace android {
-namespace renderscript {
+ObjectBaseRef<ProgramRaster> ProgramRaster::getProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull) {
+ ObjectBaseRef<ProgramRaster> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateRaster.mRasterPrograms.size(); ct++) {
+ ProgramRaster *existing = rsc->mStateRaster.mRasterPrograms[ct];
+ if (existing->mHal.state.pointSmooth != pointSmooth) continue;
+ if (existing->mHal.state.lineSmooth != lineSmooth) continue;
+ if (existing->mHal.state.pointSprite != pointSprite) continue;
+ if (existing->mHal.state.lineWidth != lineWidth) continue;
+ if (existing->mHal.state.cull != cull) continue;
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
-RsProgramRaster rsi_ProgramRasterCreate(Context * rsc,
- bool pointSmooth,
- bool lineSmooth,
- bool pointSprite,
- float lineWidth,
- RsCullMode cull) {
ProgramRaster *pr = new ProgramRaster(rsc, pointSmooth,
lineSmooth, pointSprite, lineWidth, cull);
+ returnRef.set(pr);
+
+ ObjectBase::asyncLock();
+ rsc->mStateRaster.mRasterPrograms.push(pr);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
+namespace android {
+namespace renderscript {
+
+RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, bool pointSmooth, bool lineSmooth,
+ bool pointSprite, float lineWidth, RsCullMode cull) {
+ ObjectBaseRef<ProgramRaster> pr = ProgramRaster::getProgramRaster(rsc, pointSmooth, lineSmooth,
+ pointSprite, lineWidth, cull);
pr->incUserRef();
- return pr;
+ return pr.get();
}
}
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
index efdb948..09d7d54 100644
--- a/libs/rs/rsProgramRaster.h
+++ b/libs/rs/rsProgramRaster.h
@@ -27,19 +27,17 @@ class ProgramRasterState;
class ProgramRaster : public ProgramBase {
public:
- ProgramRaster(Context *rsc,
- bool pointSmooth,
- bool lineSmooth,
- bool pointSprite,
- float lineWidth,
- RsCullMode cull);
- virtual ~ProgramRaster();
-
virtual void setup(const Context *, ProgramRasterState *);
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_RASTER; }
static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
+ static ObjectBaseRef<ProgramRaster> getProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull);
struct Hal {
mutable void *drv;
@@ -55,6 +53,17 @@ public:
Hal mHal;
protected:
+ virtual void preDestroy() const;
+ virtual ~ProgramRaster();
+
+private:
+ ProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull);
+
};
class ProgramRasterState {
@@ -66,6 +75,9 @@ public:
ObjectBaseRef<ProgramRaster> mDefault;
ObjectBaseRef<ProgramRaster> mLast;
+
+ // Cache of all existing raster programs.
+ Vector<ProgramRaster *> mRasterPrograms;
};
diff --git a/libs/rs/rsProgramStore.cpp b/libs/rs/rsProgramStore.cpp
index 8fe890b..7e25a22 100644
--- a/libs/rs/rsProgramStore.cpp
+++ b/libs/rs/rsProgramStore.cpp
@@ -41,6 +41,15 @@ ProgramStore::ProgramStore(Context *rsc,
mHal.state.depthFunc = depthFunc;
}
+void ProgramStore::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateFragmentStore.mStorePrograms.size(); ct++) {
+ if (mRSC->mStateFragmentStore.mStorePrograms[ct] == this) {
+ mRSC->mStateFragmentStore.mStorePrograms.removeAt(ct);
+ break;
+ }
+ }
+}
+
ProgramStore::~ProgramStore() {
mRSC->mHal.funcs.store.destroy(mRSC, this);
}
@@ -71,14 +80,58 @@ ProgramStoreState::ProgramStoreState() {
ProgramStoreState::~ProgramStoreState() {
}
+ObjectBaseRef<ProgramStore> ProgramStore::getProgramStore(Context *rsc,
+ bool colorMaskR,
+ bool colorMaskG,
+ bool colorMaskB,
+ bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc,
+ RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc) {
+ ObjectBaseRef<ProgramStore> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateFragmentStore.mStorePrograms.size(); ct++) {
+ ProgramStore *existing = rsc->mStateFragmentStore.mStorePrograms[ct];
+ if (existing->mHal.state.ditherEnable != ditherEnable) continue;
+ if (existing->mHal.state.colorRWriteEnable != colorMaskR) continue;
+ if (existing->mHal.state.colorGWriteEnable != colorMaskG) continue;
+ if (existing->mHal.state.colorBWriteEnable != colorMaskB) continue;
+ if (existing->mHal.state.colorAWriteEnable != colorMaskA) continue;
+ if (existing->mHal.state.blendSrc != srcFunc) continue;
+ if (existing->mHal.state.blendDst != destFunc) continue;
+ if (existing->mHal.state.depthWriteEnable != depthMask) continue;
+ if (existing->mHal.state.depthFunc != depthFunc) continue;
+
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
+
+ ProgramStore *pfs = new ProgramStore(rsc,
+ colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+ depthMask, ditherEnable,
+ srcFunc, destFunc, depthFunc);
+ returnRef.set(pfs);
+
+ pfs->init();
+
+ ObjectBase::asyncLock();
+ rsc->mStateFragmentStore.mStorePrograms.push(pfs);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
+
+
void ProgramStoreState::init(Context *rsc) {
- ProgramStore *ps = new ProgramStore(rsc,
- true, true, true, true,
- true, true,
- RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
- RS_DEPTH_FUNC_LESS);
- ps->init();
- mDefault.set(ps);
+ mDefault.set(ProgramStore::getProgramStore(rsc,
+ true, true, true, true,
+ true, true,
+ RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
+ RS_DEPTH_FUNC_LESS).get());
}
void ProgramStoreState::deinit(Context *rsc) {
@@ -96,13 +149,14 @@ RsProgramStore rsi_ProgramStoreCreate(Context *rsc,
RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
RsDepthFunc depthFunc) {
- ProgramStore *pfs = new ProgramStore(rsc,
- colorMaskR, colorMaskG, colorMaskB, colorMaskA,
- depthMask, ditherEnable,
- srcFunc, destFunc, depthFunc);
- pfs->init();
- pfs->incUserRef();
- return pfs;
+
+ ObjectBaseRef<ProgramStore> ps = ProgramStore::getProgramStore(rsc,
+ colorMaskR, colorMaskG,
+ colorMaskB, colorMaskA,
+ depthMask, ditherEnable,
+ srcFunc, destFunc, depthFunc);
+ ps->incUserRef();
+ return ps.get();
}
}
diff --git a/libs/rs/rsProgramStore.h b/libs/rs/rsProgramStore.h
index 77b3881..e21f039 100644
--- a/libs/rs/rsProgramStore.h
+++ b/libs/rs/rsProgramStore.h
@@ -28,18 +28,17 @@ class ProgramStoreState;
class ProgramStore : public ProgramBase {
public:
- ProgramStore(Context *,
- bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
- bool depthMask, bool ditherEnable,
- RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
- RsDepthFunc depthFunc);
- virtual ~ProgramStore();
-
virtual void setup(const Context *, ProgramStoreState *);
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_STORE; }
static ProgramStore *createFromStream(Context *rsc, IStream *stream);
+ static ObjectBaseRef<ProgramStore> getProgramStore(Context *,
+ bool colorMaskR, bool colorMaskG,
+ bool colorMaskB, bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc);
void init();
@@ -66,6 +65,15 @@ public:
Hal mHal;
protected:
+ virtual void preDestroy() const;
+ virtual ~ProgramStore();
+
+private:
+ ProgramStore(Context *,
+ bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc);
};
class ProgramStoreState {
@@ -77,6 +85,9 @@ public:
ObjectBaseRef<ProgramStore> mDefault;
ObjectBaseRef<ProgramStore> mLast;
+
+ // Cache of all existing store programs.
+ Vector<ProgramStore *> mStorePrograms;
};
}
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 058a456..51cb2a8a 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -150,26 +150,30 @@ ProgramVertexState::~ProgramVertexState() {
}
void ProgramVertexState::init(Context *rsc) {
- const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1);
- const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
- const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
- const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
-
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1);
- const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
-
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1);
- rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1);
- rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1);
- rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1);
- const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc);
-
- Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<const Element> matrixElem = Element::createRef(rsc, RS_TYPE_MATRIX_4X4,
+ RS_KIND_USER, false, 1);
+ ObjectBaseRef<const Element> f2Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 2);
+ ObjectBaseRef<const Element> f3Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 3);
+ ObjectBaseRef<const Element> f4Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 4);
+
+ Element::Builder constBuilder;
+ constBuilder.add(matrixElem.get(), "MV", 1);
+ constBuilder.add(matrixElem.get(), "P", 1);
+ constBuilder.add(matrixElem.get(), "TexMatrix", 1);
+ constBuilder.add(matrixElem.get(), "MVP", 1);
+ ObjectBaseRef<const Element> constInput = constBuilder.create(rsc);
+
+ Element::Builder inputBuilder;
+ inputBuilder.add(f4Elem.get(), "position", 1);
+ inputBuilder.add(f4Elem.get(), "color", 1);
+ inputBuilder.add(f3Elem.get(), "normal", 1);
+ inputBuilder.add(f2Elem.get(), "texture0", 1);
+ ObjectBaseRef<const Element> attrElem = inputBuilder.create(rsc);
+
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false);
String8 shaderString(RS_SHADER_INTERNAL);
shaderString.append("varying vec4 varColor;\n");
@@ -183,13 +187,13 @@ void ProgramVertexState::init(Context *rsc) {
uint32_t tmp[4];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
tmp[2] = RS_PROGRAM_PARAM_INPUT;
- tmp[3] = (uint32_t)attrElem;
+ tmp[3] = (uint32_t)attrElem.get();
ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
shaderString.length(), tmp, 4);
- Allocation *alloc = Allocation::createAllocation(rsc, inputType,
+ Allocation *alloc = Allocation::createAllocation(rsc, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
pv->bindAllocation(rsc, alloc, 0);
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 2a05d16..5fc64a4 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -48,6 +48,15 @@ Sampler::~Sampler() {
mRSC->mHal.funcs.sampler.destroy(mRSC, this);
}
+void Sampler::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateSampler.mAllSamplers.size(); ct++) {
+ if (mRSC->mStateSampler.mAllSamplers[ct] == this) {
+ mRSC->mStateSampler.mAllSamplers.removeAt(ct);
+ break;
+ }
+ }
+}
+
void Sampler::bindToContext(SamplerState *ss, uint32_t slot) {
ss->mSamplers[slot].set(this);
mBoundSlot = slot;
@@ -66,6 +75,39 @@ Sampler *Sampler::createFromStream(Context *rsc, IStream *stream) {
return NULL;
}
+ObjectBaseRef<Sampler> Sampler::getSampler(Context *rsc,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso) {
+ ObjectBaseRef<Sampler> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateSampler.mAllSamplers.size(); ct++) {
+ Sampler *existing = rsc->mStateSampler.mAllSamplers[ct];
+ if (existing->mHal.state.magFilter != magFilter) continue;
+ if (existing->mHal.state.minFilter != minFilter ) continue;
+ if (existing->mHal.state.wrapS != wrapS) continue;
+ if (existing->mHal.state.wrapT != wrapT) continue;
+ if (existing->mHal.state.wrapR != wrapR) continue;
+ if (existing->mHal.state.aniso != aniso) continue;
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
+
+ Sampler *s = new Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+ returnRef.set(s);
+
+ ObjectBase::asyncLock();
+ rsc->mStateSampler.mAllSamplers.push(s);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
////////////////////////////////
namespace android {
@@ -78,9 +120,10 @@ RsSampler rsi_SamplerCreate(Context * rsc,
RsSamplerValue wrapT,
RsSamplerValue wrapR,
float aniso) {
- Sampler * s = new Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+ ObjectBaseRef<Sampler> s = Sampler::getSampler(rsc, magFilter, minFilter,
+ wrapS, wrapT, wrapR, aniso);
s->incUserRef();
- return s;
+ return s.get();
}
}}
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index 90b6082..e698132 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -30,16 +30,13 @@ class SamplerState;
class Sampler : public ObjectBase {
public:
- Sampler(Context *,
- RsSamplerValue magFilter,
- RsSamplerValue minFilter,
- RsSamplerValue wrapS,
- RsSamplerValue wrapT,
- RsSamplerValue wrapR,
- float aniso = 1.0f);
-
- virtual ~Sampler();
-
+ static ObjectBaseRef<Sampler> getSampler(Context *,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso = 1.0f);
void bindToContext(SamplerState *, uint32_t slot);
void unbindFromContext(SamplerState *);
@@ -65,14 +62,33 @@ public:
protected:
int32_t mBoundSlot;
+ virtual void preDestroy() const;
+ virtual ~Sampler();
+
private:
Sampler(Context *);
+ Sampler(Context *,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso = 1.0f);
};
class SamplerState {
public:
ObjectBaseRef<Sampler> mSamplers[RS_MAX_SAMPLER_SLOT];
+ void init(Context *rsc) {
+ }
+ void deinit(Context *rsc) {
+ for (uint32_t i = 0; i < RS_MAX_SAMPLER_SLOT; i ++) {
+ mSamplers[i].clear();
+ }
+ }
+ // Cache of all existing raster programs.
+ Vector<Sampler *> mAllSamplers;
};
}
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 10e3182..9a6a31b 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -25,7 +25,7 @@ Type::Type(Context *rsc) : ObjectBase(rsc) {
clear();
}
-void Type::preDestroy() {
+void Type::preDestroy() const {
for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
if (mRSC->mStateType.mTypes[ct] == this) {
mRSC->mStateType.mTypes.removeAt(ct);
@@ -58,6 +58,7 @@ TypeState::TypeState() {
}
TypeState::~TypeState() {
+ rsAssert(!mTypes.size());
}
size_t Type::getOffsetForFace(uint32_t face) const {
@@ -183,7 +184,9 @@ Type *Type::createFromStream(Context *rsc, IStream *stream) {
uint32_t z = stream->loadU32();
uint8_t lod = stream->loadU8();
uint8_t faces = stream->loadU8();
- return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
+ Type *type = Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
+ elem->decUserRef();
+ return type;
}
bool Type::getIsNp2() const {
@@ -203,24 +206,11 @@ bool Type::getIsNp2() const {
return false;
}
-bool Type::isEqual(const Type *other) const {
- if (other == NULL) {
- return false;
- }
- if (other->getElement()->isEqual(getElement()) &&
- other->getDimX() == mDimX &&
- other->getDimY() == mDimY &&
- other->getDimZ() == mDimZ &&
- other->getDimLOD() == mDimLOD &&
- other->getDimFaces() == mFaces) {
- return true;
- }
- return false;
-}
+ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces) {
+ ObjectBaseRef<Type> returnRef;
-Type * Type::getType(Context *rsc, const Element *e,
- uint32_t dimX, uint32_t dimY, uint32_t dimZ,
- bool dimLOD, bool dimFaces) {
TypeState * stc = &rsc->mStateType;
ObjectBase::asyncLock();
@@ -232,14 +222,15 @@ Type * Type::getType(Context *rsc, const Element *e,
if (t->getDimZ() != dimZ) continue;
if (t->getDimLOD() != dimLOD) continue;
if (t->getDimFaces() != dimFaces) continue;
- t->incUserRef();
+ returnRef.set(t);
ObjectBase::asyncUnlock();
- return t;
+ return returnRef;
}
ObjectBase::asyncUnlock();
Type *nt = new Type(rsc);
+ returnRef.set(nt);
nt->mElement.set(e);
nt->mDimX = dimX;
nt->mDimY = dimY;
@@ -247,25 +238,24 @@ Type * Type::getType(Context *rsc, const Element *e,
nt->mDimLOD = dimLOD;
nt->mFaces = dimFaces;
nt->compute();
- nt->incUserRef();
ObjectBase::asyncLock();
stc->mTypes.push(nt);
ObjectBase::asyncUnlock();
- return nt;
+ return returnRef;
}
-Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
- return getType(rsc, mElement.get(), dimX,
- mDimY, mDimZ, mDimLOD, mFaces);
+ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
+ return getTypeRef(rsc, mElement.get(), dimX,
+ mDimY, mDimZ, mDimLOD, mFaces);
}
-Type * Type::cloneAndResize2D(Context *rsc,
+ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
uint32_t dimX,
uint32_t dimY) const {
- return getType(rsc, mElement.get(), dimX, dimY,
- mDimZ, mDimLOD, mFaces);
+ return getTypeRef(rsc, mElement.get(), dimX, dimY,
+ mDimZ, mDimLOD, mFaces);
}
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 086db33..bc0d9ff 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -62,14 +62,20 @@ public:
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_TYPE; }
static Type *createFromStream(Context *rsc, IStream *stream);
- bool isEqual(const Type *other) const;
+ ObjectBaseRef<Type> cloneAndResize1D(Context *rsc, uint32_t dimX) const;
+ ObjectBaseRef<Type> cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
- Type * cloneAndResize1D(Context *rsc, uint32_t dimX) const;
- Type * cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
+ static ObjectBaseRef<Type> getTypeRef(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces);
- static Type * getType(Context *rsc, const Element *e,
- uint32_t dimX, uint32_t dimY, uint32_t dimZ,
- bool dimLOD, bool dimFaces);
+ static Type* getType(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces) {
+ ObjectBaseRef<Type> type = getTypeRef(rsc, e, dimX, dimY, dimZ, dimLOD, dimFaces);
+ type->incUserRef();
+ return type.get();
+ }
protected:
struct LOD {
@@ -105,7 +111,7 @@ protected:
uint32_t mLODCount;
protected:
- virtual void preDestroy();
+ virtual void preDestroy() const;
virtual ~Type();
private: