Skip to content

Commit c72cb1c

Browse files
Alex SakhartchoukAndroid (Google) Code Review
authored andcommitted
Merge "State based shader recompile to support camera input."
2 parents b85967b + 5ff1959 commit c72cb1c

File tree

5 files changed

+132
-66
lines changed

5 files changed

+132
-66
lines changed

libs/rs/driver/rsdProgram.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) {
7171
if(pv->mHal.drv) {
7272
drv = (RsdShader*)pv->mHal.drv;
7373
if (rsc->props.mLogShaders) {
74-
ALOGV("Destroying vertex shader with ID %u", drv->getShaderID());
74+
ALOGV("Destroying vertex shader with ID %u", (uint32_t)pv);
7575
}
76-
if (drv->getShaderID()) {
77-
dc->gl.shaderCache->cleanupVertex(drv->getShaderID());
76+
if (drv->getStateBasedIDCount()) {
77+
dc->gl.shaderCache->cleanupVertex(drv);
7878
}
7979
delete drv;
8080
}
@@ -105,10 +105,10 @@ void rsdProgramFragmentDestroy(const Context *rsc, const ProgramFragment *pf) {
105105
if(pf->mHal.drv) {
106106
drv = (RsdShader*)pf->mHal.drv;
107107
if (rsc->props.mLogShaders) {
108-
ALOGV("Destroying fragment shader with ID %u", drv->getShaderID());
108+
ALOGV("Destroying fragment shader with ID %u", (uint32_t)pf);
109109
}
110-
if (drv->getShaderID()) {
111-
dc->gl.shaderCache->cleanupFragment(drv->getShaderID());
110+
if (drv->getStateBasedIDCount()) {
111+
dc->gl.shaderCache->cleanupFragment(drv);
112112
}
113113
delete drv;
114114
}

libs/rs/driver/rsdShader.cpp

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,30 +46,74 @@ RsdShader::RsdShader(const Program *p, uint32_t type,
4646
}
4747

4848
RsdShader::~RsdShader() {
49-
if (mShaderID) {
50-
glDeleteShader(mShaderID);
49+
for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) {
50+
StateBasedKey *state = mStateBasedShaders.itemAt(i);
51+
if (state->mShaderID) {
52+
glDeleteShader(state->mShaderID);
53+
}
54+
delete state;
5155
}
5256

5357
delete[] mAttribNames;
5458
delete[] mUniformNames;
5559
delete[] mUniformArraySizes;
56-
delete[] mTextureTargets;
5760
}
5861

5962
void RsdShader::initMemberVars() {
6063
mDirty = true;
61-
mShaderID = 0;
6264
mAttribCount = 0;
6365
mUniformCount = 0;
6466

6567
mAttribNames = NULL;
6668
mUniformNames = NULL;
6769
mUniformArraySizes = NULL;
68-
mTextureTargets = NULL;
70+
mCurrentState = NULL;
6971

7072
mIsValid = false;
7173
}
7274

75+
RsdShader::StateBasedKey *RsdShader::getExistingState() {
76+
RsdShader::StateBasedKey *returnKey = NULL;
77+
78+
for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) {
79+
returnKey = mStateBasedShaders.itemAt(i);
80+
81+
for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) {
82+
uint32_t texType = 0;
83+
if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
84+
Allocation *a = mRSProgram->mHal.state.textures[ct];
85+
if (a && a->mHal.state.surfaceTextureID) {
86+
texType = GL_TEXTURE_EXTERNAL_OES;
87+
} else {
88+
texType = GL_TEXTURE_2D;
89+
}
90+
} else {
91+
texType = GL_TEXTURE_CUBE_MAP;
92+
}
93+
if (texType != returnKey->mTextureTargets[ct]) {
94+
returnKey = NULL;
95+
break;
96+
}
97+
}
98+
}
99+
return returnKey;
100+
}
101+
102+
uint32_t RsdShader::getStateBasedShaderID(const Context *rsc) {
103+
StateBasedKey *state = getExistingState();
104+
if (state != NULL) {
105+
mCurrentState = state;
106+
return mCurrentState->mShaderID;
107+
}
108+
// We have not created a shader for this particular state yet
109+
state = new StateBasedKey(mTextureCount);
110+
mCurrentState = state;
111+
mStateBasedShaders.add(state);
112+
createShader();
113+
loadShader(rsc);
114+
return mCurrentState->mShaderID;
115+
}
116+
73117
void RsdShader::init(const char** textureNames, size_t textureNamesCount,
74118
const size_t *textureNamesLength) {
75119
uint32_t attribCount = 0;
@@ -155,14 +199,14 @@ void RsdShader::appendTextures() {
155199
appendUsing = false;
156200
}
157201
mShader.append("uniform samplerExternalOES UNI_");
158-
mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES;
202+
mCurrentState->mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES;
159203
} else {
160204
mShader.append("uniform sampler2D UNI_");
161-
mTextureTargets[ct] = GL_TEXTURE_2D;
205+
mCurrentState->mTextureTargets[ct] = GL_TEXTURE_2D;
162206
}
163207
} else {
164208
mShader.append("uniform samplerCube UNI_");
165-
mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
209+
mCurrentState->mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
166210
}
167211

