blob: 708a0e0f5957a68571bd4f85694647903607ab49 [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 Samse514b452009-09-25 14:51:22 -070027ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
28 Program(rsc, in, out)
Jason Sams326e0dd2009-05-22 14:03:28 -070029{
Jason Samsf2649a92009-09-25 16:37:33 -070030 mAllocFile = __FILE__;
31 mAllocLine = __LINE__;
Jason Sams326e0dd2009-05-22 14:03:28 -070032 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
33 mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
34 mTextureDimensions[ct] = 2;
35 }
36 mTextureEnableMask = 0;
Jason Samse0158412009-08-20 16:10:36 -070037 mPointSpriteEnable = pointSpriteEnable;
Jason Sams334fd9a2009-07-02 15:09:27 -070038 mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
Jason Sams326e0dd2009-05-22 14:03:28 -070039}
40
41ProgramFragment::~ProgramFragment()
42{
43}
44
Jason Samsafcb25c2009-08-25 11:34:49 -070045void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Sams326e0dd2009-05-22 14:03:28 -070046{
Jason Samscfb1d112009-08-05 13:57:03 -070047 if ((state->mLast.get() == this) && !mDirty) {
48 return;
49 }
50 state->mLast.set(this);
51
Jason Sams326e0dd2009-05-22 14:03:28 -070052 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
53 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams334fd9a2009-07-02 15:09:27 -070054 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Sams326e0dd2009-05-22 14:03:28 -070055 glDisable(GL_TEXTURE_2D);
56 continue;
57 }
58
59 glEnable(GL_TEXTURE_2D);
Jason Samsafcb25c2009-08-25 11:34:49 -070060 if (rsc->checkVersion1_1()) {
Romain Guye62cc902009-09-04 17:55:41 -070061 if (mPointSpriteEnable) {
62 glEnable(GL_POINT_SPRITE_OES);
63 } else {
64 glDisable(GL_POINT_SPRITE_OES);
65 }
Jason Samsafcb25c2009-08-25 11:34:49 -070066 glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
67 }
Jason Sams326e0dd2009-05-22 14:03:28 -070068 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
69
70 switch(mEnvModes[ct]) {
71 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams334fd9a2009-07-02 15:09:27 -070072 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Sams326e0dd2009-05-22 14:03:28 -070073 break;
74 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams334fd9a2009-07-02 15:09:27 -070075 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Sams326e0dd2009-05-22 14:03:28 -070076 break;
77 case RS_TEX_ENV_MODE_DECAL:
Jason Sams334fd9a2009-07-02 15:09:27 -070078 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Sams326e0dd2009-05-22 14:03:28 -070079 break;
80 }
81
Jason Sams39c8bc72009-05-28 15:37:57 -070082 if (mSamplers[ct].get()) {
83 mSamplers[ct]->setupGL();
84 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -070085 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
86 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams334fd9a2009-07-02 15:09:27 -070087 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Sams6678e9b2009-05-27 14:45:32 -070088 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -070089 }
Jason Sams334fd9a2009-07-02 15:09:27 -070090
91 // Gross hack.
92 if (ct == 2) {
93 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
94
95 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
96 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
97 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
98 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
99 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
100
101 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
102 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
103 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
104 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
105 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
106 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700107 }
108 glActiveTexture(GL_TEXTURE0);
Jason Samscfb1d112009-08-05 13:57:03 -0700109 mDirty = false;
Jason Sams326e0dd2009-05-22 14:03:28 -0700110}
111
112
113void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
114{
115 if (slot >= MAX_TEXTURE) {
116 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
117 return;
118 }
119
Jason Sams334fd9a2009-07-02 15:09:27 -0700120 //LOGE("bindtex %i %p", slot, a);
Jason Sams326e0dd2009-05-22 14:03:28 -0700121 mTextures[slot].set(a);
Jason Samscfb1d112009-08-05 13:57:03 -0700122 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700123}
124
125void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
126{
127 if (slot >= MAX_TEXTURE) {
128 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
129 return;
130 }
131
132 mSamplers[slot].set(s);
Jason Samscfb1d112009-08-05 13:57:03 -0700133 mDirty = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700134}
135
136void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
137{
138 if (slot >= MAX_TEXTURE) {
139 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
140 return;
141 }
142
143 if (dim >= 4) {
144 LOGE("Attempt to setType to a dimension > 3");
145 return;
146 }
147
148 mTextureFormats[slot].set(e);
149 mTextureDimensions[slot] = dim;
150}
151
152void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
153{
154 if (slot >= MAX_TEXTURE) {
155 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
156 return;
157 }
158
159 mEnvModes[slot] = env;
160}
161
162void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
163{
164 if (slot >= MAX_TEXTURE) {
165 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
166 return;
167 }
168
169 uint32_t bit = 1 << slot;
170 mTextureEnableMask &= ~bit;
171 if (enable) {
172 mTextureEnableMask |= bit;
173 }
174}
175
176
177
178ProgramFragmentState::ProgramFragmentState()
179{
180 mPF = NULL;
181}
182
183ProgramFragmentState::~ProgramFragmentState()
184{
185 delete mPF;
186
187}
188
Jason Sams8ce125b2009-06-17 16:52:59 -0700189void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
190{
Jason Samse514b452009-09-25 14:51:22 -0700191 ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false);
Jason Sams8ce125b2009-06-17 16:52:59 -0700192 mDefault.set(pf);
193}
Jason Sams326e0dd2009-05-22 14:03:28 -0700194
Jason Samsf2649a92009-09-25 16:37:33 -0700195void ProgramFragmentState::deinit(Context *rsc)
196{
197 mDefault.clear();
198 mLast.clear();
199}
200
Jason Sams326e0dd2009-05-22 14:03:28 -0700201
202namespace android {
203namespace renderscript {
204
Jason Samse0158412009-08-20 16:10:36 -0700205void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
Jason Sams326e0dd2009-05-22 14:03:28 -0700206{
207 delete rsc->mStateFragment.mPF;
Jason Samse514b452009-09-25 14:51:22 -0700208 rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable);
Jason Sams326e0dd2009-05-22 14:03:28 -0700209}
210
211void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
212{
213 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
214 pf->bindTexture(slot, static_cast<Allocation *>(a));
Jason Sams326e0dd2009-05-22 14:03:28 -0700215}
216
217void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
218{
219 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
220 pf->bindSampler(slot, static_cast<Sampler *>(s));
Jason Sams326e0dd2009-05-22 14:03:28 -0700221}
222
Jason Samse0158412009-08-20 16:10:36 -0700223void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt)
Jason Sams326e0dd2009-05-22 14:03:28 -0700224{
225 const Type *t = static_cast<const Type *>(vt);
Jason Samse0158412009-08-20 16:10:36 -0700226 if (t) {
227 uint32_t dim = 1;
228 if (t->getDimY()) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700229 dim ++;
Jason Samse0158412009-08-20 16:10:36 -0700230 if (t->getDimZ()) {
231 dim ++;
232 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700233 }
Jason Samse0158412009-08-20 16:10:36 -0700234 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
Jason Sams326e0dd2009-05-22 14:03:28 -0700235 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700236 rsc->mStateFragment.mPF->setEnvMode(slot, env);
Jason Sams326e0dd2009-05-22 14:03:28 -0700237 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
238}
239
240RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
241{
242 ProgramFragment *pf = rsc->mStateFragment.mPF;
Jason Sams9397e302009-08-27 20:23:34 -0700243 pf->incUserRef();
Jason Sams326e0dd2009-05-22 14:03:28 -0700244 rsc->mStateFragment.mPF = 0;
245 return pf;
246}
247
Jason Sams326e0dd2009-05-22 14:03:28 -0700248
249}
250}
251