blob: 628f93ec8d6dfdeb197a4a0a93c7ec9b1ba4db4f [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
42void ProgramFragment::setupGL()
43{
44 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
45 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams334fd9a2009-07-02 15:09:27 -070046 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Sams326e0dd2009-05-22 14:03:28 -070047 glDisable(GL_TEXTURE_2D);
48 continue;
49 }
50
51 glEnable(GL_TEXTURE_2D);
52 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
53
54 switch(mEnvModes[ct]) {
55 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams334fd9a2009-07-02 15:09:27 -070056 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Sams326e0dd2009-05-22 14:03:28 -070057 break;
58 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams334fd9a2009-07-02 15:09:27 -070059 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Sams326e0dd2009-05-22 14:03:28 -070060 break;
61 case RS_TEX_ENV_MODE_DECAL:
Jason Sams334fd9a2009-07-02 15:09:27 -070062 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Sams326e0dd2009-05-22 14:03:28 -070063 break;
64 }
65
Jason Sams39c8bc72009-05-28 15:37:57 -070066 if (mSamplers[ct].get()) {
67 mSamplers[ct]->setupGL();
68 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -070069 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
70 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams334fd9a2009-07-02 15:09:27 -070071 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Sams6678e9b2009-05-27 14:45:32 -070072 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -070073 }
Jason Sams334fd9a2009-07-02 15:09:27 -070074
75 // Gross hack.
76 if (ct == 2) {
77 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
78
79 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
80 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
81 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
82 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
83 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
84
85 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
86 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
87 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
88 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
89 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
90 }
Jason Sams326e0dd2009-05-22 14:03:28 -070091 }
Jason Sams334fd9a2009-07-02 15:09:27 -070092
93
Jason Sams326e0dd2009-05-22 14:03:28 -070094 glActiveTexture(GL_TEXTURE0);
95}
96
97
98void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
99{
100 if (slot >= MAX_TEXTURE) {
101 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
102 return;
103 }
104
Jason Sams334fd9a2009-07-02 15:09:27 -0700105 //LOGE("bindtex %i %p", slot, a);
Jason Sams326e0dd2009-05-22 14:03:28 -0700106 mTextures[slot].set(a);
107}
108
109void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
110{
111 if (slot >= MAX_TEXTURE) {
112 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
113 return;
114 }
115
116 mSamplers[slot].set(s);
117}
118
119void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
120{
121 if (slot >= MAX_TEXTURE) {
122 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
123 return;
124 }
125
126 if (dim >= 4) {
127 LOGE("Attempt to setType to a dimension > 3");
128 return;
129 }
130
131 mTextureFormats[slot].set(e);
132 mTextureDimensions[slot] = dim;
133}
134
135void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
136{
137 if (slot >= MAX_TEXTURE) {
138 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
139 return;
140 }
141
142 mEnvModes[slot] = env;
143}
144
145void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
146{
147 if (slot >= MAX_TEXTURE) {
148 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
149 return;
150 }
151
152 uint32_t bit = 1 << slot;
153 mTextureEnableMask &= ~bit;
154 if (enable) {
155 mTextureEnableMask |= bit;
156 }
157}
158
159
160
161ProgramFragmentState::ProgramFragmentState()
162{
163 mPF = NULL;
164}
165
166ProgramFragmentState::~ProgramFragmentState()
167{
168 delete mPF;
169
170}
171
Jason Sams8ce125b2009-06-17 16:52:59 -0700172void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
173{
174 ProgramFragment *pf = new ProgramFragment(NULL, NULL);
175 mDefault.set(pf);
176}
Jason Sams326e0dd2009-05-22 14:03:28 -0700177
178
179namespace android {
180namespace renderscript {
181
182void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out)
183{
184 delete rsc->mStateFragment.mPF;
185 rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out);
186}
187
188void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
189{
190 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
191 pf->bindTexture(slot, static_cast<Allocation *>(a));
Jason Sams326e0dd2009-05-22 14:03:28 -0700192 if (pf == rsc->getFragment()) {
193 pf->setupGL();
194 }
195}
196
197void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
198{
199 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
200 pf->bindSampler(slot, static_cast<Sampler *>(s));
201
202 if (pf == rsc->getFragment()) {
203 pf->setupGL();
204 }
205}
206
207void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt)
208{
209 const Type *t = static_cast<const Type *>(vt);
210 uint32_t dim = 1;
211 if (t->getDimY()) {
212 dim ++;
213 if (t->getDimZ()) {
214 dim ++;
215 }
216 }
217
218 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
219}
220
221void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env)
222{
223 rsc->mStateFragment.mPF->setEnvMode(slot, env);
224}
225
226void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable)
227{
228 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
229}
230
231RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
232{
233 ProgramFragment *pf = rsc->mStateFragment.mPF;
234 pf->incRef();
235 rsc->mStateFragment.mPF = 0;
236 return pf;
237}
238
Jason Samsa0a1b6f2009-06-10 15:04:38 -0700239void rsi_ProgramFragmentDestroy(Context *rsc, RsProgramFragment vpf)
240{
241 ProgramFragment *pf = (ProgramFragment *)vpf;
242 if (pf->getName()) {
243 rsc->removeName(pf);
244 }
245 pf->decRef();
246}
Jason Sams326e0dd2009-05-22 14:03:28 -0700247
248
249}
250}
251