blob: c94f29432d90ec6f42f711b420041010c14ec284 [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 Sams4b962e52009-06-22 17:15:15 -070019#include <GLES/gl.h>
20#include <GLES/glext.h>
Jason Samsbb51c402009-11-25 13:22:07 -080021#include <GLES2/gl2.h>
22#include <GLES2/gl2ext.h>
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070023#else
24#include "rsContextHostStub.h"
25#include <OpenGL/gl.h>
26#include <OpenGL/glext.h>
27#endif //ANDROID_RS_BUILD_FOR_HOST
28
29#include "rsProgramFragment.h"
Jason Sams4b962e52009-06-22 17:15:15 -070030
Jason Samsd19f10d2009-05-22 14:03:28 -070031using namespace android;
32using namespace android::renderscript;
33
Jason Sams7e5ab3b2009-12-15 13:27:04 -080034ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
35 uint32_t shaderLength, const uint32_t * params,
36 uint32_t paramLength) :
37 Program(rsc, shaderText, shaderLength, params, paramLength)
38{
39 mAllocFile = __FILE__;
40 mAllocLine = __LINE__;
41
Jason Sams442a6472010-08-04 17:50:20 -070042 mConstantColor[0] = 1.f;
43 mConstantColor[1] = 1.f;
44 mConstantColor[2] = 1.f;
45 mConstantColor[3] = 1.f;
46
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -070047 init(rsc);
Jason Sams7e5ab3b2009-12-15 13:27:04 -080048}
49
Jason Samsd19f10d2009-05-22 14:03:28 -070050ProgramFragment::~ProgramFragment()
51{
Alex Sakhartchoukfeede2a2010-10-01 10:54:06 -070052 if(mShaderID) {
53 mRSC->mShaderCache.cleanupFragment(mShaderID);
54 }
Jason Samsd19f10d2009-05-22 14:03:28 -070055}
56
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -070057void ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b, float a)
Jason Sams442a6472010-08-04 17:50:20 -070058{
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070059 if(isUserProgram()) {
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -070060 LOGE("Attempting to set fixed function emulation color on user program");
61 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set fixed function emulation color on user program");
62 return;
63 }
64 if(mConstants[0].get() == NULL) {
65 LOGE("Unable to set fixed function emulation color because allocation is missing");
66 rsc->setError(RS_ERROR_BAD_SHADER, "Unable to set fixed function emulation color because allocation is missing");
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070067 return;
68 }
Jason Sams442a6472010-08-04 17:50:20 -070069 mConstantColor[0] = r;
70 mConstantColor[1] = g;
71 mConstantColor[2] = b;
72 mConstantColor[3] = a;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070073 memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float));
Jason Sams442a6472010-08-04 17:50:20 -070074 mDirty = true;
75}
76
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -070077void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
Jason Samsbb51c402009-11-25 13:22:07 -080078{
79 //LOGE("sgl2 frag1 %x", glGetError());
80 if ((state->mLast.get() == this) && !mDirty) {
Jason Sams7c1f4c32010-06-22 17:22:13 -070081 return;
Jason Samsbb51c402009-11-25 13:22:07 -080082 }
83 state->mLast.set(this);
84
Jason Sams5dbfe932010-01-27 14:41:43 -080085 rsc->checkError("ProgramFragment::setupGL2 start");
Jason Sams442a6472010-08-04 17:50:20 -070086
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -070087 rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -070088 setupUserConstants(rsc, sc, true);
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -070089
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -070090 uint32_t numTexturesToBind = mTextureCount;
91 uint32_t numTexturesAvailable = rsc->getMaxFragmentTextures();
92 if(numTexturesToBind >= numTexturesAvailable) {
93 LOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
94 mTextureCount, (uint32_t)this, numTexturesAvailable);
95 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
96 numTexturesToBind = numTexturesAvailable;
97 }
98
99 for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
Jason Samsbb51c402009-11-25 13:22:07 -0800100 glActiveTexture(GL_TEXTURE0 + ct);
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700101 if (!mTextures[ct].get()) {
102 LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
103 rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
Jason Samsbb51c402009-11-25 13:22:07 -0800104 continue;
105 }
106
Jason Sams3b7d39b2009-12-14 12:57:40 -0800107 mTextures[ct]->uploadCheck(rsc);
Jason Samsbb51c402009-11-25 13:22:07 -0800108 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
Jason Sams5dbfe932010-01-27 14:41:43 -0800109 rsc->checkError("ProgramFragment::setupGL2 tex bind");
Jason Samsbb51c402009-11-25 13:22:07 -0800110 if (mSamplers[ct].get()) {
Jason Samsd081fff2010-09-16 18:18:29 -0700111 mSamplers[ct]->setupGL(rsc, mTextures[ct].get());
Jason Samsbb51c402009-11-25 13:22:07 -0800112 } else {
113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Samsd081fff2010-09-16 18:18:29 -0700115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Jason Sams5dbfe932010-01-27 14:41:43 -0800117 rsc->checkError("ProgramFragment::setupGL2 tex env");
Jason Samsbb51c402009-11-25 13:22:07 -0800118 }
119
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700120 glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Jason Sams5dbfe932010-01-27 14:41:43 -0800121 rsc->checkError("ProgramFragment::setupGL2 uniforms");
Jason Samsbb51c402009-11-25 13:22:07 -0800122 }
123
124 glActiveTexture(GL_TEXTURE0);
125 mDirty = false;
Jason Samsa09a6e12010-01-06 11:57:52 -0800126 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsbb51c402009-11-25 13:22:07 -0800127}
128
Jason Sams5dad8b42009-12-15 19:10:11 -0800129void ProgramFragment::loadShader(Context *rsc) {
130 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsbb51c402009-11-25 13:22:07 -0800131}
132
133void ProgramFragment::createShader()
134{
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800135 if (mUserShader.length() > 1) {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700136 mShader.append("precision mediump float;\n");
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700137 appendUserConstants();
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700138 char buf[256];
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800139 for (uint32_t ct=0; ct < mTextureCount; ct++) {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700140 sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct);
Jason Samsbb51c402009-11-25 13:22:07 -0800141 mShader.append(buf);
Jason Samsbb51c402009-11-25 13:22:07 -0800142 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800143 mShader.append(mUserShader);
144 } else {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700145 LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
146 rsAssert(0);
Jason Samsbb51c402009-11-25 13:22:07 -0800147 }
Jason Samsbb51c402009-11-25 13:22:07 -0800148}
Jason Samsd19f10d2009-05-22 14:03:28 -0700149
Jason Samsbb51c402009-11-25 13:22:07 -0800150void ProgramFragment::init(Context *rsc)
151{
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700152 mUniformCount = 0;
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700153 if (mUserShader.size() > 0) {
154 for (uint32_t ct=0; ct < mConstantCount; ct++) {
Alex Sakhartchouk4378f112010-09-29 09:49:13 -0700155 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, RS_SHADER_UNI);
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700156 }
157 }
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700158 mTextureUniformIndexStart = mUniformCount;
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700159 char buf[256];
160 for (uint32_t ct=0; ct < mTextureCount; ct++) {
161 sprintf(buf, "UNI_Tex%i", ct);
162 mUniformNames[mUniformCount++].setTo(buf);
163 }
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700164
165 createShader();
Jason Samsbb51c402009-11-25 13:22:07 -0800166}
Jason Samsd19f10d2009-05-22 14:03:28 -0700167
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700168void ProgramFragment::serialize(OStream *stream) const
169{
Jason Sams7c1f4c32010-06-22 17:22:13 -0700170
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700171}
172
173ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
174{
175 return NULL;
176}
177
Jason Samsd19f10d2009-05-22 14:03:28 -0700178ProgramFragmentState::ProgramFragmentState()
179{
180 mPF = NULL;
181}
182
183ProgramFragmentState::~ProgramFragmentState()
184{
185 delete mPF;
186
187}
188
Jason Samsf603d212010-05-14 15:30:29 -0700189void ProgramFragmentState::init(Context *rsc)
Jason Sams9c54bdb2009-06-17 16:52:59 -0700190{
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700191 String8 shaderString(RS_SHADER_INTERNAL);
192 shaderString.append("varying lowp vec4 varColor;\n");
193 shaderString.append("varying vec4 varTex0;\n");
194 shaderString.append("void main() {\n");
195 shaderString.append(" lowp vec4 col = UNI_Color;\n");
196 shaderString.append(" gl_FragColor = col;\n");
197 shaderString.append("}\n");
198
199 const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
200 rsc->mStateElement.elementBuilderBegin();
201 rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
202 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
203
204 Type *inputType = new Type(rsc);
205 inputType->setElement(constInput);
206 inputType->setDimX(1);
207 inputType->compute();
208
209 uint32_t tmp[4];
210 tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
211 tmp[1] = (uint32_t)inputType;
212 tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
213 tmp[3] = 0;
214
215 Allocation *constAlloc = new Allocation(rsc, inputType);
216 ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
217 shaderString.length(), tmp, 4);
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700218 pf->bindAllocation(rsc, constAlloc, 0);
219 pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f);
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700220
Jason Sams9c54bdb2009-06-17 16:52:59 -0700221 mDefault.set(pf);
222}
Jason Samsd19f10d2009-05-22 14:03:28 -0700223
Jason Sams61f08d62009-09-25 16:37:33 -0700224void ProgramFragmentState::deinit(Context *rsc)
225{
226 mDefault.clear();
227 mLast.clear();
228}
229
Jason Samsd19f10d2009-05-22 14:03:28 -0700230
231namespace android {
232namespace renderscript {
233
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700234RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, const char * shaderText,
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800235 uint32_t shaderLength, const uint32_t * params,
236 uint32_t paramLength)
237{
238 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
239 pf->incUserRef();
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700240 //LOGE("rsi_ProgramFragmentCreate %p", pf);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800241 return pf;
242}
Jason Samsd19f10d2009-05-22 14:03:28 -0700243
244}
245}
246