rsProgram.cpp revision e7ae69f4a70f1813cf8086ebd9714192c635300a
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
32326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
334815c0d121310cfcd6a8aba4eab77a9910af53acJason SamsProgram::Program(Context *rsc) : ObjectBase(rsc)
34326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{
35f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mAllocFile = __FILE__;
36f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mAllocLine = __LINE__;
37c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mDirty = true;
38c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mShaderID = 0;
39c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mAttribCount = 0;
40c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mUniformCount = 0;
41f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
424815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputElements = NULL;
434815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputElements = NULL;
444815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantTypes = NULL;
454815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputCount = 0;
464815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputCount = 0;
474815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantCount = 0;
48a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams    mIsValid = false;
49e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mIsInternal = false;
504815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
514815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
524815c0d121310cfcd6a8aba4eab77a9910af53acJason SamsProgram::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
534815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams                 const uint32_t * params, uint32_t paramLength) :
544815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    ObjectBase(rsc)
554815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams{
564815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mAllocFile = __FILE__;
574815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mAllocLine = __LINE__;
584815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mDirty = true;
594815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mShaderID = 0;
604815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mAttribCount = 0;
614815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mUniformCount = 0;
62f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams    mTextureCount = 0;
634815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
644815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputCount = 0;
654815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputCount = 0;
664815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantCount = 0;
674815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
684815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (uint32_t ct=0; ct < paramLength; ct+=2) {
694815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
704815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mInputCount++;
714815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
724815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
734815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mOutputCount++;
744815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
754815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
764815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mConstantCount++;
774815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
78f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams        if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
79f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams            mTextureCount = params[ct+1];
80f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams        }
814815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
824815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
834815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputElements = new ObjectBaseRef<Element>[mInputCount];
844815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
854815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
864815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
874815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t input = 0;
884815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t output = 0;
894815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t constant = 0;
904815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (uint32_t ct=0; ct < paramLength; ct+=2) {
914815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
924815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
934815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
944815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
954815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
964815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
974815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
984815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
994815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
1004815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
101e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mIsInternal = false;
102e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL);
103e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    if(shaderLength > internalTokenLen &&
104e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk       strncmp(RS_SHADER_INTERNAL, shaderText, internalTokenLen) == 0) {
105e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        mIsInternal = true;
106e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        shaderText += internalTokenLen;
107e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        shaderLength -= internalTokenLen;
108e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    }
1094815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mUserShader.setTo(shaderText, shaderLength);
110326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
111326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
112326e0ddf89e8df2837752fbfd7a014814b32082cJason SamsProgram::~Program()
113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{
1149ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) {
1159ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams        bindAllocation(NULL, ct);
1169ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    }
1174815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1184815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mInputElements;
1194815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mOutputElements;
1204815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mConstantTypes;
1214815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputCount = 0;
1224815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputCount = 0;
1234815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantCount = 0;
124326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
125326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
126326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1279ebb0c44ece47531f3d0a98ba52ae448de42032bJason Samsvoid Program::bindAllocation(Allocation *alloc, uint32_t slot)
128326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{
1299ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    if (mConstants[slot].get() == alloc) {
1305c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        return;
1315c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
1329ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    if (mConstants[slot].get()) {
1339ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams        mConstants[slot].get()->removeProgramToDirty(this);
1345c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
1359ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    mConstants[slot].set(alloc);
1365c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    if (alloc) {
1375c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        alloc->addProgramToDirty(this);
1385c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
139326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mDirty = true;
140326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
141326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1427dad9c30a59c99b57269e1b498807b6f034d56e9Jason Samsvoid Program::bindTexture(uint32_t slot, Allocation *a)
1437dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams{
1447dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    if (slot >= MAX_TEXTURE) {
1457dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams        LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
1467dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams        return;
1477dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    }
1487dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
1497dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    //LOGE("bindtex %i %p", slot, a);
1507dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mTextures[slot].set(a);
1517dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mDirty = true;
1527dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
1537dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
1547dad9c30a59c99b57269e1b498807b6f034d56e9Jason Samsvoid Program::bindSampler(uint32_t slot, Sampler *s)
1557dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams{
1567dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    if (slot >= MAX_TEXTURE) {
1577dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams        LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
1587dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams        return;
1597dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    }
1607dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
1617dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mSamplers[slot].set(s);
1627dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    mDirty = true;
1637dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
1647dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
165b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason SamsString8 Program::getGLSLInputString() const
166b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams{
167b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    String8 s;
168b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    for (uint32_t ct=0; ct < mInputCount; ct++) {
169b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        const Element *e = mInputElements[ct].get();
170b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        for (uint32_t field=0; field < e->getFieldCount(); field++) {
171b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            const Element *f = e->getField(field);
172b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
173b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            // Cannot be complex
174b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            rsAssert(!f->getFieldCount());
175b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            switch(f->getComponent().getVectorSize()) {
176b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 1: s.append("attribute float ATTRIB_"); break;
177b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 2: s.append("attribute vec2 ATTRIB_"); break;
178b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 3: s.append("attribute vec3 ATTRIB_"); break;
179b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            case 4: s.append("attribute vec4 ATTRIB_"); break;
180b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            default:
181b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams                rsAssert(0);
182b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            }
183b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
184b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            s.append(e->getFieldName(field));
185b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams            s.append(";\n");
186b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        }
187b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    }
188b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    return s;
189b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams}
190b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
191b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason SamsString8 Program::getGLSLOutputString() const
192b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams{
193b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    return String8();
194b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams}
195b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
196b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason SamsString8 Program::getGLSLConstantString() const
197b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams{
198b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    return String8();
199b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams}
200b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
2017dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
202c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid Program::createShader()
203c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{
204c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
205c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
206cd50653f99c960e1a47c2c30e53b369b8805344aJason Samsbool Program::loadShader(Context *rsc, uint32_t type)
207c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{
208c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mShaderID = glCreateShader(type);
209c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    rsAssert(mShaderID);
210c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
211cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    if (rsc->props.mLogShaders) {
212cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams        LOGV("Loading shader type %x, ID %i", type, mShaderID);
2138492a70e1265925903c5e2389fd1d185d82c7047Nick Kralevich        LOGV("%s", mShader.string());
214cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    }
215c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
216c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    if (mShaderID) {
217c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        const char * ss = mShader.string();
218c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glShaderSource(mShaderID, 1, &ss, NULL);
219c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glCompileShader(mShaderID);
220cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams
221c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        GLint compiled = 0;
222c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
223c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        if (!compiled) {
224c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            GLint infoLen = 0;
225c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
226c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            if (infoLen) {
227c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                char* buf = (char*) malloc(infoLen);
228c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                if (buf) {
229c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
230c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    LOGE("Could not compile shader \n%s\n", buf);
231c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    free(buf);
232c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                }
233c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                glDeleteShader(mShaderID);
234c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                mShaderID = 0;
235a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams                rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
236c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                return false;
237c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            }
238c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        }
239c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    }
240cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams
241cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    if (rsc->props.mLogShaders) {
242cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams        LOGV("--Shader load result %x ", glGetError());
243cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams    }
244a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams    mIsValid = true;
245c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    return true;
246c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
247f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams
248f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Samsvoid Program::setShader(const char *txt, uint32_t len)
249f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams{
250f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams    mUserShader.setTo(txt, len);
251f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams}
252f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams
2536e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchoukvoid Program::appendUserConstants() {
2546e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    for (uint32_t ct=0; ct < mConstantCount; ct++) {
2556e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const Element *e = mConstantTypes[ct]->getElement();
2566e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        for (uint32_t field=0; field < e->getFieldCount(); field++) {
2576e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const Element *f = e->getField(field);
2586e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const char *fn = e->getFieldName(field);
2596e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
2606e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            if (fn[0] == '#') {
2616e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                continue;
2626e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
2636e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
2646e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            // Cannot be complex
2656e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            rsAssert(!f->getFieldCount());
2666e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            if(f->getType() == RS_TYPE_MATRIX_4X4) {
2676e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                mShader.append("uniform mat4 UNI_");
2686e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
2696e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            else if(f->getType() == RS_TYPE_MATRIX_3X3) {
2706e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                mShader.append("uniform mat3 UNI_");
2716e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
2726e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            else if(f->getType() == RS_TYPE_MATRIX_2X2) {
2736e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                mShader.append("uniform mat2 UNI_");
2746e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
2756e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            else {
2766e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                switch(f->getComponent().getVectorSize()) {
2776e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 1: mShader.append("uniform float UNI_"); break;
2786e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 2: mShader.append("uniform vec2 UNI_"); break;
2796e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 3: mShader.append("uniform vec3 UNI_"); break;
2806e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                case 4: mShader.append("uniform vec4 UNI_"); break;
2816e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                default:
2826e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    rsAssert(0);
2836e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                }
2846e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
2856e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
2866e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            mShader.append(fn);
2876e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            mShader.append(";\n");
2886e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
2896e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    }
2906e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk}
2916e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
2926e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchoukvoid Program::setupUserConstants(ShaderCache *sc, bool isFragment) {
293e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    uint32_t uidx = 0;
2946e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    for (uint32_t ct=0; ct < mConstantCount; ct++) {
295e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        Allocation *alloc = mConstants[ct].get();
2966e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        if (!alloc) {
2976e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            continue;
2986e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
2996e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
3006e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
3016e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const Element *e = mConstantTypes[ct]->getElement();
3026e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        for (uint32_t field=0; field < e->getFieldCount(); field++) {
3036e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const Element *f = e->getField(field);
3046e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const char *fieldName = e->getFieldName(field);
3056e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            // If this field is padding, skip it
3066e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            if(fieldName[0] == '#') {
3076e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                continue;
3086e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
3096e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
3106e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            uint32_t offset = e->getFieldOffsetBytes(field);
3116e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            const float *fd = reinterpret_cast<const float *>(&data[offset]);
3126e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
3136e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            int32_t slot = -1;
3146e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            if(!isFragment) {
3156e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                slot = sc->vtxUniformSlot(uidx);
3166e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
3176e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            else {
3186e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                slot = sc->fragUniformSlot(uidx);
3196e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
3206e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
3216e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            //LOGE("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
3226e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            if (slot >= 0) {
3236e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                if(f->getType() == RS_TYPE_MATRIX_4X4) {
3246e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    glUniformMatrix4fv(slot, 1, GL_FALSE, fd);
325e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk                    /*for(int i = 0; i < 4; i++) {
326e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk                        LOGE("Mat = %f %f %f %f", fd[i*4 + 0], fd[i*4 + 1], fd[i*4 + 2], fd[i*4 + 3]);
327e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk                    }*/
3286e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                }
3296e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                else if(f->getType() == RS_TYPE_MATRIX_3X3) {
3306e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    glUniformMatrix3fv(slot, 1, GL_FALSE, fd);
3316e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                }
3326e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                else if(f->getType() == RS_TYPE_MATRIX_2X2) {
3336e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    glUniformMatrix2fv(slot, 1, GL_FALSE, fd);
3346e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                }
3356e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                else {
3366e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    switch(f->getComponent().getVectorSize()) {
3376e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    case 1:
3386e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        //LOGE("Uniform 1 = %f", fd[0]);
3396e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        glUniform1fv(slot, 1, fd);
3406e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        break;
3416e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    case 2:
3426e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
3436e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        glUniform2fv(slot, 1, fd);
3446e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        break;
3456e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    case 3:
3466e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
3476e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        glUniform3fv(slot, 1, fd);
3486e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        break;
3496e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    case 4:
3506e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
3516e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        glUniform4fv(slot, 1, fd);
3526e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        break;
3536e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    default:
3546e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                        rsAssert(0);
3556e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                    }
3566e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk                }
3576e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            }
3586e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            uidx ++;
3596e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
3606e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    }
3616e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk}
3624815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
3636e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchoukvoid Program::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
3646e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk{
3656e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    rsAssert(e->getFieldCount());
3666e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
3676e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        const Element *ce = e->getField(ct);
3686e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        if (ce->getFieldCount()) {
3696e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            initAddUserElement(ce, names, count, prefix);
3706e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
3716e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        else if(e->getFieldName(ct)[0] != '#') {
3726e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            String8 tmp(prefix);
3736e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            tmp.append(e->getFieldName(ct));
3746e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            names[*count].setTo(tmp.string());
3756e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk            (*count)++;
3766e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk        }
3776e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk    }
3786e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk}
3794815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
3804815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsnamespace android {
3814815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsnamespace renderscript {
3824815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
3834815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
3844815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsvoid rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
3854815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams{
3864815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    Program *p = static_cast<Program *>(vp);
3879ebb0c44ece47531f3d0a98ba52ae448de42032bJason Sams    p->bindAllocation(static_cast<Allocation *>(constants), slot);
3884815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
3894815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
3907dad9c30a59c99b57269e1b498807b6f034d56e9Jason Samsvoid rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)
3917dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams{
3927dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    Program *p = static_cast<Program *>(vpf);
3937dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    p->bindTexture(slot, static_cast<Allocation *>(a));
3947dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
3957dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams
3967dad9c30a59c99b57269e1b498807b6f034d56e9Jason Samsvoid rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s)
3977dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams{
3987dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    Program *p = static_cast<Program *>(vpf);
3997dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams    p->bindSampler(slot, static_cast<Sampler *>(s));
4007dad9c30a59c99b57269e1b498807b6f034d56e9Jason Sams}
4014815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
4024815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
4034815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
4044815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
405