@@ -46,30 +46,74 @@ RsdShader::RsdShader(const Program *p, uint32_t type,
4646}
4747
4848RsdShader::~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
5962void 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+
73117void 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
173217bool 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
185230bool 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
545587void RsdShader::initAddUserElement (const Element *e, String8 *names, uint32_t *arrayLengths,
0 commit comments