168212
mShader.append(mTextureNames[ct]);
@@ -171,6 +215,7 @@ void RsdShader::appendTextures() {
171215
}
172216

173217
bool RsdShader::createShader() {
218+
mShader.clear();
174219
if (mType == GL_FRAGMENT_SHADER) {
175220
mShader.append("precision mediump float;\n");
176221
}
@@ -183,37 +228,37 @@ bool RsdShader::createShader() {
183228
}
184229

185230
bool RsdShader::loadShader(const Context *rsc) {
186-
mShaderID = glCreateShader(mType);
187-
rsAssert(mShaderID);
231+
mCurrentState->mShaderID = glCreateShader(mType);
232+
rsAssert(mCurrentState->mShaderID);
188233

189234
if(!mShader.length()) {
190235
createShader();
191236
}
192237

193238
if (rsc->props.mLogShaders) {
194-
ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
239+
ALOGV("Loading shader type %x, ID %i", mType, mCurrentState->mShaderID);
195240
ALOGV("%s", mShader.string());
196241
}
197242

198-
if (mShaderID) {
243+
if (mCurrentState->mShaderID) {
199244
const char * ss = mShader.string();
200-
RSD_CALL_GL(glShaderSource, mShaderID, 1, &ss, NULL);
201-
RSD_CALL_GL(glCompileShader, mShaderID);
245+
RSD_CALL_GL(glShaderSource, mCurrentState->mShaderID, 1, &ss, NULL);
246+
RSD_CALL_GL(glCompileShader, mCurrentState->mShaderID);
202247

203248
GLint compiled = 0;
204-
RSD_CALL_GL(glGetShaderiv, mShaderID, GL_COMPILE_STATUS, &compiled);
249+
RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_COMPILE_STATUS, &compiled);
205250
if (!compiled) {
206251
GLint infoLen = 0;
207-
RSD_CALL_GL(glGetShaderiv, mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
252+
RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
208253
if (infoLen) {
209254
char* buf = (char*) malloc(infoLen);
210255
if (buf) {
211-
RSD_CALL_GL(glGetShaderInfoLog, mShaderID, infoLen, NULL, buf);
256+
RSD_CALL_GL(glGetShaderInfoLog, mCurrentState->mShaderID, infoLen, NULL, buf);
212257
rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf);
213258
free(buf);
214259
}
215-
RSD_CALL_GL(glDeleteShader, mShaderID);
216-
mShaderID = 0;
260+
RSD_CALL_GL(glDeleteShader, mCurrentState->mShaderID);
261+
mCurrentState->mShaderID = 0;
217262
return false;
218263
}
219264
}
@@ -430,7 +475,7 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
430475

431476
if (!mRSProgram->mHal.state.textures[ct]) {
432477
// if nothing is bound, reset to default GL texture
433-
RSD_CALL_GL(glBindTexture, mTextureTargets[ct], 0);
478+
RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], 0);
434479
continue;
435480
}
436481

@@ -537,9 +582,6 @@ void RsdShader::initAttribAndUniformArray() {
537582
}
538583

539584
mTextureCount = mRSProgram->mHal.state.texturesCount;
540-
if (mTextureCount) {
541-
mTextureTargets = new uint32_t[mTextureCount];
542-
}
543585
}
544586

