blob: f9eb1b269b8b51ad3818b3142503cc1f78e12522 [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;
35}
36
37ProgramFragment::~ProgramFragment()
38{
39}
40
41void ProgramFragment::setupGL()
42{
43 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
44 glActiveTexture(GL_TEXTURE0 + ct);
45 if (!(mTextureEnableMask & (1 << ct)) ||
Jason Sams6678e9b2009-05-27 14:45:32 -070046 //!mSamplers[ct].get() ||
Jason Sams326e0dd2009-05-22 14:03:28 -070047 !mTextures[ct].get()) {
48
49 glDisable(GL_TEXTURE_2D);
50 continue;
51 }
52
53 glEnable(GL_TEXTURE_2D);
54 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
55
56 switch(mEnvModes[ct]) {
57 case RS_TEX_ENV_MODE_REPLACE:
58 glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
59 break;
60 case RS_TEX_ENV_MODE_MODULATE:
61 glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
62 break;
63 case RS_TEX_ENV_MODE_DECAL:
64 glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_DECAL);
65 break;
66 }
67
Jason Sams39c8bc72009-05-28 15:37:57 -070068 if (mSamplers[ct].get()) {
69 mSamplers[ct]->setupGL();
70 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -070071 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
72 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
73 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -070075 }
Jason Sams326e0dd2009-05-22 14:03:28 -070076 }
77 glActiveTexture(GL_TEXTURE0);
78}
79
80
81void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
82{
83 if (slot >= MAX_TEXTURE) {
84 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
85 return;
86 }
87
88 mTextures[slot].set(a);
89}
90
91void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
92{
93 if (slot >= MAX_TEXTURE) {
94 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
95 return;
96 }
97
98 mSamplers[slot].set(s);
99}
100
101void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
102{
103 if (slot >= MAX_TEXTURE) {
104 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
105 return;
106 }
107
108 if (dim >= 4) {
109 LOGE("Attempt to setType to a dimension > 3");
110 return;
111 }
112
113 mTextureFormats[slot].set(e);
114 mTextureDimensions[slot] = dim;
115}
116
117void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
118{
119 if (slot >= MAX_TEXTURE) {
120 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
121 return;
122 }
123
124 mEnvModes[slot] = env;
125}
126
127void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
128{
129 if (slot >= MAX_TEXTURE) {
130 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
131 return;
132 }
133
134 uint32_t bit = 1 << slot;
135 mTextureEnableMask &= ~bit;
136 if (enable) {
137 mTextureEnableMask |= bit;
138 }
139}
140
141
142
143ProgramFragmentState::ProgramFragmentState()
144{
145 mPF = NULL;
146}
147
148ProgramFragmentState::~ProgramFragmentState()
149{
150 delete mPF;
151
152}
153
Jason Sams8ce125b2009-06-17 16:52:59 -0700154void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
155{
156 ProgramFragment *pf = new ProgramFragment(NULL, NULL);
157 mDefault.set(pf);
158}
Jason Sams326e0dd2009-05-22 14:03:28 -0700159
160
161namespace android {
162namespace renderscript {
163
164void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out)
165{
166 delete rsc->mStateFragment.mPF;
167 rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out);
168}
169
170void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
171{
172 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
173 pf->bindTexture(slot, static_cast<Allocation *>(a));
174
175 //LOGE("%p %p", pf, rsc->getFragment());
176 if (pf == rsc->getFragment()) {
177 pf->setupGL();
178 }
179}
180
181void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
182{
183 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
184 pf->bindSampler(slot, static_cast<Sampler *>(s));
185
186 if (pf == rsc->getFragment()) {
187 pf->setupGL();
188 }
189}
190
191void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt)
192{
193 const Type *t = static_cast<const Type *>(vt);
194 uint32_t dim = 1;
195 if (t->getDimY()) {
196 dim ++;
197 if (t->getDimZ()) {
198 dim ++;
199 }
200 }
201
202 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
203}
204
205void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env)
206{
207 rsc->mStateFragment.mPF->setEnvMode(slot, env);
208}
209
210void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable)
211{
212 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
213}
214
215RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
216{
217 ProgramFragment *pf = rsc->mStateFragment.mPF;
218 pf->incRef();
219 rsc->mStateFragment.mPF = 0;
220 return pf;
221}
222
Jason Samsa0a1b6f2009-06-10 15:04:38 -0700223void rsi_ProgramFragmentDestroy(Context *rsc, RsProgramFragment vpf)
224{
225 ProgramFragment *pf = (ProgramFragment *)vpf;
226 if (pf->getName()) {
227 rsc->removeName(pf);
228 }
229 pf->decRef();
230}
Jason Sams326e0dd2009-05-22 14:03:28 -0700231
232
233}
234}
235