rsProgramVertex.cpp revision f0c1df480304a72ce41e7d4b088319cbd7f0938a
1e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/* 2e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Copyright (C) 2009 The Android Open Source Project 3e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * 4e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * you may not use this file except in compliance with the License. 6e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * You may obtain a copy of the License at 7e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * 8e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * 10e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * See the License for the specific language governing permissions and 14e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * limitations under the License. 15e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */ 16e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 17e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#ifndef ANDROID_RS_BUILD_FOR_HOST 18e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include "rsContext.h" 19e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <GLES/gl.h> 20e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <GLES/glext.h> 21e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <GLES2/gl2.h> 22e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <GLES2/gl2ext.h> 23e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#else 24e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include "rsContextHostStub.h" 25e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <OpenGL/gl.h> 26e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <OpenGL/glext.h> 27e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#endif //ANDROID_RS_BUILD_FOR_HOST 28e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 29e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include "rsProgramVertex.h" 30e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 31e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkusing namespace android; 32e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkusing namespace android::renderscript; 33e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 34e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 35e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, 36e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint32_t shaderLength, const uint32_t * params, 37e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint32_t paramLength) : 38e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk Program(rsc, shaderText, shaderLength, params, paramLength) 39e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk{ 40e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk init(rsc); 41e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 42e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 43e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkProgramVertex::~ProgramVertex() 44e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk{ 45 if(mShaderID) { 46 mRSC->mShaderCache.cleanupVertex(mShaderID); 47 } 48} 49 50void ProgramVertex::loadShader(Context *rsc) { 51 Program::loadShader(rsc, GL_VERTEX_SHADER); 52} 53 54void ProgramVertex::createShader() 55{ 56 if (mUserShader.length() > 1) { 57 58 appendUserConstants(); 59 60 for (uint32_t ct=0; ct < mInputCount; ct++) { 61 const Element *e = mInputElements[ct].get(); 62 for (uint32_t field=0; field < e->getFieldCount(); field++) { 63 const Element *f = e->getField(field); 64 const char *fn = e->getFieldName(field); 65 66 if (fn[0] == '#') { 67 continue; 68 } 69 70 // Cannot be complex 71 rsAssert(!f->getFieldCount()); 72 switch(f->getComponent().getVectorSize()) { 73 case 1: mShader.append("attribute float ATTRIB_"); break; 74 case 2: mShader.append("attribute vec2 ATTRIB_"); break; 75 case 3: mShader.append("attribute vec3 ATTRIB_"); break; 76 case 4: mShader.append("attribute vec4 ATTRIB_"); break; 77 default: 78 rsAssert(0); 79 } 80 81 mShader.append(fn); 82 mShader.append(";\n"); 83 } 84 } 85 mShader.append(mUserShader); 86 } else { 87 LOGE("ProgramFragment::createShader cannot create program, shader code not defined"); 88 rsAssert(0); 89 } 90} 91 92void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc) 93{ 94 //LOGE("sgl2 vtx1 %x", glGetError()); 95 if ((state->mLast.get() == this) && !mDirty) { 96 return; 97 } 98 99 rsc->checkError("ProgramVertex::setupGL2 start"); 100 101 if(!isUserProgram()) { 102 if(mConstants[0].get() == NULL) { 103 LOGE("Unable to set fixed function emulation matrices because allocation is missing"); 104 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing"); 105 return; 106 } 107 float *f = static_cast<float *>(mConstants[0]->getPtr()); 108 Matrix mvp; 109 mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 110 Matrix t; 111 t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); 112 mvp.multiply(&t); 113 for(uint32_t i = 0; i < 16; i ++) { 114 f[RS_PROGRAM_VERTEX_MVP_OFFSET + i] = mvp.m[i]; 115 } 116 } 117 118 rsc->checkError("ProgramVertex::setupGL2 begin uniforms"); 119 setupUserConstants(rsc, sc, false); 120 121 state->mLast.set(this); 122 rsc->checkError("ProgramVertex::setupGL2"); 123} 124 125void ProgramVertex::setProjectionMatrix(Context *rsc, const rsc_Matrix *m) const 126{ 127 if(isUserProgram()) { 128 LOGE("Attempting to set fixed function emulation matrix projection on user program"); 129 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader"); 130 return; 131 } 132 if(mConstants[0].get() == NULL) { 133 LOGE("Unable to set fixed function emulation matrix projection because allocation is missing"); 134 return; 135 } 136 float *f = static_cast<float *>(mConstants[0]->getPtr()); 137 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix)); 138 mDirty = true; 139} 140 141void ProgramVertex::setModelviewMatrix(Context *rsc, const rsc_Matrix *m) const 142{ 143 if(isUserProgram()) { 144 LOGE("Attempting to set fixed function emulation matrix modelview on user program"); 145 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader"); 146 return; 147 } 148 if(mConstants[0].get() == NULL) { 149 LOGE("Unable to set fixed function emulation matrix modelview because allocation is missing"); 150 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing"); 151 return; 152 } 153 float *f = static_cast<float *>(mConstants[0]->getPtr()); 154 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix)); 155 mDirty = true; 156} 157 158void ProgramVertex::setTextureMatrix(Context *rsc, const rsc_Matrix *m) const 159{ 160 if(isUserProgram()) { 161 LOGE("Attempting to set fixed function emulation matrix texture on user program"); 162 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader"); 163 return; 164 } 165 if(mConstants[0].get() == NULL) { 166 LOGE("Unable to set fixed function emulation matrix texture because allocation is missing"); 167 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing"); 168 return; 169 } 170 float *f = static_cast<float *>(mConstants[0]->getPtr()); 171 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix)); 172 mDirty = true; 173} 174 175void ProgramVertex::getProjectionMatrix(Context *rsc, rsc_Matrix *m) const 176{ 177 if(isUserProgram()) { 178 LOGE("Attempting to get fixed function emulation matrix projection on user program"); 179 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot get emulation matrix on user shader"); 180 return; 181 } 182 if(mConstants[0].get() == NULL) { 183 LOGE("Unable to get fixed function emulation matrix projection because allocation is missing"); 184 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing"); 185 return; 186 } 187 float *f = static_cast<float *>(mConstants[0]->getPtr()); 188 memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix)); 189} 190 191void ProgramVertex::transformToScreen(Context *rsc, float *v4out, const float *v3in) const 192{ 193 if(isUserProgram()) { 194 return; 195 } 196 float *f = static_cast<float *>(mConstants[0]->getPtr()); 197 Matrix mvp; 198 mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], 199 (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); 200 mvp.vectorMultiply(v4out, v3in); 201} 202 203void ProgramVertex::init(Context *rsc) 204{ 205 mAttribCount = 0; 206 if (mUserShader.size() > 0) { 207 for (uint32_t ct=0; ct < mInputCount; ct++) { 208 initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, RS_SHADER_ATTR); 209 } 210 mUniformCount = 0; 211 for (uint32_t ct=0; ct < mConstantCount; ct++) { 212 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, RS_SHADER_UNI); 213 } 214 } 215 createShader(); 216} 217 218void ProgramVertex::serialize(OStream *stream) const 219{ 220 221} 222 223ProgramVertex *ProgramVertex::createFromStream(Context *rsc, IStream *stream) 224{ 225 return NULL; 226} 227 228 229/////////////////////////////////////////////////////////////////////// 230 231ProgramVertexState::ProgramVertexState() 232{ 233} 234 235ProgramVertexState::~ProgramVertexState() 236{ 237} 238 239void ProgramVertexState::init(Context *rsc) 240{ 241 const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1); 242 const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2); 243 const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3); 244 const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); 245 246 rsc->mStateElement.elementBuilderBegin(); 247 rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1); 248 rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1); 249 rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1); 250 rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1); 251 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc); 252 253 rsc->mStateElement.elementBuilderBegin(); 254 rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1); 255 rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1); 256 rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1); 257 rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1); 258 const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc); 259 260 Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false); 261 262 String8 shaderString(RS_SHADER_INTERNAL); 263 shaderString.append("varying vec4 varColor;\n"); 264 shaderString.append("varying vec2 varTex0;\n"); 265 shaderString.append("void main() {\n"); 266 shaderString.append(" gl_Position = UNI_MVP * ATTRIB_position;\n"); 267 shaderString.append(" gl_PointSize = 1.0;\n"); 268 shaderString.append(" varColor = ATTRIB_color;\n"); 269 shaderString.append(" varTex0 = ATTRIB_texture0;\n"); 270 shaderString.append("}\n"); 271 272 uint32_t tmp[6]; 273 tmp[0] = RS_PROGRAM_PARAM_CONSTANT; 274 tmp[1] = (uint32_t)inputType; 275 tmp[2] = RS_PROGRAM_PARAM_INPUT; 276 tmp[3] = (uint32_t)attrElem; 277 tmp[4] = RS_PROGRAM_PARAM_TEXTURE_COUNT; 278 tmp[5] = 0; 279 280 ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), 281 shaderString.length(), tmp, 6); 282 Allocation *alloc = new Allocation(rsc, inputType); 283 pv->bindAllocation(rsc, alloc, 0); 284 285 mDefaultAlloc.set(alloc); 286 mDefault.set(pv); 287 288 updateSize(rsc); 289 290} 291 292void ProgramVertexState::updateSize(Context *rsc) 293{ 294 float *f = static_cast<float *>(mDefaultAlloc->getPtr()); 295 296 Matrix m; 297 m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1); 298 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m)); 299 memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m)); 300 301 m.loadIdentity(); 302 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m.m, sizeof(m)); 303 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m.m, sizeof(m)); 304} 305 306void ProgramVertexState::deinit(Context *rsc) 307{ 308 mDefaultAlloc.clear(); 309 mDefault.clear(); 310 mLast.clear(); 311} 312 313 314namespace android { 315namespace renderscript { 316 317RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText, 318 uint32_t shaderLength, const uint32_t * params, 319 uint32_t paramLength) 320{ 321 ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength); 322 pv->incUserRef(); 323 return pv; 324} 325 326 327} 328} 329