545587
void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths,

libs/rs/driver/rsdShader.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ class RsdShader {
4444
const size_t *textureNamesLength);
4545
virtual ~RsdShader();
4646

47-
bool createShader();
47+
uint32_t getStateBasedShaderID(const android::renderscript::Context *);
4848

49-
uint32_t getShaderID() const {return mShaderID;}
49+
// Add ability to get all ID's to clean up the cached program objects
50+
uint32_t getStateBasedIDCount() const { return mStateBasedShaders.size(); }
51+
uint32_t getStateBasedID(uint32_t index) const {
52+
return mStateBasedShaders.itemAt(index)->mShaderID;
53+
}
5054

5155
uint32_t getAttribCount() const {return mAttribCount;}
5256
uint32_t getUniformCount() const {return mUniformCount;}
@@ -64,6 +68,21 @@ class RsdShader {
6468

6569
protected:
6670

71+
class StateBasedKey {
72+
public:
73+
StateBasedKey(uint32_t texCount) : mShaderID(0) {
74+
mTextureTargets = new uint32_t[texCount];
75+
}
76+
~StateBasedKey() {
77+
delete[] mTextureTargets;
78+
}
79+
uint32_t mShaderID;
80+
uint32_t *mTextureTargets;
81+
};
82+
83+
bool createShader();
84+
StateBasedKey *getExistingState();
85+
6786
const android::renderscript::Program *mRSProgram;
6887
bool mIsValid;
6988

@@ -87,11 +106,10 @@ class RsdShader {
87106
mutable bool mDirty;
88107
android::String8 mShader;
89108
android::String8 mUserShader;
90-
uint32_t mShaderID;
91109
uint32_t mType;
92110

93111
uint32_t mTextureCount;
94-
uint32_t *mTextureTargets;
112+
StateBasedKey *mCurrentState;
95113
uint32_t mAttribCount;
96114
uint32_t mUniformCount;
97115
android::String8 *mAttribNames;
@@ -100,6 +118,8 @@ class RsdShader {
100118

101119
android::Vector<android::String8> mTextureNames;
102120

121+
android::Vector<StateBasedKey*> mStateBasedShaders;
122+
103123
int32_t mTextureUniformIndexStart;
104124

105125
void logUniform(const android::renderscript::Element *field,

libs/rs/driver/rsdShaderCache.cpp

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,17 @@ bool RsdShaderCache::link(const Context *rsc) {
108108

109109
RsdShader *vtx = mVertex;
110110
RsdShader *frag = mFragment;
111-
if (!vtx->getShaderID()) {
112-
vtx->loadShader(rsc);
113-
}
114-
if (!frag->getShaderID()) {
115-
frag->loadShader(rsc);
116-
}
111+
112+
uint32_t vID = vtx->getStateBasedShaderID(rsc);
113+
uint32_t fID = frag->getStateBasedShaderID(rsc);
117114

118115
// Don't try to cache if shaders failed to load
119-
if (!vtx->getShaderID() || !frag->getShaderID()) {
116+
if (!vID || !fID) {
120117
return false;
121118
}
122119
uint32_t entryCount = mEntries.size();
123120
for (uint32_t ct = 0; ct < entryCount; ct ++) {
124-
if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
125-
(mEntries[ct]->frag == frag->getShaderID())) {
121+
if ((mEntries[ct]->vtx == vID) && (mEntries[ct]->frag == fID)) {
126122

127123
//ALOGV("SC using program %i", mEntries[ct]->program);
128124
glUseProgram(mEntries[ct]->program);
@@ -138,14 +134,14 @@ bool RsdShaderCache::link(const Context *rsc) {
138134
frag->getUniformCount());
139135
mEntries.push(e);
140136
mCurrent = e;
141-
e->vtx = vtx->getShaderID();
142-
e->frag = frag->getShaderID();
137+
e->vtx = vID;
138+
e->frag = fID;
143139
e->program = glCreateProgram();
144140
if (e->program) {
145141
GLuint pgm = e->program;
146-
glAttachShader(pgm, vtx->getShaderID());
142+
glAttachShader(pgm, vID);
147143
//ALOGE("e1 %x", glGetError());
148-
glAttachShader(pgm, frag->getShaderID());
144+
glAttachShader(pgm, fID);
149145

150146
glBindAttribLocation(pgm, 0, "ATTRIB_position");
151147
glBindAttribLocation(pgm, 1, "ATTRIB_color");
@@ -241,30 +237,38 @@ int32_t RsdShaderCache::vtxAttribSlot(const String8 &attrName) const {
241237
return -1;
242238
}
243239

244-
void RsdShaderCache::cleanupVertex(uint32_t id) {
240+
void RsdShaderCache::cleanupVertex(RsdShader *s) {
245241
int32_t numEntries = (int32_t)mEntries.size();
246-
for (int32_t ct = 0; ct < numEntries; ct ++) {
247-
if (mEntries[ct]->vtx == id) {
248-
glDeleteProgram(mEntries[ct]->program);
249-
250-
delete mEntries[ct];
251-
mEntries.removeAt(ct);
252-
numEntries = (int32_t)mEntries.size();
253-
ct --;
242+
uint32_t numShaderIDs = s->getStateBasedIDCount();
243+
for (uint32_t sId = 0; sId < numShaderIDs; sId ++) {
244+
uint32_t id = s->getStateBasedID(sId);
245+
for (int32_t ct = 0; ct < numEntries; ct ++) {
246+
if (mEntries[ct]->vtx == id) {
247+
glDeleteProgram(mEntries[ct]->program);
248+
249+
delete mEntries[ct];
250+
mEntries.removeAt(ct);
251+
numEntries = (int32_t)mEntries.size();
252+
ct --;
253+
}
254254
}
255255
}
256256
}
257257

258-
void RsdShaderCache::cleanupFragment(uint32_t id) {
258+
void RsdShaderCache::cleanupFragment(RsdShader *s) {
259259
int32_t numEntries = (int32_t)mEntries.size();
260-
for (int32_t ct = 0; ct < numEntries; ct ++) {
261-
if (mEntries[ct]->frag == id) {
262-
glDeleteProgram(mEntries[ct]->program);
263-
264-
delete mEntries[ct];
265-
mEntries.removeAt(ct);
266-
numEntries = (int32_t)mEntries.size();
267-
ct --;
260+
uint32_t numShaderIDs = s->getStateBasedIDCount();
261+
for (uint32_t sId = 0; sId < numShaderIDs; sId ++) {
262+
uint32_t id = s->getStateBasedID(sId);
263+
for (int32_t ct = 0; ct < numEntries; ct ++) {
264+
if (mEntries[ct]->frag == id) {
265+
glDeleteProgram(mEntries[ct]->program);
266+
267+
delete mEntries[ct];
268+
mEntries.removeAt(ct);
269+
numEntries = (int32_t)mEntries.size();
270+
ct --;
271+
}
268272
}
269273
}
270274
}

libs/rs/driver/rsdShaderCache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class RsdShaderCache {
4949

5050
bool setup(const android::renderscript::Context *rsc);
5151

52-
void cleanupVertex(uint32_t id);
53-
void cleanupFragment(uint32_t id);
52+
void cleanupVertex(RsdShader *s);
53+
void cleanupFragment(RsdShader *s);
5454

5555
void cleanupAll();
5656

0 commit comments

Comments
 (0)