blob: 0adce75cb430be5e90ed6f77322a05f6a3e9ba7a [file] [log] [blame]
Jason Sams326e0dd2009-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
17#include "rsContext.h"
18#include "rsProgramFragment.h"
19
Jason Sams1aa5a4e2009-06-22 17:15:15 -070020#include <GLES/gl.h>
21#include <GLES/glext.h>
22
Jason Sams326e0dd2009-05-22 14:03:28 -070023using namespace android;
24using namespace android::renderscript;
25
26
Jason Samse0158412009-08-20 16:10:36 -070027ProgramFragment::ProgramFragment(Element *in, Element *out, bool pointSpriteEnable) :
Jason Sams326e0dd2009-05-22 14:03:28 -070028 Program(in, out)
29{
30 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
31 mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
32 mTextureDimensions[ct] = 2;
33 }
34 mTextureEnableMask = 0;
Jason Samse0158412009-08-20 16:10:36 -070035 mPointSpriteEnable = pointSpriteEnable;
Jason Sams334fd9a2009-07-02 15:09:27 -070036 mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
Jason Sams326e0dd2009-05-22 14:03:28 -070037}
38
39ProgramFragment::~ProgramFragment()
40{
41}
42
Jason Samsafcb25c2009-08-25 11:34:49 -070043void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Sams326e0dd2009-05-22 14:03:28 -070044{
Jason Samscfb1d112009-08-05 13:57:03 -070045 if ((state->mLast.get() == this) && !mDirty) {
46 return;
47 }
48 state->mLast.set(this);
49
Jason Sams326e0dd2009-05-22 14:03:28 -070050 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
51 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams334fd9a2009-07-02 15:09:27 -070052 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Sams326e0dd2009-05-22 14:03:28 -070053 glDisable(GL_TEXTURE_2D);
54 continue;
55 }
56
57 glEnable(GL_TEXTURE_2D);
Jason Samsafcb25c2009-08-25 11:34:49 -070058 if (rsc->checkVersion1_1()) {
59 glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
60 }
Jason Sams326e0dd2009-05-22 14:03:28 -070061 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
62
63 switch(mEnvModes[ct]) {
64 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams334fd9a2009-07-02 15:09:27 -070065 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Sams326e0dd2009-05-22 14:03:28 -070066 break;
67 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams334fd9a2009-07-02 15:09:27 -070068 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Sams326e0dd2009-05-22 14:03:28 -070069 break;
70 case RS_TEX_ENV_MODE_DECAL:
Jason Sams334fd9a2009-07-02 15:09:27 -070071 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Sams326e0dd2009-05-22 14:03:28 -070072 break;
73 }
74
Jason Sams39c8bc72009-05-28 15:37:57 -070075 if (mSamplers[ct].get()) {
76 mSamplers[ct]->setupGL();
77 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -070078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
79 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams334fd9a2009-07-02 15:09:27 -070080 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Sams6678e9b2009-05-27 14:45:32 -070081 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -070082 }
Jason Sams334fd9a2009-07-02 15:09:27 -070083
84 // Gross hack.
85 if (ct == 2) {
86 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
87
88 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
89 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
90 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
91 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
92 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
93
94 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
95 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
96 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
97 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
98 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
99 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700100 }
101 glActiveTexture(GL_TEXTURE0);
Jason Samscfb1d112009-08-05 13:57:03 -0700102 mDirty = false;
Jason Sams326e0dd2009-05-22 14:03:28 -0700103}
104
105
106void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
107{
108 if (slot >= MAX_TEXTURE) {
109 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
110 return;
111 }
112
Jason Sams334fd9a2009-07-02 15:09:27 -0700113 //LOGE("bindtex %i %p", slot, a);
Jason Sams326e0dd2009-05-22 14:03:28 -0700114 mTextures[slot].set(a);
Jason Samscfb1d112009-08-05 13:57:03 -0700115 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700116}
117
118void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
119{
120 if (slot >= MAX_TEXTURE) {
121 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
122 return;
123 }
124
125 mSamplers[slot].set(s);
Jason Samscfb1d112009-08-05 13:57:03 -0700126 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700127}
128
129void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
130{
131 if (slot >= MAX_TEXTURE) {
132 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
133 return;
134 }
135
136 if (dim >= 4) {
137 LOGE("Attempt to setType to a dimension > 3");
138 return;
139 }
140
141 mTextureFormats[slot].set(e);
142 mTextureDimensions[slot] = dim;
143}
144
145void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
146{
147 if (slot >= MAX_TEXTURE) {
148 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
149 return;
150 }
151
152 mEnvModes[slot] = env;
153}
154
155void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
156{
157 if (slot >= MAX_TEXTURE) {
158 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
159 return;
160 }
161
162 uint32_t bit = 1 << slot;
163 mTextureEnableMask &= ~bit;
164 if (enable) {
165 mTextureEnableMask |= bit;
166 }
167}
168
169
170
171ProgramFragmentState::ProgramFragmentState()
172{
173 mPF = NULL;
174}
175
176ProgramFragmentState::~ProgramFragmentState()
177{
178 delete mPF;
179
180}
181
Jason Sams8ce125b2009-06-17 16:52:59 -0700182void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
183{
Jason Samse0158412009-08-20 16:10:36 -0700184 ProgramFragment *pf = new ProgramFragment(NULL, NULL, false);
Jason Sams8ce125b2009-06-17 16:52:59 -0700185 mDefault.set(pf);
186}
Jason Sams326e0dd2009-05-22 14:03:28 -0700187
188
189namespace android {
190namespace renderscript {
191
Jason Samse0158412009-08-20 16:10:36 -0700192void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
Jason Sams326e0dd2009-05-22 14:03:28 -0700193{
194 delete rsc->mStateFragment.mPF;
Jason Samse0158412009-08-20 16:10:36 -0700195 rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out, pointSpriteEnable);
Jason Sams326e0dd2009-05-22 14:03:28 -0700196}
197
198void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
199{
200 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
201 pf->bindTexture(slot, static_cast<Allocation *>(a));
Jason Sams326e0dd2009-05-22 14:03:28 -0700202}
203
204void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
205{
206 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
207 pf->bindSampler(slot, static_cast<Sampler *>(s));
Jason Sams326e0dd2009-05-22 14:03:28 -0700208}
209
Jason Samse0158412009-08-20 16:10:36 -0700210void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt)
Jason Sams326e0dd2009-05-22 14:03:28 -0700211{
212 const Type *t = static_cast<const Type *>(vt);
Jason Samse0158412009-08-20 16:10:36 -0700213 if (t) {
214 uint32_t dim = 1;
215 if (t->getDimY()) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700216 dim ++;
Jason Samse0158412009-08-20 16:10:36 -0700217 if (t->getDimZ()) {
218 dim ++;
219 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700220 }
Jason Samse0158412009-08-20 16:10:36 -0700221 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
Jason Sams326e0dd2009-05-22 14:03:28 -0700222 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700223 rsc->mStateFragment.mPF->setEnvMode(slot, env);
Jason Sams326e0dd2009-05-22 14:03:28 -0700224 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
225}
226
227RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
228{
229 ProgramFragment *pf = rsc->mStateFragment.mPF;
Jason Sams9397e302009-08-27 20:23:34 -0700230 pf->incUserRef();
Jason Sams326e0dd2009-05-22 14:03:28 -0700231 rsc->mStateFragment.mPF = 0;
232 return pf;
233}
234
Jason Sams326e0dd2009-05-22 14:03:28 -0700235
236}
237}
238