blob: ce3af2dd9e2ab9688313bc56db1dd3e67c3c336c [file] [log] [blame]
Jason Samsd19f10d2009-05-22 14:03:28 -07001/*
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
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Samsd19f10d2009-05-22 14:03:28 -070018#include "rsContext.h"
Jason Samsbb51c402009-11-25 13:22:07 -080019#include <GLES2/gl2.h>
20#include <GLES2/gl2ext.h>
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070021#else
22#include "rsContextHostStub.h"
23#include <OpenGL/gl.h>
24#include <OpenGL/glext.h>
25#endif //ANDROID_RS_BUILD_FOR_HOST
26
27#include "rsProgram.h"
Jason Samsbb51c402009-11-25 13:22:07 -080028
Jason Samsd19f10d2009-05-22 14:03:28 -070029using namespace android;
30using namespace android::renderscript;
31
Jason Sams0011bcf2009-12-15 12:58:36 -080032Program::Program(Context *rsc) : ObjectBase(rsc)
Jason Samsd19f10d2009-05-22 14:03:28 -070033{
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080034 initMemberVars();
Jason Sams0011bcf2009-12-15 12:58:36 -080035}
36
37Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
38 const uint32_t * params, uint32_t paramLength) :
39 ObjectBase(rsc)
40{
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080041 initMemberVars();
Jason Sams0011bcf2009-12-15 12:58:36 -080042
43 for (uint32_t ct=0; ct < paramLength; ct+=2) {
44 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
45 mInputCount++;
46 }
47 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
48 mOutputCount++;
49 }
50 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
51 mConstantCount++;
52 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -080053 if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
54 mTextureCount = params[ct+1];
55 }
Jason Sams0011bcf2009-12-15 12:58:36 -080056 }
57
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -070058 mTextures = new ObjectBaseRef<Allocation>[mTextureCount];
59 mSamplers = new ObjectBaseRef<Sampler>[mTextureCount];
Jason Sams0011bcf2009-12-15 12:58:36 -080060 mInputElements = new ObjectBaseRef<Element>[mInputCount];
61 mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
62 mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080063 mConstants = new ObjectBaseRef<Allocation>[mConstantCount];
Jason Sams0011bcf2009-12-15 12:58:36 -080064
65 uint32_t input = 0;
66 uint32_t output = 0;
67 uint32_t constant = 0;
68 for (uint32_t ct=0; ct < paramLength; ct+=2) {
69 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
70 mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
71 }
72 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
73 mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
74 }
75 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
76 mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
77 }
78 }
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070079 mIsInternal = false;
80 uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL);
81 if(shaderLength > internalTokenLen &&
82 strncmp(RS_SHADER_INTERNAL, shaderText, internalTokenLen) == 0) {
83 mIsInternal = true;
84 shaderText += internalTokenLen;
85 shaderLength -= internalTokenLen;
86 }
Jason Sams0011bcf2009-12-15 12:58:36 -080087 mUserShader.setTo(shaderText, shaderLength);
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -080088
89 initAttribAndUniformArray();
Jason Samsd19f10d2009-05-22 14:03:28 -070090}
91
92Program::~Program()
93{
Alex Sakhartchoukfeede2a2010-10-01 10:54:06 -070094 if(mRSC->props.mLogShaders) {
95 LOGV("Program::~Program with shader id %u", mShaderID);
96 }
97
98 if(mShaderID) {
99 glDeleteShader(mShaderID);
100 }
101
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800102 for (uint32_t ct=0; ct < mConstantCount; ct++) {
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700103 bindAllocation(NULL, NULL, ct);
Jason Samsea87e962010-01-12 12:12:28 -0800104 }
Jason Sams0011bcf2009-12-15 12:58:36 -0800105
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700106 for (uint32_t ct=0; ct < mTextureCount; ct++) {
107 bindTexture(NULL, ct, NULL);
108 bindSampler(NULL, ct, NULL);
109 }
110 delete[] mTextures;
111 delete[] mSamplers;
Jason Sams0011bcf2009-12-15 12:58:36 -0800112 delete[] mInputElements;
113 delete[] mOutputElements;
114 delete[] mConstantTypes;
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800115 delete[] mConstants;
116 delete[] mAttribNames;
117 delete[] mUniformNames;
118 delete[] mUniformArraySizes;
Jason Sams0011bcf2009-12-15 12:58:36 -0800119 mInputCount = 0;
120 mOutputCount = 0;
121 mConstantCount = 0;
Jason Samsd19f10d2009-05-22 14:03:28 -0700122}
123
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800124void Program::initMemberVars() {
125 mDirty = true;
126 mShaderID = 0;
127 mAttribCount = 0;
128 mUniformCount = 0;
129 mTextureCount = 0;
130
131 mTextures = NULL;
132 mSamplers = NULL;
133 mInputElements = NULL;
134 mOutputElements = NULL;
135 mConstantTypes = NULL;
136 mConstants = NULL;
137 mAttribNames = NULL;
138 mUniformNames = NULL;
139 mUniformArraySizes = NULL;
140 mInputCount = 0;
141 mOutputCount = 0;
142 mConstantCount = 0;
143 mIsValid = false;
144 mIsInternal = false;
145}
Jason Samsd19f10d2009-05-22 14:03:28 -0700146
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700147void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot)
Jason Samsd19f10d2009-05-22 14:03:28 -0700148{
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700149 if (alloc != NULL) {
150 if (slot >= mConstantCount) {
151 LOGE("Attempt to bind alloc at slot %u, on shader id %u, but const count is %u",
152 slot, (uint32_t)this, mConstantCount);
153 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
154 return;
155 }
156 if (!alloc->getType()->isEqual(mConstantTypes[slot].get())) {
157 LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
158 slot, (uint32_t)this);
159 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
160 return;
161 }
162 }
Jason Samsea87e962010-01-12 12:12:28 -0800163 if (mConstants[slot].get() == alloc) {
Jason Sams83f1c632009-10-26 15:19:28 -0700164 return;
165 }
Jason Samsea87e962010-01-12 12:12:28 -0800166 if (mConstants[slot].get()) {
167 mConstants[slot].get()->removeProgramToDirty(this);
Jason Sams83f1c632009-10-26 15:19:28 -0700168 }
Jason Samsea87e962010-01-12 12:12:28 -0800169 mConstants[slot].set(alloc);
Jason Sams83f1c632009-10-26 15:19:28 -0700170 if (alloc) {
171 alloc->addProgramToDirty(this);
172 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700173 mDirty = true;
174}
175
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700176void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a)
Jason Sams68afd012009-12-17 16:55:08 -0800177{
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700178 if (slot >= mTextureCount) {
179 LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mTextureCount);
180 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture");
Jason Sams68afd012009-12-17 16:55:08 -0800181 return;
182 }
183
184 //LOGE("bindtex %i %p", slot, a);
185 mTextures[slot].set(a);
186 mDirty = true;
187}
188
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700189void Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s)
Jason Sams68afd012009-12-17 16:55:08 -0800190{
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700191 if (slot >= mTextureCount) {
192 LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mTextureCount);
193 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler");
Jason Sams68afd012009-12-17 16:55:08 -0800194 return;
195 }
196
197 mSamplers[slot].set(s);
198 mDirty = true;
199}
200
Jason Samse17964e2010-01-04 16:52:27 -0800201String8 Program::getGLSLInputString() const
202{
203 String8 s;
204 for (uint32_t ct=0; ct < mInputCount; ct++) {
205 const Element *e = mInputElements[ct].get();
206 for (uint32_t field=0; field < e->getFieldCount(); field++) {
207 const Element *f = e->getField(field);
208
209 // Cannot be complex
210 rsAssert(!f->getFieldCount());
211 switch(f->getComponent().getVectorSize()) {
212 case 1: s.append("attribute float ATTRIB_"); break;
213 case 2: s.append("attribute vec2 ATTRIB_"); break;
214 case 3: s.append("attribute vec3 ATTRIB_"); break;
215 case 4: s.append("attribute vec4 ATTRIB_"); break;
216 default:
217 rsAssert(0);
218 }
219
220 s.append(e->getFieldName(field));
221 s.append(";\n");
222 }
223 }
224 return s;
225}
226
227String8 Program::getGLSLOutputString() const
228{
229 return String8();
230}
231
232String8 Program::getGLSLConstantString() const
233{
234 return String8();
235}
236
Jason Sams68afd012009-12-17 16:55:08 -0800237
Jason Samsbb51c402009-11-25 13:22:07 -0800238void Program::createShader()
239{
240}
Jason Sams9bee51c2009-08-05 13:57:03 -0700241
Jason Sams5dad8b42009-12-15 19:10:11 -0800242bool Program::loadShader(Context *rsc, uint32_t type)
Jason Samsbb51c402009-11-25 13:22:07 -0800243{
244 mShaderID = glCreateShader(type);
245 rsAssert(mShaderID);
246
Jason Sams5dad8b42009-12-15 19:10:11 -0800247 if (rsc->props.mLogShaders) {
248 LOGV("Loading shader type %x, ID %i", type, mShaderID);
Nick Kralevichce2cbe42010-05-13 14:46:27 -0700249 LOGV("%s", mShader.string());
Jason Sams5dad8b42009-12-15 19:10:11 -0800250 }
Jason Samsbb51c402009-11-25 13:22:07 -0800251
252 if (mShaderID) {
253 const char * ss = mShader.string();
254 glShaderSource(mShaderID, 1, &ss, NULL);
255 glCompileShader(mShaderID);
256
257 GLint compiled = 0;
258 glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
259 if (!compiled) {
260 GLint infoLen = 0;
261 glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
262 if (infoLen) {
263 char* buf = (char*) malloc(infoLen);
264 if (buf) {
265 glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
266 LOGE("Could not compile shader \n%s\n", buf);
267 free(buf);
268 }
269 glDeleteShader(mShaderID);
270 mShaderID = 0;
Jason Sams156cce62010-03-03 13:03:18 -0800271 rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
Jason Samsbb51c402009-11-25 13:22:07 -0800272 return false;
273 }
274 }
275 }
Jason Sams5dad8b42009-12-15 19:10:11 -0800276
277 if (rsc->props.mLogShaders) {
278 LOGV("--Shader load result %x ", glGetError());
279 }
Jason Sams156cce62010-03-03 13:03:18 -0800280 mIsValid = true;
Jason Samsbb51c402009-11-25 13:22:07 -0800281 return true;
282}
Jason Sams54c0ec12009-11-30 14:49:55 -0800283
284void Program::setShader(const char *txt, uint32_t len)
285{
286 mUserShader.setTo(txt, len);
287}
288
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700289void Program::appendUserConstants() {
290 for (uint32_t ct=0; ct < mConstantCount; ct++) {
291 const Element *e = mConstantTypes[ct]->getElement();
292 for (uint32_t field=0; field < e->getFieldCount(); field++) {
293 const Element *f = e->getField(field);
294 const char *fn = e->getFieldName(field);
Jason Sams0011bcf2009-12-15 12:58:36 -0800295
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700296 if (fn[0] == '#') {
297 continue;
298 }
299
300 // Cannot be complex
301 rsAssert(!f->getFieldCount());
302 if(f->getType() == RS_TYPE_MATRIX_4X4) {
303 mShader.append("uniform mat4 UNI_");
304 }
305 else if(f->getType() == RS_TYPE_MATRIX_3X3) {
306 mShader.append("uniform mat3 UNI_");
307 }
308 else if(f->getType() == RS_TYPE_MATRIX_2X2) {
309 mShader.append("uniform mat2 UNI_");
310 }
311 else {
312 switch(f->getComponent().getVectorSize()) {
313 case 1: mShader.append("uniform float UNI_"); break;
314 case 2: mShader.append("uniform vec2 UNI_"); break;
315 case 3: mShader.append("uniform vec3 UNI_"); break;
316 case 4: mShader.append("uniform vec4 UNI_"); break;
317 default:
318 rsAssert(0);
319 }
320 }
321
322 mShader.append(fn);
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800323 if(e->getFieldArraySize(field) > 1) {
324 mShader.appendFormat("[%d]", e->getFieldArraySize(field));
325 }
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700326 mShader.append(";\n");
327 }
328 }
329}
330
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800331void Program::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
332 RsDataType dataType = field->getType();
333 uint32_t elementSize = field->getSizeBytes() / sizeof(float);
334 for(uint32_t i = 0; i < arraySize; i ++) {
335 if(arraySize > 1) {
336 LOGV("Array Element [%u]", i);
337 }
338 if(dataType == RS_TYPE_MATRIX_4X4) {
339 LOGV("Matrix4x4");
340 LOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
341 LOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
342 LOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
343 LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
344 }
345 else if(dataType == RS_TYPE_MATRIX_3X3) {
346 LOGV("Matrix3x3");
347 LOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
348 LOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
349 LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
350 }
351 else if(dataType == RS_TYPE_MATRIX_2X2) {
352 LOGV("Matrix2x2");
353 LOGV("{%f, %f", fd[0], fd[2]);
354 LOGV(" %f, %f}", fd[1], fd[3]);
355 }
356 else {
357 switch(field->getComponent().getVectorSize()) {
358 case 1:
359 LOGV("Uniform 1 = %f", fd[0]);
360 break;
361 case 2:
362 LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
363 break;
364 case 3:
365 LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
366 break;
367 case 4:
368 LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
369 break;
370 default:
371 rsAssert(0);
372 }
373 }
374 LOGE("Element size %u data=%p", elementSize, fd);
375 fd += elementSize;
376 LOGE("New data=%p", fd);
377 }
378}
379
380void Program::setUniform(Context *rsc, const Element *field, const float *fd,
381 int32_t slot, uint32_t arraySize ) {
382 RsDataType dataType = field->getType();
383 if(dataType == RS_TYPE_MATRIX_4X4) {
384 glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
385 }
386 else if(dataType == RS_TYPE_MATRIX_3X3) {
387 glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
388 }
389 else if(dataType == RS_TYPE_MATRIX_2X2) {
390 glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
391 }
392 else {
393 switch(field->getComponent().getVectorSize()) {
394 case 1:
395 glUniform1fv(slot, arraySize, fd);
396 break;
397 case 2:
398 glUniform2fv(slot, arraySize, fd);
399 break;
400 case 3:
401 glUniform3fv(slot, arraySize, fd);
402 break;
403 case 4:
404 glUniform4fv(slot, arraySize, fd);
405 break;
406 default:
407 rsAssert(0);
408 }
409 }
410}
411
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700412void Program::setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment) {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700413 uint32_t uidx = 0;
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700414 for (uint32_t ct=0; ct < mConstantCount; ct++) {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700415 Allocation *alloc = mConstants[ct].get();
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700416 if (!alloc) {
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700417 LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
418 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700419 continue;
420 }
421
422 const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
423 const Element *e = mConstantTypes[ct]->getElement();
424 for (uint32_t field=0; field < e->getFieldCount(); field++) {
425 const Element *f = e->getField(field);
426 const char *fieldName = e->getFieldName(field);
427 // If this field is padding, skip it
428 if(fieldName[0] == '#') {
429 continue;
430 }
431
432 uint32_t offset = e->getFieldOffsetBytes(field);
433 const float *fd = reinterpret_cast<const float *>(&data[offset]);
434
435 int32_t slot = -1;
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800436 uint32_t arraySize = 1;
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700437 if(!isFragment) {
438 slot = sc->vtxUniformSlot(uidx);
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800439 arraySize = sc->vtxUniformSize(uidx);
440 } else {
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700441 slot = sc->fragUniformSlot(uidx);
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800442 arraySize = sc->fragUniformSize(uidx);
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700443 }
Alex Sakhartchouk4378f112010-09-29 09:49:13 -0700444 if(rsc->props.mLogShadersUniforms) {
445 LOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
446 }
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700447 uidx ++;
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800448 if (slot < 0) {
449 continue;
450 }
451
452 if(rsc->props.mLogShadersUniforms) {
453 logUniform(f, fd, arraySize);
454 }
455 setUniform(rsc, f, fd, slot, arraySize);
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700456 }
457 }
458}
459
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800460void Program::initAttribAndUniformArray() {
461 mAttribCount = 0;
462 for (uint32_t ct=0; ct < mInputCount; ct++) {
463 const Element *elem = mInputElements[ct].get();
464 for (uint32_t field=0; field < elem->getFieldCount(); field++) {
465 if(elem->getFieldName(field)[0] != '#') {
466 mAttribCount ++;
467 }
468 }
469 }
470
471 mUniformCount = 0;
472 for (uint32_t ct=0; ct < mConstantCount; ct++) {
473 const Element *elem = mConstantTypes[ct]->getElement();
474
475 for (uint32_t field=0; field < elem->getFieldCount(); field++) {
476 if(elem->getFieldName(field)[0] != '#') {
477 mUniformCount ++;
478 }
479 }
480 }
481 mUniformCount += mTextureCount;
482
483 if(mAttribCount) {
484 mAttribNames = new String8[mAttribCount];
485 }
486 if(mUniformCount) {
487 mUniformNames = new String8[mUniformCount];
488 mUniformArraySizes = new uint32_t[mUniformCount];
489 }
490}
491
492void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix)
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700493{
494 rsAssert(e->getFieldCount());
495 for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
496 const Element *ce = e->getField(ct);
497 if (ce->getFieldCount()) {
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800498 initAddUserElement(ce, names, arrayLengths, count, prefix);
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700499 }
500 else if(e->getFieldName(ct)[0] != '#') {
501 String8 tmp(prefix);
502 tmp.append(e->getFieldName(ct));
503 names[*count].setTo(tmp.string());
Alex Sakhartchouk9d71e212010-11-08 15:10:52 -0800504 if(arrayLengths) {
505 arrayLengths[*count] = e->getFieldArraySize(ct);
506 }
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700507 (*count)++;
508 }
509 }
510}
Jason Sams0011bcf2009-12-15 12:58:36 -0800511
512namespace android {
513namespace renderscript {
514
515
516void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
517{
518 Program *p = static_cast<Program *>(vp);
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700519 p->bindAllocation(rsc, static_cast<Allocation *>(constants), slot);
Jason Sams0011bcf2009-12-15 12:58:36 -0800520}
521
Jason Sams68afd012009-12-17 16:55:08 -0800522void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)
523{
524 Program *p = static_cast<Program *>(vpf);
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700525 p->bindTexture(rsc, slot, static_cast<Allocation *>(a));
Jason Sams68afd012009-12-17 16:55:08 -0800526}
527
528void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s)
529{
530 Program *p = static_cast<Program *>(vpf);
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700531 p->bindSampler(rsc, slot, static_cast<Sampler *>(s));
Jason Sams68afd012009-12-17 16:55:08 -0800532}
Jason Sams0011bcf2009-12-15 12:58:36 -0800533
534}
535}
536