diff options
Diffstat (limited to 'libs/rs/rsShaderCache.cpp')
-rw-r--r-- | libs/rs/rsShaderCache.cpp | 123 |
1 files changed, 69 insertions, 54 deletions
diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp index 4711d1b..45f6207 100644 --- a/libs/rs/rsShaderCache.cpp +++ b/libs/rs/rsShaderCache.cpp @@ -14,10 +14,14 @@ * limitations under the License. */ +#ifndef ANDROID_RS_BUILD_FOR_HOST #include "rsContext.h" - #include <GLES/gl.h> #include <GLES2/gl2.h> +#else +#include "rsContextHostStub.h" +#include <OpenGL/gl.h> +#endif //ANDROID_RS_BUILD_FOR_HOST using namespace android; using namespace android::renderscript; @@ -25,20 +29,15 @@ using namespace android::renderscript; ShaderCache::ShaderCache() { - mEntryCount = 0; - mEntryAllocationCount = 16; - mEntries = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); + mEntries.setCapacity(16); } ShaderCache::~ShaderCache() { - for (uint32_t ct=0; ct < mEntryCount; ct++) { - glDeleteProgram(mEntries[ct].program); + for (uint32_t ct=0; ct < mEntries.size(); ct++) { + glDeleteProgram(mEntries[ct]->program); + free(mEntries[ct]); } - - mEntryCount = 0; - mEntryAllocationCount = 0; - free(mEntries); } bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag) @@ -49,61 +48,46 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag if (!frag->getShaderID()) { frag->loadShader(rsc); } - //LOGV("ShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID()); - for (uint32_t ct=0; ct < mEntryCount; ct++) { - if ((mEntries[ct].vtx == vtx->getShaderID()) && - (mEntries[ct].frag == frag->getShaderID())) { - - //LOGV("SC using program %i", mEntries[ct].program); - glUseProgram(mEntries[ct].program); - mCurrent = &mEntries[ct]; + // Don't try to cache if shaders failed to load + if(!vtx->getShaderID() || !frag->getShaderID()) { + return false; + } + //LOGV("ShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID()); + uint32_t entryCount = mEntries.size(); + for(uint32_t ct = 0; ct < entryCount; ct ++) { + if ((mEntries[ct]->vtx == vtx->getShaderID()) && + (mEntries[ct]->frag == frag->getShaderID())) { + + //LOGV("SC using program %i", mEntries[ct]->program); + glUseProgram(mEntries[ct]->program); + mCurrent = mEntries[ct]; //LOGV("ShaderCache hit, using %i", ct); rsc->checkError("ShaderCache::lookup (hit)"); return true; } } - // Not in cache, add it. - - if (mEntryAllocationCount == mEntryCount) { - // Out of space, make some. - mEntryAllocationCount *= 2; - entry_t *e = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); - if (!e) { - LOGE("Out of memory for ShaderCache::lookup"); - return false; - } - memcpy(e, mEntries, sizeof(entry_t) * mEntryCount); - free(mEntries); - mEntries = e; - } - //LOGV("ShaderCache miss, using %i", mEntryCount); + //LOGV("ShaderCache miss"); //LOGE("e0 %x", glGetError()); - - entry_t *e = &mEntries[mEntryCount]; + entry_t *e = (entry_t *)malloc(sizeof(entry_t)); + mEntries.push(e); mCurrent = e; e->vtx = vtx->getShaderID(); e->frag = frag->getShaderID(); e->program = glCreateProgram(); - e->mUserVertexProgram = vtx->isUserProgram(); - if (mEntries[mEntryCount].program) { + e->vtxAttrCount = vtx->getAttribCount(); + if (e->program) { GLuint pgm = e->program; glAttachShader(pgm, vtx->getShaderID()); //LOGE("e1 %x", glGetError()); glAttachShader(pgm, frag->getShaderID()); if (!vtx->isUserProgram()) { - glBindAttribLocation(pgm, 0, "ATTRIB_LegacyPosition"); - glBindAttribLocation(pgm, 1, "ATTRIB_LegacyColor"); - glBindAttribLocation(pgm, 2, "ATTRIB_LegacyNormal"); - glBindAttribLocation(pgm, 3, "ATTRIB_LegacyPointSize"); - glBindAttribLocation(pgm, 4, "ATTRIB_LegacyTexture"); - e->mVtxAttribSlots[RS_KIND_POSITION] = 0; - e->mVtxAttribSlots[RS_KIND_COLOR] = 1; - e->mVtxAttribSlots[RS_KIND_NORMAL] = 2; - e->mVtxAttribSlots[RS_KIND_POINT_SIZE] = 3; - e->mVtxAttribSlots[RS_KIND_TEXTURE] = 4; + glBindAttribLocation(pgm, 0, "ATTRIB_position"); + glBindAttribLocation(pgm, 1, "ATTRIB_color"); + glBindAttribLocation(pgm, 2, "ATTRIB_normal"); + glBindAttribLocation(pgm, 3, "ATTRIB_texture0"); } //LOGE("e2 %x", glGetError()); @@ -126,14 +110,15 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag rsc->setError(RS_ERROR_BAD_SHADER, "Error linking GL Programs"); return false; } - if (vtx->isUserProgram()) { - for (uint32_t ct=0; ct < vtx->getAttribCount(); ct++) { - e->mVtxAttribSlots[ct] = glGetAttribLocation(pgm, vtx->getAttribName(ct)); - if (rsc->props.mLogShaders) { - LOGV("vtx A %i, %s = %d\n", ct, vtx->getAttribName(ct).string(), e->mVtxAttribSlots[ct]); - } + + for (uint32_t ct=0; ct < e->vtxAttrCount; ct++) { + e->mVtxAttribSlots[ct] = glGetAttribLocation(pgm, vtx->getAttribName(ct)); + e->mVtxAttribNames[ct] = vtx->getAttribName(ct).string(); + if (rsc->props.mLogShaders) { + LOGV("vtx A %i, %s = %d\n", ct, vtx->getAttribName(ct).string(), e->mVtxAttribSlots[ct]); } } + for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { e->mVtxUniformSlots[ct] = glGetUniformLocation(pgm, vtx->getUniformName(ct)); if (rsc->props.mLogShaders) { @@ -151,17 +136,47 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag e->mIsValid = true; //LOGV("SC made program %i", e->program); glUseProgram(e->program); - mEntryCount++; rsc->checkError("ShaderCache::lookup (miss)"); return true; } +int32_t ShaderCache::vtxAttribSlot(const String8 &attrName) const { + for (uint32_t ct=0; ct < mCurrent->vtxAttrCount; ct++) { + if(attrName == mCurrent->mVtxAttribNames[ct]) { + return mCurrent->mVtxAttribSlots[ct]; + } + } + return -1; +} + void ShaderCache::cleanupVertex(uint32_t id) { + int32_t numEntries = (int32_t)mEntries.size(); + for(int32_t ct = 0; ct < numEntries; ct ++) { + if (mEntries[ct]->vtx == id) { + glDeleteProgram(mEntries[ct]->program); + + free(mEntries[ct]); + mEntries.removeAt(ct); + numEntries = (int32_t)mEntries.size(); + ct --; + } + } } void ShaderCache::cleanupFragment(uint32_t id) { + int32_t numEntries = (int32_t)mEntries.size(); + for(int32_t ct = 0; ct < numEntries; ct ++) { + if (mEntries[ct]->frag == id) { + glDeleteProgram(mEntries[ct]->program); + + free(mEntries[ct]); + mEntries.removeAt(ct); + numEntries = (int32_t)mEntries.size(); + ct --; + } + } } void ShaderCache::cleanupAll() |