blob: 5f685ff573551dc0a035037f71c5b7988c087c22 [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
17#include "rsContext.h"
18#include "rsProgramFragment.h"
19
Jason Sams4b962e52009-06-22 17:15:15 -070020#include <GLES/gl.h>
21#include <GLES/glext.h>
22
Jason Samsd19f10d2009-05-22 14:03:28 -070023using namespace android;
24using namespace android::renderscript;
25
26
Jason Samsa9e7a052009-09-25 14:51:22 -070027ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
28 Program(rsc, in, out)
Jason Samsd19f10d2009-05-22 14:03:28 -070029{
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 Sams25ffcdc2009-08-20 16:10:36 -070035 mPointSpriteEnable = pointSpriteEnable;
Jason Sams4244afa2009-07-02 15:09:27 -070036 mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
Jason Samsd19f10d2009-05-22 14:03:28 -070037}
38
39ProgramFragment::~ProgramFragment()
40{
41}
42
Jason Samsb13ada52009-08-25 11:34:49 -070043void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Samsd19f10d2009-05-22 14:03:28 -070044{
Jason Sams9bee51c2009-08-05 13:57:03 -070045 if ((state->mLast.get() == this) && !mDirty) {
46 return;
47 }
48 state->mLast.set(this);
49
Jason Samsd19f10d2009-05-22 14:03:28 -070050 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
51 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams4244afa2009-07-02 15:09:27 -070052 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsd19f10d2009-05-22 14:03:28 -070053 glDisable(GL_TEXTURE_2D);
54 continue;
55 }
56
57 glEnable(GL_TEXTURE_2D);
Jason Samsb13ada52009-08-25 11:34:49 -070058 if (rsc->checkVersion1_1()) {
Romain Guy2d496bf2009-09-04 17:55:41 -070059 if (mPointSpriteEnable) {
60 glEnable(GL_POINT_SPRITE_OES);
61 } else {
62 glDisable(GL_POINT_SPRITE_OES);
63 }
Jason Samsb13ada52009-08-25 11:34:49 -070064 glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
65 }
Jason Samsd19f10d2009-05-22 14:03:28 -070066 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
67
68 switch(mEnvModes[ct]) {
69 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams4244afa2009-07-02 15:09:27 -070070 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Samsd19f10d2009-05-22 14:03:28 -070071 break;
72 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams4244afa2009-07-02 15:09:27 -070073 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Samsd19f10d2009-05-22 14:03:28 -070074 break;
75 case RS_TEX_ENV_MODE_DECAL:
Jason Sams4244afa2009-07-02 15:09:27 -070076 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Samsd19f10d2009-05-22 14:03:28 -070077 break;
78 }
79
Jason Sams02fb2cb2009-05-28 15:37:57 -070080 if (mSamplers[ct].get()) {
81 mSamplers[ct]->setupGL();
82 } else {
Jason Samsfe08d992009-05-27 14:45:32 -070083 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
84 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams4244afa2009-07-02 15:09:27 -070085 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Samsfe08d992009-05-27 14:45:32 -070086 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams02fb2cb2009-05-28 15:37:57 -070087 }
Jason Sams4244afa2009-07-02 15:09:27 -070088
89 // Gross hack.
90 if (ct == 2) {
91 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
92
93 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
94 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
95 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
96 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
97 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
98
99 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
100 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
101 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
102 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
103 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
104 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700105 }
106 glActiveTexture(GL_TEXTURE0);
Jason Sams9bee51c2009-08-05 13:57:03 -0700107 mDirty = false;
Jason Samsd19f10d2009-05-22 14:03:28 -0700108}
109
110
111void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
112{
113 if (slot >= MAX_TEXTURE) {
114 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
115 return;
116 }
117
Jason Sams4244afa2009-07-02 15:09:27 -0700118 //LOGE("bindtex %i %p", slot, a);
Jason Samsd19f10d2009-05-22 14:03:28 -0700119 mTextures[slot].set(a);
Jason Sams9bee51c2009-08-05 13:57:03 -0700120 mDirty = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700121}
122
123void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
124{
125 if (slot >= MAX_TEXTURE) {
126 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
127 return;
128 }
129
130 mSamplers[slot].set(s);
Jason Sams9bee51c2009-08-05 13:57:03 -0700131 mDirty = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700132}
133
134void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
135{
136 if (slot >= MAX_TEXTURE) {
137 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
138 return;
139 }
140
141 if (dim >= 4) {
142 LOGE("Attempt to setType to a dimension > 3");
143 return;
144 }
145
146 mTextureFormats[slot].set(e);
147 mTextureDimensions[slot] = dim;
148}
149
150void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
151{
152 if (slot >= MAX_TEXTURE) {
153 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
154 return;
155 }
156
157 mEnvModes[slot] = env;
158}
159
160void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
161{
162 if (slot >= MAX_TEXTURE) {
163 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
164 return;
165 }
166
167 uint32_t bit = 1 << slot;
168 mTextureEnableMask &= ~bit;
169 if (enable) {
170 mTextureEnableMask |= bit;
171 }
172}
173
174
175
176ProgramFragmentState::ProgramFragmentState()
177{
178 mPF = NULL;
179}
180
181ProgramFragmentState::~ProgramFragmentState()
182{
183 delete mPF;
184
185}
186
Jason Sams9c54bdb2009-06-17 16:52:59 -0700187void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
188{
Jason Samsa9e7a052009-09-25 14:51:22 -0700189 ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false);
Jason Sams9c54bdb2009-06-17 16:52:59 -0700190 mDefault.set(pf);
191}
Jason Samsd19f10d2009-05-22 14:03:28 -0700192
193
194namespace android {
195namespace renderscript {
196
Jason Sams25ffcdc2009-08-20 16:10:36 -0700197void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
Jason Samsd19f10d2009-05-22 14:03:28 -0700198{
199 delete rsc->mStateFragment.mPF;
Jason Samsa9e7a052009-09-25 14:51:22 -0700200 rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable);
Jason Samsd19f10d2009-05-22 14:03:28 -0700201}
202
203void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
204{
205 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
206 pf->bindTexture(slot, static_cast<Allocation *>(a));
Jason Samsd19f10d2009-05-22 14:03:28 -0700207}
208
209void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
210{
211 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
212 pf->bindSampler(slot, static_cast<Sampler *>(s));
Jason Samsd19f10d2009-05-22 14:03:28 -0700213}
214
Jason Sams25ffcdc2009-08-20 16:10:36 -0700215void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt)
Jason Samsd19f10d2009-05-22 14:03:28 -0700216{
217 const Type *t = static_cast<const Type *>(vt);
Jason Sams25ffcdc2009-08-20 16:10:36 -0700218 if (t) {
219 uint32_t dim = 1;
220 if (t->getDimY()) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700221 dim ++;
Jason Sams25ffcdc2009-08-20 16:10:36 -0700222 if (t->getDimZ()) {
223 dim ++;
224 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700225 }
Jason Sams25ffcdc2009-08-20 16:10:36 -0700226 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
Jason Samsd19f10d2009-05-22 14:03:28 -0700227 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700228 rsc->mStateFragment.mPF->setEnvMode(slot, env);
Jason Samsd19f10d2009-05-22 14:03:28 -0700229 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
230}
231
232RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
233{
234 ProgramFragment *pf = rsc->mStateFragment.mPF;
Jason Sams07ae4062009-08-27 20:23:34 -0700235 pf->incUserRef();
Jason Samsd19f10d2009-05-22 14:03:28 -0700236 rsc->mStateFragment.mPF = 0;
237 return pf;
238}
239
Jason Samsd19f10d2009-05-22 14:03:28 -0700240
241}
242}
243