• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "rsContext.h"
18 #include "rsProgramVertex.h"
19 
20 #include <GLES/gl.h>
21 #include <GLES/glext.h>
22 #include <GLES2/gl2.h>
23 #include <GLES2/gl2ext.h>
24 
25 using namespace android;
26 using namespace android::renderscript;
27 
28 
ProgramVertex(Context * rsc,bool texMat)29 ProgramVertex::ProgramVertex(Context *rsc, bool texMat) :
30     Program(rsc)
31 {
32     mAllocFile = __FILE__;
33     mAllocLine = __LINE__;
34     mTextureMatrixEnable = texMat;
35     mLightCount = 0;
36     init(rsc);
37 }
38 
ProgramVertex(Context * rsc,const char * shaderText,uint32_t shaderLength,const uint32_t * params,uint32_t paramLength)39 ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText,
40                              uint32_t shaderLength, const uint32_t * params,
41                              uint32_t paramLength) :
42     Program(rsc, shaderText, shaderLength, params, paramLength)
43 {
44     mAllocFile = __FILE__;
45     mAllocLine = __LINE__;
46     mTextureMatrixEnable = false;
47     mLightCount = 0;
48 
49     init(rsc);
50 }
51 
~ProgramVertex()52 ProgramVertex::~ProgramVertex()
53 {
54 }
55 
logMatrix(const char * txt,const float * f)56 static void logMatrix(const char *txt, const float *f)
57 {
58     LOGV("Matrix %s, %p", txt, f);
59     LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[0], f[4], f[8], f[12]);
60     LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[1], f[5], f[9], f[13]);
61     LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[2], f[6], f[10], f[14]);
62     LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[3], f[7], f[11], f[15]);
63 }
64 
setupGL(const Context * rsc,ProgramVertexState * state)65 void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state)
66 {
67     if ((state->mLast.get() == this) && !mDirty) {
68         return;
69     }
70     state->mLast.set(this);
71 
72     const float *f = static_cast<const float *>(mConstants[0]->getPtr());
73 
74     glMatrixMode(GL_TEXTURE);
75     if (mTextureMatrixEnable) {
76         glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
77     } else {
78         glLoadIdentity();
79     }
80 
81     glMatrixMode(GL_MODELVIEW);
82     glLoadIdentity();
83     if (mLightCount) {
84         int v = 0;
85         glEnable(GL_LIGHTING);
86         glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v);
87         for (uint32_t ct = 0; ct < mLightCount; ct++) {
88             const Light *l = mLights[ct].get();
89             glEnable(GL_LIGHT0 + ct);
90             l->setupGL(ct);
91         }
92         for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) {
93             glDisable(GL_LIGHT0 + ct);
94         }
95     } else {
96         glDisable(GL_LIGHTING);
97     }
98 
99     if (!f) {
100         LOGE("Must bind constants to vertex program");
101     }
102 
103     glMatrixMode(GL_PROJECTION);
104     glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
105     glMatrixMode(GL_MODELVIEW);
106     glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
107 
108     mDirty = false;
109 }
110 
loadShader(Context * rsc)111 void ProgramVertex::loadShader(Context *rsc) {
112     Program::loadShader(rsc, GL_VERTEX_SHADER);
113 }
114 
createShader()115 void ProgramVertex::createShader()
116 {
117     mShader.setTo("");
118 
119     mShader.append("varying vec4 varColor;\n");
120     mShader.append("varying vec4 varTex0;\n");
121 
122     if (mUserShader.length() > 1) {
123         mShader.append("uniform mat4 ");
124         mShader.append(mUniformNames[0]);
125         mShader.append(";\n");
126 
127         for (uint32_t ct=0; ct < mConstantCount; ct++) {
128             const Element *e = mConstantTypes[ct]->getElement();
129             for (uint32_t field=0; field < e->getFieldCount(); field++) {
130                 const Element *f = e->getField(field);
131 
132                 // Cannot be complex
133                 rsAssert(!f->getFieldCount());
134                 switch(f->getComponent().getVectorSize()) {
135                 case 1: mShader.append("uniform float UNI_"); break;
136                 case 2: mShader.append("uniform vec2 UNI_"); break;
137                 case 3: mShader.append("uniform vec3 UNI_"); break;
138                 case 4: mShader.append("uniform vec4 UNI_"); break;
139                 default:
140                     rsAssert(0);
141                 }
142 
143                 mShader.append(e->getFieldName(field));
144                 mShader.append(";\n");
145             }
146         }
147 
148 
149         for (uint32_t ct=0; ct < mInputCount; ct++) {
150             const Element *e = mInputElements[ct].get();
151             for (uint32_t field=0; field < e->getFieldCount(); field++) {
152                 const Element *f = e->getField(field);
153 
154                 // Cannot be complex
155                 rsAssert(!f->getFieldCount());
156                 switch(f->getComponent().getVectorSize()) {
157                 case 1: mShader.append("attribute float ATTRIB_"); break;
158                 case 2: mShader.append("attribute vec2 ATTRIB_"); break;
159                 case 3: mShader.append("attribute vec3 ATTRIB_"); break;
160                 case 4: mShader.append("attribute vec4 ATTRIB_"); break;
161                 default:
162                     rsAssert(0);
163                 }
164 
165                 mShader.append(e->getFieldName(field));
166                 mShader.append(";\n");
167             }
168         }
169         mShader.append(mUserShader);
170     } else {
171         mShader.append("attribute vec4 ATTRIB_LegacyPosition;\n");
172         mShader.append("attribute vec4 ATTRIB_LegacyColor;\n");
173         mShader.append("attribute vec3 ATTRIB_LegacyNormal;\n");
174         mShader.append("attribute float ATTRIB_LegacyPointSize;\n");
175         mShader.append("attribute vec4 ATTRIB_LegacyTexture;\n");
176 
177         for (uint32_t ct=0; ct < mUniformCount; ct++) {
178             mShader.append("uniform mat4 ");
179             mShader.append(mUniformNames[ct]);
180             mShader.append(";\n");
181         }
182 
183         mShader.append("void main() {\n");
184         mShader.append("  gl_Position = UNI_MVP * ATTRIB_LegacyPosition;\n");
185         mShader.append("  gl_PointSize = ATTRIB_LegacyPointSize;\n");
186 
187         mShader.append("  varColor = ATTRIB_LegacyColor;\n");
188         if (mTextureMatrixEnable) {
189             mShader.append("  varTex0 = UNI_TexMatrix * ATTRIB_LegacyTexture;\n");
190         } else {
191             mShader.append("  varTex0 = ATTRIB_LegacyTexture;\n");
192         }
193         //mShader.append("  pos.x = pos.x / 480.0;\n");
194         //mShader.append("  pos.y = pos.y / 800.0;\n");
195         //mShader.append("  gl_Position = pos;\n");
196         mShader.append("}\n");
197     }
198 }
199 
setupGL2(const Context * rsc,ProgramVertexState * state,ShaderCache * sc)200 void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc)
201 {
202     //LOGE("sgl2 vtx1 %x", glGetError());
203     if ((state->mLast.get() == this) && !mDirty) {
204         //return;
205     }
206 
207     rsc->checkError("ProgramVertex::setupGL2 start");
208     glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]);
209 
210     const float *f = static_cast<const float *>(mConstants[0]->getPtr());
211 
212     Matrix mvp;
213     mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
214     Matrix t;
215     t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
216     mvp.multiply(&t);
217 
218     glUniformMatrix4fv(sc->vtxUniformSlot(0), 1, GL_FALSE, mvp.m);
219     if (mTextureMatrixEnable) {
220         glUniformMatrix4fv(sc->vtxUniformSlot(1), 1, GL_FALSE,
221                            &f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
222     }
223 
224     rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
225     uint32_t uidx = 1;
226     for (uint32_t ct=0; ct < mConstantCount; ct++) {
227         Allocation *alloc = mConstants[ct+1].get();
228         if (!alloc) {
229             continue;
230         }
231 
232         const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
233         const Element *e = mConstantTypes[ct]->getElement();
234         for (uint32_t field=0; field < e->getFieldCount(); field++) {
235             const Element *f = e->getField(field);
236             uint32_t offset = e->getFieldOffsetBytes(field);
237             int32_t slot = sc->vtxUniformSlot(uidx);
238 
239             const float *fd = reinterpret_cast<const float *>(&data[offset]);
240 
241             //LOGE("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i", slot, offset, ct, field, uidx);
242             if (slot >= 0) {
243                 switch(f->getComponent().getVectorSize()) {
244                 case 1:
245                     //LOGE("Uniform 1 = %f", fd[0]);
246                     glUniform1fv(slot, 1, fd);
247                     break;
248                 case 2:
249                     //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
250                     glUniform2fv(slot, 1, fd);
251                     break;
252                 case 3:
253                     //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
254                     glUniform3fv(slot, 1, fd);
255                     break;
256                 case 4:
257                     //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
258                     glUniform4fv(slot, 1, fd);
259                     break;
260                 default:
261                     rsAssert(0);
262                 }
263             }
264             uidx ++;
265         }
266     }
267 
268     for (uint32_t ct=0; ct < mConstantCount; ct++) {
269         uint32_t glSlot = sc->vtxUniformSlot(ct + 1);
270 
271     }
272 
273     state->mLast.set(this);
274     rsc->checkError("ProgramVertex::setupGL2");
275 }
276 
addLight(const Light * l)277 void ProgramVertex::addLight(const Light *l)
278 {
279     if (mLightCount < MAX_LIGHTS) {
280         mLights[mLightCount].set(l);
281         mLightCount++;
282     }
283 }
284 
setProjectionMatrix(const rsc_Matrix * m) const285 void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const
286 {
287     float *f = static_cast<float *>(mConstants[0]->getPtr());
288     memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
289     mDirty = true;
290 }
291 
setModelviewMatrix(const rsc_Matrix * m) const292 void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const
293 {
294     float *f = static_cast<float *>(mConstants[0]->getPtr());
295     memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
296     mDirty = true;
297 }
298 
setTextureMatrix(const rsc_Matrix * m) const299 void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const
300 {
301     float *f = static_cast<float *>(mConstants[0]->getPtr());
302     memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
303     mDirty = true;
304 }
305 
transformToScreen(const Context * rsc,float * v4out,const float * v3in) const306 void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const
307 {
308     float *f = static_cast<float *>(mConstants[0]->getPtr());
309     Matrix mvp;
310     mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
311                      (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
312     mvp.vectorMultiply(v4out, v3in);
313 }
314 
initAddUserElement(const Element * e,String8 * names,uint32_t * count,const char * prefix)315 void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
316 {
317     rsAssert(e->getFieldCount());
318     for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
319         const Element *ce = e->getField(ct);
320         if (ce->getFieldCount()) {
321             initAddUserElement(ce, names, count, prefix);
322         } else {
323             String8 tmp(prefix);
324             tmp.append(e->getFieldName(ct));
325             names[*count].setTo(tmp.string());
326             (*count)++;
327         }
328     }
329 }
330 
331 
init(Context * rsc)332 void ProgramVertex::init(Context *rsc)
333 {
334     mAttribCount = 0;
335     if (mUserShader.size() > 0) {
336         for (uint32_t ct=0; ct < mInputCount; ct++) {
337             initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, "ATTRIB_");
338         }
339 
340         mUniformCount = 1;
341         mUniformNames[0].setTo("UNI_MVP");
342         for (uint32_t ct=0; ct < mConstantCount; ct++) {
343             initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
344         }
345     } else {
346         mUniformCount = 2;
347         mUniformNames[0].setTo("UNI_MVP");
348         mUniformNames[1].setTo("UNI_TexMatrix");
349     }
350 
351     createShader();
352 }
353 
354 
355 ///////////////////////////////////////////////////////////////////////
356 
ProgramVertexState()357 ProgramVertexState::ProgramVertexState()
358 {
359 }
360 
~ProgramVertexState()361 ProgramVertexState::~ProgramVertexState()
362 {
363 }
364 
init(Context * rsc,int32_t w,int32_t h)365 void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
366 {
367     RsElement e = (RsElement) Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
368 
369     rsi_TypeBegin(rsc, e);
370     rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
371     mAllocType.set((Type *)rsi_TypeCreate(rsc));
372 
373     ProgramVertex *pv = new ProgramVertex(rsc, false);
374     Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get());
375     mDefaultAlloc.set(alloc);
376     mDefault.set(pv);
377     pv->init(rsc);
378     pv->bindAllocation(alloc, 0);
379 
380     color[0] = 1.f;
381     color[1] = 1.f;
382     color[2] = 1.f;
383     color[3] = 1.f;
384 
385     updateSize(rsc, w, h);
386 }
387 
updateSize(Context * rsc,int32_t w,int32_t h)388 void ProgramVertexState::updateSize(Context *rsc, int32_t w, int32_t h)
389 {
390     Matrix m;
391     m.loadOrtho(0,w, h,0, -1,1);
392     mDefaultAlloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
393 
394     m.loadIdentity();
395     mDefaultAlloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
396 }
397 
deinit(Context * rsc)398 void ProgramVertexState::deinit(Context *rsc)
399 {
400     mDefaultAlloc.clear();
401     mDefault.clear();
402     mAllocType.clear();
403     mLast.clear();
404 }
405 
406 
407 namespace android {
408 namespace renderscript {
409 
410 
rsi_ProgramVertexCreate(Context * rsc,bool texMat)411 RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, bool texMat)
412 {
413     ProgramVertex *pv = new ProgramVertex(rsc, texMat);
414     pv->incUserRef();
415     return pv;
416 }
417 
rsi_ProgramVertexCreate2(Context * rsc,const char * shaderText,uint32_t shaderLength,const uint32_t * params,uint32_t paramLength)418 RsProgramVertex rsi_ProgramVertexCreate2(Context *rsc, const char * shaderText,
419                              uint32_t shaderLength, const uint32_t * params,
420                              uint32_t paramLength)
421 {
422     ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength);
423     pv->incUserRef();
424     return pv;
425 }
426 
427 
428 }
429 }
430