blob: 5f2dfae6b2c9f2d223766616bac8712625217b94 [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{
Jason Sams61f08d62009-09-25 16:37:33 -070030 mAllocFile = __FILE__;
31 mAllocLine = __LINE__;
Jason Samsd19f10d2009-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 Sams25ffcdc2009-08-20 16:10:36 -070037 mPointSpriteEnable = pointSpriteEnable;
Jason Sams4244afa2009-07-02 15:09:27 -070038 mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
Jason Samsd19f10d2009-05-22 14:03:28 -070039}
40
41ProgramFragment::~ProgramFragment()
42{
43}
44
Jason Samsb13ada52009-08-25 11:34:49 -070045void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Samsd19f10d2009-05-22 14:03:28 -070046{
Jason Sams9bee51c2009-08-05 13:57:03 -070047 if ((state->mLast.get() == this) && !mDirty) {
48 return;
49 }
50 state->mLast.set(this);
51
Jason Samsd19f10d2009-05-22 14:03:28 -070052 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
53 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams4244afa2009-07-02 15:09:27 -070054 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsd19f10d2009-05-22 14:03:28 -070055 glDisable(GL_TEXTURE_2D);
56 continue;
57 }
58
59 glEnable(GL_TEXTURE_2D);
Jason Samsb13ada52009-08-25 11:34:49 -070060 if (rsc->checkVersion1_1()) {
Romain Guy2d496bf2009-09-04 17:55:41 -070061 if (mPointSpriteEnable) {
62 glEnable(GL_POINT_SPRITE_OES);
63 } else {
64 glDisable(GL_POINT_SPRITE_OES);
65 }
Jason Samsb13ada52009-08-25 11:34:49 -070066 glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
67 }
Jason Samsc73ec392009-12-03 15:43:18 -080068
69 rsAssert(mTextures[ct]->getTextureID() != 0);
70 if (mTextures[ct]->getTextureID() == 0) {
71 // This is a hack for eclair to try to fix the white squares bug.
72 Allocation *a = (Allocation *)mTextures[ct].get();
73 a->uploadToTexture((Context *)rsc, 0);
74 if (mTextures[ct]->getTextureID() == 0) {
75 // At this point we are screwed. Crash to restart the app.
76 rsc->dumpDebug();
77 LOGE("Multiple failures during texture upload. Driver appears wedged.");
78 ((char *)0)[0] = 0;
79 }
80
81 }
Jason Samsd19f10d2009-05-22 14:03:28 -070082 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
83
84 switch(mEnvModes[ct]) {
85 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams4244afa2009-07-02 15:09:27 -070086 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Samsd19f10d2009-05-22 14:03:28 -070087 break;
88 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams4244afa2009-07-02 15:09:27 -070089 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Samsd19f10d2009-05-22 14:03:28 -070090 break;
91 case RS_TEX_ENV_MODE_DECAL:
Jason Sams4244afa2009-07-02 15:09:27 -070092 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Samsd19f10d2009-05-22 14:03:28 -070093 break;
94 }
95
Jason Sams02fb2cb2009-05-28 15:37:57 -070096 if (mSamplers[ct].get()) {
97 mSamplers[ct]->setupGL();
98 } else {
Jason Samsfe08d992009-05-27 14:45:32 -070099 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams4244afa2009-07-02 15:09:27 -0700101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Samsfe08d992009-05-27 14:45:32 -0700102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams02fb2cb2009-05-28 15:37:57 -0700103 }
Jason Sams4244afa2009-07-02 15:09:27 -0700104
105 // Gross hack.
106 if (ct == 2) {
107 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
108
109 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
110 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
111 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
112 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
113 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
114
115 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
116 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
117 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
118 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
119 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
120 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700121 }
122 glActiveTexture(GL_TEXTURE0);
Jason Sams9bee51c2009-08-05 13:57:03 -0700123 mDirty = false;
Jason Samsd19f10d2009-05-22 14:03:28 -0700124}
125
126
127void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
128{
129 if (slot >= MAX_TEXTURE) {
130 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
131 return;
132 }
133
Jason Sams4244afa2009-07-02 15:09:27 -0700134 //LOGE("bindtex %i %p", slot, a);
Jason Samsd19f10d2009-05-22 14:03:28 -0700135 mTextures[slot].set(a);
Jason Sams9bee51c2009-08-05 13:57:03 -0700136 mDirty = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700137}
138
139void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
140{
141 if (slot >= MAX_TEXTURE) {
142 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
143 return;
144 }
145
146 mSamplers[slot].set(s);
Jason Sams9bee51c2009-08-05 13:57:03 -0700147 mDirty = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700148}
149
150void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
151{
152 if (slot >= MAX_TEXTURE) {
153 LOGE("Attempt to setType to a slot > MAX_TEXTURE");
154 return;
155 }
156
157 if (dim >= 4) {
158 LOGE("Attempt to setType to a dimension > 3");
159 return;
160 }
161
162 mTextureFormats[slot].set(e);
163 mTextureDimensions[slot] = dim;
164}
165
166void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
167{
168 if (slot >= MAX_TEXTURE) {
169 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
170 return;
171 }
172
173 mEnvModes[slot] = env;
174}
175
176void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
177{
178 if (slot >= MAX_TEXTURE) {
179 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
180 return;
181 }
182
183 uint32_t bit = 1 << slot;
184 mTextureEnableMask &= ~bit;
185 if (enable) {
186 mTextureEnableMask |= bit;
187 }
188}
189
190
191
192ProgramFragmentState::ProgramFragmentState()
193{
194 mPF = NULL;
195}
196
197ProgramFragmentState::~ProgramFragmentState()
198{
199 delete mPF;
200
201}
202
Jason Sams9c54bdb2009-06-17 16:52:59 -0700203void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
204{
Jason Samsa9e7a052009-09-25 14:51:22 -0700205 ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false);
Jason Sams9c54bdb2009-06-17 16:52:59 -0700206 mDefault.set(pf);
207}
Jason Samsd19f10d2009-05-22 14:03:28 -0700208
Jason Sams61f08d62009-09-25 16:37:33 -0700209void ProgramFragmentState::deinit(Context *rsc)
210{
211 mDefault.clear();
212 mLast.clear();
213}
214
Jason Samsd19f10d2009-05-22 14:03:28 -0700215
216namespace android {
217namespace renderscript {
218
Jason Sams25ffcdc2009-08-20 16:10:36 -0700219void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
Jason Samsd19f10d2009-05-22 14:03:28 -0700220{
221 delete rsc->mStateFragment.mPF;
Jason Samsa9e7a052009-09-25 14:51:22 -0700222 rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable);
Jason Samsd19f10d2009-05-22 14:03:28 -0700223}
224
225void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
226{
227 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
228 pf->bindTexture(slot, static_cast<Allocation *>(a));
Jason Samsd19f10d2009-05-22 14:03:28 -0700229}
230
231void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
232{
233 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
234 pf->bindSampler(slot, static_cast<Sampler *>(s));
Jason Samsd19f10d2009-05-22 14:03:28 -0700235}
236
Jason Sams25ffcdc2009-08-20 16:10:36 -0700237void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt)
Jason Samsd19f10d2009-05-22 14:03:28 -0700238{
239 const Type *t = static_cast<const Type *>(vt);
Jason Sams25ffcdc2009-08-20 16:10:36 -0700240 if (t) {
241 uint32_t dim = 1;
242 if (t->getDimY()) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700243 dim ++;
Jason Sams25ffcdc2009-08-20 16:10:36 -0700244 if (t->getDimZ()) {
245 dim ++;
246 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700247 }
Jason Sams25ffcdc2009-08-20 16:10:36 -0700248 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
Jason Samsd19f10d2009-05-22 14:03:28 -0700249 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700250 rsc->mStateFragment.mPF->setEnvMode(slot, env);
Jason Samsd19f10d2009-05-22 14:03:28 -0700251 rsc->mStateFragment.mPF->setTexEnable(slot, enable);
252}
253
254RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
255{
256 ProgramFragment *pf = rsc->mStateFragment.mPF;
Jason Sams07ae4062009-08-27 20:23:34 -0700257 pf->incUserRef();
Jason Samsd19f10d2009-05-22 14:03:28 -0700258 rsc->mStateFragment.mPF = 0;
259 return pf;
260}
261
Jason Samsd19f10d2009-05-22 14:03:28 -0700262
263}
264}
265