diff options
author | Alex Sakhartchouk <alexst@google.com> | 2012-03-27 08:49:52 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-03-27 08:49:52 -0700 |
commit | c72cb1c2e0fe7966f4a32a51ef6b5238516ea772 (patch) | |
tree | a2bfba6331eb3f3b101c0b085f041ce62a1931d3 /libs/rs/driver | |
parent | b85967b9af76e1e60f7a96603e2567a6449d2e04 (diff) | |
parent | 5ff1959f9541980c2c957f482a4b0999533bbb4e (diff) | |
download | frameworks_base-c72cb1c2e0fe7966f4a32a51ef6b5238516ea772.zip frameworks_base-c72cb1c2e0fe7966f4a32a51ef6b5238516ea772.tar.gz frameworks_base-c72cb1c2e0fe7966f4a32a51ef6b5238516ea772.tar.bz2 |
Merge "State based shader recompile to support camera input."
Diffstat (limited to 'libs/rs/driver')
-rw-r--r-- | libs/rs/driver/rsdProgram.cpp | 12 | ||||
-rw-r--r-- | libs/rs/driver/rsdShader.cpp | 88 | ||||
-rw-r--r-- | libs/rs/driver/rsdShader.h | 28 | ||||
-rw-r--r-- | libs/rs/driver/rsdShaderCache.cpp | 66 | ||||
-rw-r--r-- | libs/rs/driver/rsdShaderCache.h | 4 |
5 files changed, 132 insertions, 66 deletions
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp index 30a4c5f..a96a5f9 100644 --- a/libs/rs/driver/rsdProgram.cpp +++ b/libs/rs/driver/rsdProgram.cpp @@ -71,10 +71,10 @@ void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) { if(pv->mHal.drv) { drv = (RsdShader*)pv->mHal.drv; if (rsc->props.mLogShaders) { - ALOGV("Destroying vertex shader with ID %u", drv->getShaderID()); + ALOGV("Destroying vertex shader with ID %u", (uint32_t)pv); } - if (drv->getShaderID()) { - dc->gl.shaderCache->cleanupVertex(drv->getShaderID()); + if (drv->getStateBasedIDCount()) { + dc->gl.shaderCache->cleanupVertex(drv); } delete drv; } @@ -105,10 +105,10 @@ void rsdProgramFragmentDestroy(const Context *rsc, const ProgramFragment *pf) { if(pf->mHal.drv) { drv = (RsdShader*)pf->mHal.drv; if (rsc->props.mLogShaders) { - ALOGV("Destroying fragment shader with ID %u", drv->getShaderID()); + ALOGV("Destroying fragment shader with ID %u", (uint32_t)pf); } - if (drv->getShaderID()) { - dc->gl.shaderCache->cleanupFragment(drv->getShaderID()); + if (drv->getStateBasedIDCount()) { + dc->gl.shaderCache->cleanupFragment(drv); } delete drv; } diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp index a386735..6d9fa90 100644 --- a/libs/rs/driver/rsdShader.cpp +++ b/libs/rs/driver/rsdShader.cpp @@ -46,30 +46,74 @@ RsdShader::RsdShader(const Program *p, uint32_t type, } RsdShader::~RsdShader() { - if (mShaderID) { - glDeleteShader(mShaderID); + for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) { + StateBasedKey *state = mStateBasedShaders.itemAt(i); + if (state->mShaderID) { + glDeleteShader(state->mShaderID); + } + delete state; } delete[] mAttribNames; delete[] mUniformNames; delete[] mUniformArraySizes; - delete[] mTextureTargets; } void RsdShader::initMemberVars() { mDirty = true; - mShaderID = 0; mAttribCount = 0; mUniformCount = 0; mAttribNames = NULL; mUniformNames = NULL; mUniformArraySizes = NULL; - mTextureTargets = NULL; + mCurrentState = NULL; mIsValid = false; } +RsdShader::StateBasedKey *RsdShader::getExistingState() { + RsdShader::StateBasedKey *returnKey = NULL; + + for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) { + returnKey = mStateBasedShaders.itemAt(i); + + for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) { + uint32_t texType = 0; + if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) { + Allocation *a = mRSProgram->mHal.state.textures[ct]; + if (a && a->mHal.state.surfaceTextureID) { + texType = GL_TEXTURE_EXTERNAL_OES; + } else { + texType = GL_TEXTURE_2D; + } + } else { + texType = GL_TEXTURE_CUBE_MAP; + } + if (texType != returnKey->mTextureTargets[ct]) { + returnKey = NULL; + break; + } + } + } + return returnKey; +} + +uint32_t RsdShader::getStateBasedShaderID(const Context *rsc) { + StateBasedKey *state = getExistingState(); + if (state != NULL) { + mCurrentState = state; + return mCurrentState->mShaderID; + } + // We have not created a shader for this particular state yet + state = new StateBasedKey(mTextureCount); + mCurrentState = state; + mStateBasedShaders.add(state); + createShader(); + loadShader(rsc); + return mCurrentState->mShaderID; +} + void RsdShader::init(const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength) { uint32_t attribCount = 0; @@ -155,14 +199,14 @@ void RsdShader::appendTextures() { appendUsing = false; } mShader.append("uniform samplerExternalOES UNI_"); - mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES; + mCurrentState->mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES; } else { mShader.append("uniform sampler2D UNI_"); - mTextureTargets[ct] = GL_TEXTURE_2D; + mCurrentState->mTextureTargets[ct] = GL_TEXTURE_2D; } } else { mShader.append("uniform samplerCube UNI_"); - mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP; + mCurrentState->mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP; } mShader.append(mTextureNames[ct]); @@ -171,6 +215,7 @@ void RsdShader::appendTextures() { } bool RsdShader::createShader() { + mShader.clear(); if (mType == GL_FRAGMENT_SHADER) { mShader.append("precision mediump float;\n"); } @@ -183,37 +228,37 @@ bool RsdShader::createShader() { } bool RsdShader::loadShader(const Context *rsc) { - mShaderID = glCreateShader(mType); - rsAssert(mShaderID); + mCurrentState->mShaderID = glCreateShader(mType); + rsAssert(mCurrentState->mShaderID); if(!mShader.length()) { createShader(); } if (rsc->props.mLogShaders) { - ALOGV("Loading shader type %x, ID %i", mType, mShaderID); + ALOGV("Loading shader type %x, ID %i", mType, mCurrentState->mShaderID); ALOGV("%s", mShader.string()); } - if (mShaderID) { + if (mCurrentState->mShaderID) { const char * ss = mShader.string(); - RSD_CALL_GL(glShaderSource, mShaderID, 1, &ss, NULL); - RSD_CALL_GL(glCompileShader, mShaderID); + RSD_CALL_GL(glShaderSource, mCurrentState->mShaderID, 1, &ss, NULL); + RSD_CALL_GL(glCompileShader, mCurrentState->mShaderID); GLint compiled = 0; - RSD_CALL_GL(glGetShaderiv, mShaderID, GL_COMPILE_STATUS, &compiled); + RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; - RSD_CALL_GL(glGetShaderiv, mShaderID, GL_INFO_LOG_LENGTH, &infoLen); + RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* buf = (char*) malloc(infoLen); if (buf) { - RSD_CALL_GL(glGetShaderInfoLog, mShaderID, infoLen, NULL, buf); + RSD_CALL_GL(glGetShaderInfoLog, mCurrentState->mShaderID, infoLen, NULL, buf); rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf); free(buf); } - RSD_CALL_GL(glDeleteShader, mShaderID); - mShaderID = 0; + RSD_CALL_GL(glDeleteShader, mCurrentState->mShaderID); + mCurrentState->mShaderID = 0; return false; } } @@ -430,7 +475,7 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) { if (!mRSProgram->mHal.state.textures[ct]) { // if nothing is bound, reset to default GL texture - RSD_CALL_GL(glBindTexture, mTextureTargets[ct], 0); + RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], 0); continue; } @@ -537,9 +582,6 @@ void RsdShader::initAttribAndUniformArray() { } mTextureCount = mRSProgram->mHal.state.texturesCount; - if (mTextureCount) { - mTextureTargets = new uint32_t[mTextureCount]; - } } void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h index 6c0b616..2680b3e 100644 --- a/libs/rs/driver/rsdShader.h +++ b/libs/rs/driver/rsdShader.h @@ -44,9 +44,13 @@ public: const size_t *textureNamesLength); virtual ~RsdShader(); - bool createShader(); + uint32_t getStateBasedShaderID(const android::renderscript::Context *); - uint32_t getShaderID() const {return mShaderID;} + // Add ability to get all ID's to clean up the cached program objects + uint32_t getStateBasedIDCount() const { return mStateBasedShaders.size(); } + uint32_t getStateBasedID(uint32_t index) const { + return mStateBasedShaders.itemAt(index)->mShaderID; + } uint32_t getAttribCount() const {return mAttribCount;} uint32_t getUniformCount() const {return mUniformCount;} @@ -64,6 +68,21 @@ public: protected: + class StateBasedKey { + public: + StateBasedKey(uint32_t texCount) : mShaderID(0) { + mTextureTargets = new uint32_t[texCount]; + } + ~StateBasedKey() { + delete[] mTextureTargets; + } + uint32_t mShaderID; + uint32_t *mTextureTargets; + }; + + bool createShader(); + StateBasedKey *getExistingState(); + const android::renderscript::Program *mRSProgram; bool mIsValid; @@ -87,11 +106,10 @@ protected: mutable bool mDirty; android::String8 mShader; android::String8 mUserShader; - uint32_t mShaderID; uint32_t mType; uint32_t mTextureCount; - uint32_t *mTextureTargets; + StateBasedKey *mCurrentState; uint32_t mAttribCount; uint32_t mUniformCount; android::String8 *mAttribNames; @@ -100,6 +118,8 @@ protected: android::Vector<android::String8> mTextureNames; + android::Vector<StateBasedKey*> mStateBasedShaders; + int32_t mTextureUniformIndexStart; void logUniform(const android::renderscript::Element *field, diff --git a/libs/rs/driver/rsdShaderCache.cpp b/libs/rs/driver/rsdShaderCache.cpp index 50cb9f9..69b43fc 100644 --- a/libs/rs/driver/rsdShaderCache.cpp +++ b/libs/rs/driver/rsdShaderCache.cpp @@ -108,21 +108,17 @@ bool RsdShaderCache::link(const Context *rsc) { RsdShader *vtx = mVertex; RsdShader *frag = mFragment; - if (!vtx->getShaderID()) { - vtx->loadShader(rsc); - } - if (!frag->getShaderID()) { - frag->loadShader(rsc); - } + + uint32_t vID = vtx->getStateBasedShaderID(rsc); + uint32_t fID = frag->getStateBasedShaderID(rsc); // Don't try to cache if shaders failed to load - if (!vtx->getShaderID() || !frag->getShaderID()) { + if (!vID || !fID) { return false; } uint32_t entryCount = mEntries.size(); for (uint32_t ct = 0; ct < entryCount; ct ++) { - if ((mEntries[ct]->vtx == vtx->getShaderID()) && - (mEntries[ct]->frag == frag->getShaderID())) { + if ((mEntries[ct]->vtx == vID) && (mEntries[ct]->frag == fID)) { //ALOGV("SC using program %i", mEntries[ct]->program); glUseProgram(mEntries[ct]->program); @@ -138,14 +134,14 @@ bool RsdShaderCache::link(const Context *rsc) { frag->getUniformCount()); mEntries.push(e); mCurrent = e; - e->vtx = vtx->getShaderID(); - e->frag = frag->getShaderID(); + e->vtx = vID; + e->frag = fID; e->program = glCreateProgram(); if (e->program) { GLuint pgm = e->program; - glAttachShader(pgm, vtx->getShaderID()); + glAttachShader(pgm, vID); //ALOGE("e1 %x", glGetError()); - glAttachShader(pgm, frag->getShaderID()); + glAttachShader(pgm, fID); glBindAttribLocation(pgm, 0, "ATTRIB_position"); glBindAttribLocation(pgm, 1, "ATTRIB_color"); @@ -241,30 +237,38 @@ int32_t RsdShaderCache::vtxAttribSlot(const String8 &attrName) const { return -1; } -void RsdShaderCache::cleanupVertex(uint32_t id) { +void RsdShaderCache::cleanupVertex(RsdShader *s) { int32_t numEntries = (int32_t)mEntries.size(); - for (int32_t ct = 0; ct < numEntries; ct ++) { - if (mEntries[ct]->vtx == id) { - glDeleteProgram(mEntries[ct]->program); - - delete mEntries[ct]; - mEntries.removeAt(ct); - numEntries = (int32_t)mEntries.size(); - ct --; + uint32_t numShaderIDs = s->getStateBasedIDCount(); + for (uint32_t sId = 0; sId < numShaderIDs; sId ++) { + uint32_t id = s->getStateBasedID(sId); + for (int32_t ct = 0; ct < numEntries; ct ++) { + if (mEntries[ct]->vtx == id) { + glDeleteProgram(mEntries[ct]->program); + + delete mEntries[ct]; + mEntries.removeAt(ct); + numEntries = (int32_t)mEntries.size(); + ct --; + } } } } -void RsdShaderCache::cleanupFragment(uint32_t id) { +void RsdShaderCache::cleanupFragment(RsdShader *s) { int32_t numEntries = (int32_t)mEntries.size(); - for (int32_t ct = 0; ct < numEntries; ct ++) { - if (mEntries[ct]->frag == id) { - glDeleteProgram(mEntries[ct]->program); - - delete mEntries[ct]; - mEntries.removeAt(ct); - numEntries = (int32_t)mEntries.size(); - ct --; + uint32_t numShaderIDs = s->getStateBasedIDCount(); + for (uint32_t sId = 0; sId < numShaderIDs; sId ++) { + uint32_t id = s->getStateBasedID(sId); + for (int32_t ct = 0; ct < numEntries; ct ++) { + if (mEntries[ct]->frag == id) { + glDeleteProgram(mEntries[ct]->program); + + delete mEntries[ct]; + mEntries.removeAt(ct); + numEntries = (int32_t)mEntries.size(); + ct --; + } } } } diff --git a/libs/rs/driver/rsdShaderCache.h b/libs/rs/driver/rsdShaderCache.h index 1192916..88aa32d 100644 --- a/libs/rs/driver/rsdShaderCache.h +++ b/libs/rs/driver/rsdShaderCache.h @@ -49,8 +49,8 @@ public: bool setup(const android::renderscript::Context *rsc); - void cleanupVertex(uint32_t id); - void cleanupFragment(uint32_t id); + void cleanupVertex(RsdShader *s); + void cleanupFragment(RsdShader *s); void cleanupAll(); |