blob: 4ef6835271baf5aa84fb0c8b527ba92832b1cdfc [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 Samscfb1d112009-08-05 13:57:03 -070043void ProgramFragment::setupGL(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 Samse0158412009-08-20 16:10:36 -070058 //glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
Jason Sams326e0dd2009-05-22 14:03:28 -070059 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
60
61 switch(mEnvModes[ct]) {
62 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams334fd9a2009-07-02 15:09:27 -070063 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Sams326e0dd2009-05-22 14:03:28 -070064 break;
65 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams334fd9a2009-07-02 15:09:27 -070066 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Sams326e0dd2009-05-22 14:03:28 -070067 break;
68 case RS_TEX_ENV_MODE_DECAL:
Jason Sams334fd9a2009-07-02 15:09:27 -070069 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Sams326e0dd2009-05-22 14:03:28 -070070 break;
71 }
72
Jason Sams39c8bc72009-05-28 15:37:57 -070073 if (mSamplers[ct].get()) {
74 mSamplers[ct]->setupGL();
75 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -070076 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams334fd9a2009-07-02 15:09:27 -070078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Sams6678e9b2009-05-27 14:45:32 -070079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -070080 }
Jason Sams334fd9a2009-07-02 15:09:27 -070081
82 // Gross hack.
83 if (ct == 2) {
84 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
85
86 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
87 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
88 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
89 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
90 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
91
92 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
93 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
94 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
95 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
96 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
97 }
Jason Sams326e0dd2009-05-22 14:03:28 -070098 }
99 glActiveTexture(GL_TEXTURE0);
Jason Samscfb1d112009-08-05 13:57:03 -0700100 mDirty = false;
Jason Sams326e0dd2009-05-22 14:03:28 -0700101}
102
103
104void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
105{
106 if (slot >= MAX_TEXTURE) {
107 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
108 return;
109 }
110
Jason Sams334fd9a2009-07-02 15:09:27 -0700111 //LOGE("bindtex %i %p", slot, a);
Jason Sams326e0dd2009-05-22 14:03:28 -0700112 mTextures[slot].set(a);
Jason Samscfb1d112009-08-05 13:57:03 -0700113 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700114}
115
116void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
117{
118 if (slot >= MAX_TEXTURE) {
119 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
120 return;
121 }
122
123 mSamplers[slot].set(s);
Jason Samscfb1d112009-08-05 13:57:03 -0700124 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700125}
126
127void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
128{
129 if (slot >= MAX_TEXTURE) {
130 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
131 return;
132 }
133
134 if (dim >= 4) {
135 LOGE("Attempt to setType to a dimension > 3");
136 return;
137 }
138
139 mTextureFormats[slot].set(e);
140 mTextureDimensions[slot] = dim;
141}
142
143void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
144{
145 if (slot >= MAX_TEXTURE) {
146 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
147 return;
148 }
149
150 mEnvModes[slot] = env;
151}
152
153void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
154{
155 if (slot >= MAX_TEXTURE) {
156 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
157 return;
158 }
159
160 uint32_t bit = 1 << slot;
161 mTextureEnableMask &= ~bit;
162 if (enable) {
163 mTextureEnableMask |= bit;
164 }
165}
166
167
168
169ProgramFragmentState::ProgramFragmentState()
170{
171 mPF = NULL;
172}
173
174ProgramFragmentState::~ProgramFragmentState()
175{
176 delete mPF;
177
178}
179
Jason Sams8ce125b2009-06-17 16:52:59 -0700180void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
181{
Jason Samse0158412009-08-20 16:10:36 -0700182 ProgramFragment *pf = new ProgramFragment(NULL, NULL, false);
Jason Sams8ce125b2009-06-17 16:52:59 -0700183 mDefault.set(pf);
184}
Jason Sams326e0dd2009-05-22 14:03:28 -0700185
186
187namespace android {
188namespace renderscript {
189
Jason Samse0158412009-08-20 16:10:36 -0700190void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
Jason Sams326e0dd2009-05-22 14:03:28 -0700191{
192 delete rsc->mStateFragment.mPF;
Jason Samse0158412009-08-20 16:10:36 -0700193 rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out, pointSpriteEnable);
Jason Sams326e0dd2009-05-22 14:03:28 -0700194}
195
196void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
197{
198 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
199 pf->bindTexture(slot, static_cast<Allocation *>(a));
Jason Sams326e0dd2009-05-22 14:03:28 -0700200}
201
202void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
203{
204 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
205 pf->bindSampler(slot, static_cast<Sampler *>(s));
Jason Sams326e0dd2009-05-22 14:03:28 -0700206}
207
Jason Samse0158412009-08-20 16:10:36 -0700208void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt)
Jason Sams326e0dd2009-05-22 14:03:28 -0700209{
210 const Type *t = static_cast<const Type *>(vt);
Jason Samse0158412009-08-20 16:10:36 -0700211 if (t) {
212 uint32_t dim = 1;
213 if (t->getDimY()) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700214 dim ++;
Jason Samse0158412009-08-20 16:10:36 -0700215 if (t->getDimZ()) {
216 dim ++;
217 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700218 }
Jason Samse0158412009-08-20 16:10:36 -0700219 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
Jason Sams326e0dd2009-05-22 14:03:28 -0700220 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700221 rsc->mStateFragment.mPF->setEnvMode(slot, env);
Jason Sams326e0dd2009-05-22 14:03:28 -0700222 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
223}
224
225RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
226{
227 ProgramFragment *pf = rsc->mStateFragment.mPF;
228 pf->incRef();
229 rsc->mStateFragment.mPF = 0;
230 return pf;
231}
232
Jason Sams326e0dd2009-05-22 14:03:28 -0700233
234}
235}
236