rsProgram.cpp revision 84e4027f83b20af59f5b1fc52be6e45f159d3970
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
17fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST
18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsContext.h"
19c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams#include <GLES2/gl2.h>
20c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams#include <GLES2/gl2ext.h>
21fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#else
22fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include "rsContextHostStub.h"
23fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include <OpenGL/gl.h>
24fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include <OpenGL/glext.h>
25fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#endif //ANDROID_RS_BUILD_FOR_HOST
26fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
27fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include "rsProgram.h"
28c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
29326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
30326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
31326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
32afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgram::Program(Context *rsc) : ObjectBase(rsc) {
3354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk   initMemberVars();
344815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
354815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
364815c0d121310cfcd6a8aba4eab77a9910af53acJason SamsProgram::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
37afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                 const uint32_t * params, uint32_t paramLength)
38afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    : ObjectBase(rsc) {
394815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
40afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    initMemberVars();
414815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (uint32_t ct=0; ct < paramLength; ct+=2) {
424815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
434815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mInputCount++;
444815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
454815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
464815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mOutputCount++;
474815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
484815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
494815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mConstantCount++;
504815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
5184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
5284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            mTextureCount++;
53f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams        }
544815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
554815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
56383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    mTextures = new ObjectBaseRef<Allocation>[mTextureCount];
57383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    mSamplers = new ObjectBaseRef<Sampler>[mTextureCount];
5884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    mTextureTargets = new RsTextureTarget[mTextureCount];
594815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputElements = new ObjectBaseRef<Element>[mInputCount];
604815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
614815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
6254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mConstants = new ObjectBaseRef<Allocation>[mConstantCount];
634815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
644815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t input = 0;
654815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t output = 0;
664815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t constant = 0;
6784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint32_t texture = 0;
684815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (uint32_t ct=0; ct < paramLength; ct+=2) {
694815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
704815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
714815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
724815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
734815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
744815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
754815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
764815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
774815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
7884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
7984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            mTextureTargets[texture++] = (RsTextureTarget)params[ct+1];
8084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
814815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
82e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mIsInternal = false;
83e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL);
84afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (shaderLength > internalTokenLen &&
85e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk       strncmp(RS_SHADER_INTERNAL, shaderText, internalTokenLen) == 0) {
86e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        mIsInternal = true;
87e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        shaderText += internalTokenLen;
88e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        shaderLength -= internalTokenLen;
89e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    }
904815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mUserShader.setTo(shaderText, shaderLength);
9154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
9254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    initAttribAndUniformArray();
93326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
94326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
95afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgram::~Program() {
96afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mRSC->props.mLogShaders) {
97889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk        LOGV("Program::~Program with shader id %u", mShaderID);
98889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk    }
99889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk
100afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mShaderID) {
101889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk        glDeleteShader(mShaderID);
102889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk    }
103889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk
10454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    for (uint32_t ct=0; ct < mConstantCount; ct++) {
105383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        bindAllocation(NULL, NULL, ct);
1069ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    }
1074815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
108383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    for (uint32_t ct=0; ct < mTextureCount; ct++) {
109383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        bindTexture(NULL, ct, NULL);
110383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        bindSampler(NULL, ct, NULL);
111383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
112383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    delete[] mTextures;
113383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    delete[] mSamplers;
11484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    delete[] mTextureTargets;
1154815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mInputElements;
1164815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mOutputElements;
1174815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mConstantTypes;
11854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    delete[] mConstants;
11954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    delete[] mAttribNames;
12054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    delete[] mUniformNames;
12154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    delete[] mUniformArraySizes;
1224815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputCount = 0;
1234815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputCount = 0;
1244815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantCount = 0;
125326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
126326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
12754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchoukvoid Program::initMemberVars() {
12854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mDirty = true;
12954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mShaderID = 0;
13054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mAttribCount = 0;
13154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mUniformCount = 0;
13254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mTextureCount = 0;
13354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
13454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mTextures = NULL;
13554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mSamplers = NULL;
13684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    mTextureTargets = NULL;
13754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mInputElements = NULL;
13854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mOutputElements = NULL;
13954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mConstantTypes = NULL;
14054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mConstants = NULL;
14154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mAttribNames = NULL;
14254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mUniformNames = NULL;
14354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mUniformArraySizes = NULL;
14454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mInputCount = 0;
14554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mOutputCount = 0;
14654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mConstantCount = 0;
14754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mIsValid = false;
14854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mIsInternal = false;
14954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk}
150326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
151afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
152383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    if (alloc != NULL) {
153383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        if (slot >= mConstantCount) {
154383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            LOGE("Attempt to bind alloc at slot %u, on shader id %u, but const count is %u",
155383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk                 slot, (uint32_t)this, mConstantCount);
156383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
157383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            return;
158383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        }
159383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        if (!alloc->getType()->isEqual(mConstantTypes[slot].get())) {
160383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
161383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk                 slot, (uint32_t)this);
162383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
163383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            return;
164383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        }
165383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
1669ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    if (mConstants[slot].get() == alloc) {
1675c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        return;
1685c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
1699ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    if (mConstants[slot].get()) {
1709ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams        mConstants[slot].get()->removeProgramToDirty(this);
1715c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
1729ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    mConstants[slot].set(alloc);
1735c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    if (alloc) {
1745c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        alloc->addProgramToDirty(this);
1755c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
176326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mDirty = true;
177326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
178326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
179afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) {
180383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    if (slot >= mTextureCount) {
181383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mTextureCount);
182383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture");
1837dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams        return;
1847dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    }
1857dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
18684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) {
18784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot);
18884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot");
18984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return;
19084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
19184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
1927dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    //LOGE("bindtex %i %p", slot, a);
1937dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mTextures[slot].set(a);
1947dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mDirty = true;
1957dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
1967dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
197afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s) {
198383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    if (slot >= mTextureCount) {
199383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mTextureCount);
200383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler");
2017dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams        return;
2027dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    }
2037dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
2047dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mSamplers[slot].set(s);
2057dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mDirty = true;
2067dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
2077dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
208afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukString8 Program::getGLSLInputString() const {
209b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    String8 s;
210b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    for (uint32_t ct=0; ct < mInputCount; ct++) {
211b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        const Element *e = mInputElements[ct].get();
212b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        for (uint32_t field=0; field < e->getFieldCount(); field++) {
213b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            const Element *f = e->getField(field);
214b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
215b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            // Cannot be complex
216b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            rsAssert(!f->getFieldCount());
217afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            switch (f->getComponent().getVectorSize()) {
218b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 1: s.append("attribute float ATTRIB_"); break;
219b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 2: s.append("attribute vec2 ATTRIB_"); break;
220b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 3: s.append("attribute vec3 ATTRIB_"); break;
221b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 4: s.append("attribute vec4 ATTRIB_"); break;
222b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            default:
223b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams                rsAssert(0);
224b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            }
225b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
226b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            s.append(e->getFieldName(field));
227b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            s.append(";\n");
228b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        }
229b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    }
230b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    return s;
231b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams}
232b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
233afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukString8 Program::getGLSLOutputString() const {
234b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    return String8();
235b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams}
236b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
237afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukString8 Program::getGLSLConstantString() const {
238b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    return String8();
239b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams}
240b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
241afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Program::createShader() {
242c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
243c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
244afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool Program::loadShader(Context *rsc, uint32_t type) {
245c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mShaderID = glCreateShader(type);
246c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    rsAssert(mShaderID);
247c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
248cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    if (rsc->props.mLogShaders) {
249cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams        LOGV("Loading shader type %x, ID %i", type, mShaderID);
2508492a70e1265925903c5e2389fd1d185d82c7047Nick Kralevich        LOGV("%s", mShader.string());
251cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    }
252c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
253c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    if (mShaderID) {
254c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        const char * ss = mShader.string();
255c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glShaderSource(mShaderID, 1, &ss, NULL);
256c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glCompileShader(mShaderID);
257cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams
258c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        GLint compiled = 0;
259c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
260c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        if (!compiled) {
261c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            GLint infoLen = 0;
262c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
263c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            if (infoLen) {
264c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                char* buf = (char*) malloc(infoLen);
265c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                if (buf) {
266c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
267c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    LOGE("Could not compile shader \n%s\n", buf);
268c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    free(buf);
269c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                }
270c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                glDeleteShader(mShaderID);
271c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                mShaderID = 0;
272a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams                rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
273c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                return false;
274c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            }
275c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        }
276c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    }
277cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams
278cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    if (rsc->props.mLogShaders) {
279cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams        LOGV("--Shader load result %x ", glGetError());
280cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    }
281a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams    mIsValid = true;
282c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    return true;
283c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
284f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams
285afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Program::setShader(const char *txt, uint32_t len) {
286f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams    mUserShader.setTo(txt, len);
287f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams}
288f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams
2896e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchoukvoid Program::appendUserConstants() {
2906e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    for (uint32_t ct=0; ct < mConstantCount; ct++) {
2916e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const Element *e = mConstantTypes[ct]->getElement();
2926e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        for (uint32_t field=0; field < e->getFieldCount(); field++) {
2936e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const Element *f = e->getField(field);
2946e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const char *fn = e->getFieldName(field);
2956e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
2966e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            if (fn[0] == '#') {
2976e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                continue;
2986e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
2996e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
3006e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            // Cannot be complex
3016e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            rsAssert(!f->getFieldCount());
302afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (f->getType() == RS_TYPE_MATRIX_4X4) {
3036e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                mShader.append("uniform mat4 UNI_");
304afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
3056e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                mShader.append("uniform mat3 UNI_");
306afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
3076e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                mShader.append("uniform mat2 UNI_");
308afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            } else {
309afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                switch (f->getComponent().getVectorSize()) {
3106e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 1: mShader.append("uniform float UNI_"); break;
3116e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 2: mShader.append("uniform vec2 UNI_"); break;
3126e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 3: mShader.append("uniform vec3 UNI_"); break;
3136e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 4: mShader.append("uniform vec4 UNI_"); break;
3146e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                default:
3156e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    rsAssert(0);
3166e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                }
3176e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
3186e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
3196e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            mShader.append(fn);
320afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (e->getFieldArraySize(field) > 1) {
32154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                mShader.appendFormat("[%d]", e->getFieldArraySize(field));
32254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            }
3236e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            mShader.append(";\n");
3246e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
3256e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    }
3266e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk}
3276e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
32854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchoukvoid Program::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
32954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    RsDataType dataType = field->getType();
33054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    uint32_t elementSize = field->getSizeBytes() / sizeof(float);
331afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t i = 0; i < arraySize; i ++) {
332afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (arraySize > 1) {
33354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV("Array Element [%u]", i);
33454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        }
335afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (dataType == RS_TYPE_MATRIX_4X4) {
33654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV("Matrix4x4");
33754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV("{%f, %f, %f, %f",  fd[0], fd[4], fd[8], fd[12]);
33854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV(" %f, %f, %f, %f",  fd[1], fd[5], fd[9], fd[13]);
33954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV(" %f, %f, %f, %f",  fd[2], fd[6], fd[10], fd[14]);
34054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
341afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        } else if (dataType == RS_TYPE_MATRIX_3X3) {
34254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV("Matrix3x3");
34354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV("{%f, %f, %f",  fd[0], fd[3], fd[6]);
34454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV(" %f, %f, %f",  fd[1], fd[4], fd[7]);
34554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
346afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        } else if (dataType == RS_TYPE_MATRIX_2X2) {
34754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV("Matrix2x2");
34854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV("{%f, %f",  fd[0], fd[2]);
34954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            LOGV(" %f, %f}", fd[1], fd[3]);
350afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        } else {
351afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            switch (field->getComponent().getVectorSize()) {
35254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            case 1:
35354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                LOGV("Uniform 1 = %f", fd[0]);
35454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                break;
35554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            case 2:
35654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
35754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                break;
35854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            case 3:
35954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
36054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                break;
36154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            case 4:
36254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
36354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                break;
36454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            default:
36554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                rsAssert(0);
36654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            }
36754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        }
36854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        LOGE("Element size %u data=%p", elementSize, fd);
36954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        fd += elementSize;
37054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        LOGE("New data=%p", fd);
37154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
37254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk}
37354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
37454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchoukvoid Program::setUniform(Context *rsc, const Element *field, const float *fd,
37554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                         int32_t slot, uint32_t arraySize ) {
37654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    RsDataType dataType = field->getType();
377afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (dataType == RS_TYPE_MATRIX_4X4) {
37854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
379afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    } else if (dataType == RS_TYPE_MATRIX_3X3) {
38054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
381afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    } else if (dataType == RS_TYPE_MATRIX_2X2) {
38254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
383afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    } else {
384afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        switch (field->getComponent().getVectorSize()) {
38554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        case 1:
38654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            glUniform1fv(slot, arraySize, fd);
38754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            break;
38854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        case 2:
38954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            glUniform2fv(slot, arraySize, fd);
39054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            break;
39154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        case 3:
39254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            glUniform3fv(slot, arraySize, fd);
39354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            break;
39454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        case 4:
39554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            glUniform4fv(slot, arraySize, fd);
39654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            break;
39754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        default:
39854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            rsAssert(0);
39954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        }
40054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
40154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk}
40254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
403383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchoukvoid Program::setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment) {
404e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    uint32_t uidx = 0;
4056e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    for (uint32_t ct=0; ct < mConstantCount; ct++) {
406e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        Allocation *alloc = mConstants[ct].get();
4076e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        if (!alloc) {
408383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
409383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
4106e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            continue;
4116e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
4126e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
4136e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
4146e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const Element *e = mConstantTypes[ct]->getElement();
4156e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        for (uint32_t field=0; field < e->getFieldCount(); field++) {
4166e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const Element *f = e->getField(field);
4176e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const char *fieldName = e->getFieldName(field);
4186e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            // If this field is padding, skip it
419afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (fieldName[0] == '#') {
4206e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                continue;
4216e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
4226e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
4236e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            uint32_t offset = e->getFieldOffsetBytes(field);
4246e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const float *fd = reinterpret_cast<const float *>(&data[offset]);
4256e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
4266e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            int32_t slot = -1;
42754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            uint32_t arraySize = 1;
428afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (!isFragment) {
4296e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                slot = sc->vtxUniformSlot(uidx);
43054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                arraySize = sc->vtxUniformSize(uidx);
43154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            } else {
4326e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                slot = sc->fragUniformSlot(uidx);
43354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                arraySize = sc->fragUniformSize(uidx);
4346e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
435afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (rsc->props.mLogShadersUniforms) {
436886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk                LOGV("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
437886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk            }
4386e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            uidx ++;
43954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            if (slot < 0) {
44054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                continue;
44154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            }
44254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
443afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (rsc->props.mLogShadersUniforms) {
44454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                logUniform(f, fd, arraySize);
44554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            }
44654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            setUniform(rsc, f, fd, slot, arraySize);
4476e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
4486e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    }
4496e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk}
4504815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
45154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchoukvoid Program::initAttribAndUniformArray() {
45254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mAttribCount = 0;
45354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    for (uint32_t ct=0; ct < mInputCount; ct++) {
45454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        const Element *elem = mInputElements[ct].get();
45554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
456afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (elem->getFieldName(field)[0] != '#') {
45754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                mAttribCount ++;
45854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            }
45954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        }
46054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
46154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
46254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mUniformCount = 0;
46354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    for (uint32_t ct=0; ct < mConstantCount; ct++) {
46454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        const Element *elem = mConstantTypes[ct]->getElement();
46554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
46654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
467afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (elem->getFieldName(field)[0] != '#') {
46854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                mUniformCount ++;
46954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            }
47054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        }
47154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
47254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    mUniformCount += mTextureCount;
47354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
474afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mAttribCount) {
47554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        mAttribNames = new String8[mAttribCount];
47654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
477afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mUniformCount) {
47854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        mUniformNames = new String8[mUniformCount];
47954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        mUniformArraySizes = new uint32_t[mUniformCount];
48054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
48154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk}
48254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
483afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Program::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
4846e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    rsAssert(e->getFieldCount());
4856e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
4866e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const Element *ce = e->getField(ct);
4876e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        if (ce->getFieldCount()) {
48854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            initAddUserElement(ce, names, arrayLengths, count, prefix);
489afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        } else if (e->getFieldName(ct)[0] != '#') {
4906e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            String8 tmp(prefix);
4916e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            tmp.append(e->getFieldName(ct));
4926e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            names[*count].setTo(tmp.string());
493afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            if (arrayLengths) {
49454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk                arrayLengths[*count] = e->getFieldArraySize(ct);
49554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            }
4966e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            (*count)++;
4976e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
4986e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    }
4996e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk}
5004815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
5014815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsnamespace android {
5024815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsnamespace renderscript {
5034815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
504afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants) {
5054815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    Program *p = static_cast<Program *>(vp);
506383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    p->bindAllocation(rsc, static_cast<Allocation *>(constants), slot);
5074815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
5084815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
509afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a) {
5107dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    Program *p = static_cast<Program *>(vpf);
511383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    p->bindTexture(rsc, slot, static_cast<Allocation *>(a));
5127dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
5137dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
514afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s) {
5157dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    Program *p = static_cast<Program *>(vpf);
516383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    p->bindSampler(rsc, slot, static_cast<Sampler *>(s));
5177dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
5184815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
5194815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
5204815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
5214815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
522