rsProgram.cpp revision cd50653f99c960e1a47c2c30e53b369b8805344a
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
18#include "rsProgram.h"
19
20#include <GLES2/gl2.h>
21#include <GLES2/gl2ext.h>
22
23using namespace android;
24using namespace android::renderscript;
25
26
27Program::Program(Context *rsc) : ObjectBase(rsc)
28{
29    mAllocFile = __FILE__;
30    mAllocLine = __LINE__;
31    mDirty = true;
32    mShaderID = 0;
33    mAttribCount = 0;
34    mUniformCount = 0;
35
36    mInputElements = NULL;
37    mOutputElements = NULL;
38    mConstantTypes = NULL;
39    mInputCount = 0;
40    mOutputCount = 0;
41    mConstantCount = 0;
42}
43
44Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
45                 const uint32_t * params, uint32_t paramLength) :
46    ObjectBase(rsc)
47{
48    mAllocFile = __FILE__;
49    mAllocLine = __LINE__;
50    mDirty = true;
51    mShaderID = 0;
52    mAttribCount = 0;
53    mUniformCount = 0;
54    mTextureCount = 0;
55
56    mInputCount = 0;
57    mOutputCount = 0;
58    mConstantCount = 0;
59
60    for (uint32_t ct=0; ct < paramLength; ct+=2) {
61        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
62            mInputCount++;
63        }
64        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
65            mOutputCount++;
66        }
67        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
68            mConstantCount++;
69        }
70        if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
71            mTextureCount = params[ct+1];
72        }
73    }
74
75    mInputElements = new ObjectBaseRef<Element>[mInputCount];
76    mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
77    mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
78
79    uint32_t input = 0;
80    uint32_t output = 0;
81    uint32_t constant = 0;
82    for (uint32_t ct=0; ct < paramLength; ct+=2) {
83        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
84            mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
85        }
86        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
87            mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
88        }
89        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
90            mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
91        }
92    }
93    mUserShader.setTo(shaderText, shaderLength);
94}
95
96Program::~Program()
97{
98    bindAllocation(NULL);
99
100    delete[] mInputElements;
101    delete[] mOutputElements;
102    delete[] mConstantTypes;
103    mInputCount = 0;
104    mOutputCount = 0;
105    mConstantCount = 0;
106}
107
108
109void Program::bindAllocation(Allocation *alloc)
110{
111    if (mConstants.get() == alloc) {
112        return;
113    }
114    if (mConstants.get()) {
115        mConstants.get()->removeProgramToDirty(this);
116    }
117    mConstants.set(alloc);
118    if (alloc) {
119        alloc->addProgramToDirty(this);
120    }
121    mDirty = true;
122}
123
124void Program::createShader()
125{
126}
127
128bool Program::loadShader(Context *rsc, uint32_t type)
129{
130    mShaderID = glCreateShader(type);
131    rsAssert(mShaderID);
132
133    if (rsc->props.mLogShaders) {
134        LOGV("Loading shader type %x, ID %i", type, mShaderID);
135        LOGV(mShader.string());
136    }
137
138    if (mShaderID) {
139        const char * ss = mShader.string();
140        glShaderSource(mShaderID, 1, &ss, NULL);
141        glCompileShader(mShaderID);
142
143        GLint compiled = 0;
144        glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
145        if (!compiled) {
146            GLint infoLen = 0;
147            glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
148            if (infoLen) {
149                char* buf = (char*) malloc(infoLen);
150                if (buf) {
151                    glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
152                    LOGE("Could not compile shader \n%s\n", buf);
153                    free(buf);
154                }
155                glDeleteShader(mShaderID);
156                mShaderID = 0;
157                return false;
158            }
159        }
160    }
161
162    if (rsc->props.mLogShaders) {
163        LOGV("--Shader load result %x ", glGetError());
164    }
165    return true;
166}
167
168void Program::setShader(const char *txt, uint32_t len)
169{
170    mUserShader.setTo(txt, len);
171}
172
173
174
175namespace android {
176namespace renderscript {
177
178
179void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
180{
181    Program *p = static_cast<Program *>(vp);
182    p->bindAllocation(static_cast<Allocation *>(constants));
183}
184
185
186}
187}
188
189