blob: ea507dc2fa421fc087212e23ab723dfd67c15931 [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
27ProgramFragment::ProgramFragment(Element *in, Element *out) :
28 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 Sams334fd9a2009-07-02 15:09:27 -070035 mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
Jason Sams326e0dd2009-05-22 14:03:28 -070036}
37
38ProgramFragment::~ProgramFragment()
39{
40}
41
Jason Samscfb1d112009-08-05 13:57:03 -070042void ProgramFragment::setupGL(ProgramFragmentState *state)
Jason Sams326e0dd2009-05-22 14:03:28 -070043{
Jason Samscfb1d112009-08-05 13:57:03 -070044 if ((state->mLast.get() == this) && !mDirty) {
45 return;
46 }
47 state->mLast.set(this);
48
Jason Sams326e0dd2009-05-22 14:03:28 -070049 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
50 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams334fd9a2009-07-02 15:09:27 -070051 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Sams326e0dd2009-05-22 14:03:28 -070052 glDisable(GL_TEXTURE_2D);
53 continue;
54 }
55
56 glEnable(GL_TEXTURE_2D);
57 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
58
59 switch(mEnvModes[ct]) {
60 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams334fd9a2009-07-02 15:09:27 -070061 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Sams326e0dd2009-05-22 14:03:28 -070062 break;
63 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams334fd9a2009-07-02 15:09:27 -070064 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Sams326e0dd2009-05-22 14:03:28 -070065 break;
66 case RS_TEX_ENV_MODE_DECAL:
Jason Sams334fd9a2009-07-02 15:09:27 -070067 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Sams326e0dd2009-05-22 14:03:28 -070068 break;
69 }
70
Jason Sams39c8bc72009-05-28 15:37:57 -070071 if (mSamplers[ct].get()) {
72 mSamplers[ct]->setupGL();
73 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -070074 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams334fd9a2009-07-02 15:09:27 -070076 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Sams6678e9b2009-05-27 14:45:32 -070077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -070078 }
Jason Sams334fd9a2009-07-02 15:09:27 -070079
80 // Gross hack.
81 if (ct == 2) {
82 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
83
84 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
85 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
86 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
87 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
88 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
89
90 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
91 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
92 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
93 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
94 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
95 }
Jason Sams326e0dd2009-05-22 14:03:28 -070096 }
Jason Sams334fd9a2009-07-02 15:09:27 -070097
Jason Sams326e0dd2009-05-22 14:03:28 -070098 glActiveTexture(GL_TEXTURE0);
Jason Samscfb1d112009-08-05 13:57:03 -070099 mDirty = false;
Jason Sams326e0dd2009-05-22 14:03:28 -0700100}
101
102
103void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
104{
105 if (slot >= MAX_TEXTURE) {
106 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
107 return;
108 }
109
Jason Sams334fd9a2009-07-02 15:09:27 -0700110 //LOGE("bindtex %i %p", slot, a);
Jason Sams326e0dd2009-05-22 14:03:28 -0700111 mTextures[slot].set(a);
Jason Samscfb1d112009-08-05 13:57:03 -0700112 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700113}
114
115void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
116{
117 if (slot >= MAX_TEXTURE) {
118 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
119 return;
120 }
121
122 mSamplers[slot].set(s);
Jason Samscfb1d112009-08-05 13:57:03 -0700123 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700124}
125
126void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
127{
128 if (slot >= MAX_TEXTURE) {
129 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
130 return;
131 }
132
133 if (dim >= 4) {
134 LOGE("Attempt to setType to a dimension > 3");
135 return;
136 }
137
138 mTextureFormats[slot].set(e);
139 mTextureDimensions[slot] = dim;
140}
141
142void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
143{
144 if (slot >= MAX_TEXTURE) {
145 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
146 return;
147 }
148
149 mEnvModes[slot] = env;
150}
151
152void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
153{
154 if (slot >= MAX_TEXTURE) {
155 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
156 return;
157 }
158
159 uint32_t bit = 1 << slot;
160 mTextureEnableMask &= ~bit;
161 if (enable) {
162 mTextureEnableMask |= bit;
163 }
164}
165
166
167
168ProgramFragmentState::ProgramFragmentState()
169{
170 mPF = NULL;
171}
172
173ProgramFragmentState::~ProgramFragmentState()
174{
175 delete mPF;
176
177}
178
Jason Sams8ce125b2009-06-17 16:52:59 -0700179void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
180{
181 ProgramFragment *pf = new ProgramFragment(NULL, NULL);
182 mDefault.set(pf);
183}
Jason Sams326e0dd2009-05-22 14:03:28 -0700184
185
186namespace android {
187namespace renderscript {
188
189void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out)
190{
191 delete rsc->mStateFragment.mPF;
192 rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out);
193}
194
195void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
196{
197 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
198 pf->bindTexture(slot, static_cast<Allocation *>(a));
Jason Sams326e0dd2009-05-22 14:03:28 -0700199 if (pf == rsc->getFragment()) {
Jason Samscfb1d112009-08-05 13:57:03 -0700200 //pf->setupGL();
Jason Sams326e0dd2009-05-22 14:03:28 -0700201 }
202}
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));
208
209 if (pf == rsc->getFragment()) {
Jason Samscfb1d112009-08-05 13:57:03 -0700210 //pf->setupGL();
Jason Sams326e0dd2009-05-22 14:03:28 -0700211 }
212}
213
214void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt)
215{
216 const Type *t = static_cast<const Type *>(vt);
217 uint32_t dim = 1;
218 if (t->getDimY()) {
219 dim ++;
220 if (t->getDimZ()) {
221 dim ++;
222 }
223 }
224
225 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
226}
227
228void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env)
229{
230 rsc->mStateFragment.mPF->setEnvMode(slot, env);
231}
232
233void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable)
234{
235 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
236}
237
238RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
239{
240 ProgramFragment *pf = rsc->mStateFragment.mPF;
241 pf->incRef();
242 rsc->mStateFragment.mPF = 0;
243 return pf;
244}
245
Jason Samsa0a1b6f2009-06-10 15:04:38 -0700246void rsi_ProgramFragmentDestroy(Context *rsc, RsProgramFragment vpf)
247{
248 ProgramFragment *pf = (ProgramFragment *)vpf;
249 if (pf->getName()) {
250 rsc->removeName(pf);
251 }
252 pf->decRef();
253}
Jason Sams326e0dd2009-05-22 14:03:28 -0700254
255
256}
257}
258