Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c72cb1c2 authored by Alex Sakhartchouk's avatar Alex Sakhartchouk Committed by Android (Google) Code Review
Browse files

Merge "State based shader recompile to support camera input."

parents b85967b9 5ff1959f
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -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;
    }
+65 −23
Original line number Diff line number Diff line
@@ -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,
+24 −4
Original line number Diff line number Diff line
@@ -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,
+35 −31
Original line number Diff line number Diff line
@@ -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,8 +237,11 @@ 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();
    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);
@@ -254,9 +253,13 @@ void RsdShaderCache::cleanupVertex(uint32_t id) {
            }
        }
    }
}

void RsdShaderCache::cleanupFragment(uint32_t id) {
void RsdShaderCache::cleanupFragment(RsdShader *s) {
    int32_t numEntries = (int32_t)mEntries.size();
    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);
@@ -268,6 +271,7 @@ void RsdShaderCache::cleanupFragment(uint32_t id) {
            }
        }
    }
}

void RsdShaderCache::cleanupAll() {
    for (uint32_t ct=0; ct < mEntries.size(); ct++) {
+2 −2
Original line number Diff line number Diff line
@@ -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();