rsProgramFragment.cpp revision 334fd9aeacd4221fc8cd1333b2a34fb3b26b3a0d
1/* 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 20#include <GLES/gl.h> 21#include <GLES/glext.h> 22 23using 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 mEnvModes[1] = RS_TEX_ENV_MODE_DECAL; 36} 37 38ProgramFragment::~ProgramFragment() 39{ 40} 41 42void ProgramFragment::setupGL() 43{ 44 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { 45 glActiveTexture(GL_TEXTURE0 + ct); 46 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { 47 glDisable(GL_TEXTURE_2D); 48 continue; 49 } 50 51 glEnable(GL_TEXTURE_2D); 52 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); 53 54 switch(mEnvModes[ct]) { 55 case RS_TEX_ENV_MODE_REPLACE: 56 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 57 break; 58 case RS_TEX_ENV_MODE_MODULATE: 59 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 60 break; 61 case RS_TEX_ENV_MODE_DECAL: 62 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 63 break; 64 } 65 66 if (mSamplers[ct].get()) { 67 mSamplers[ct]->setupGL(); 68 } else { 69 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 70 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 71 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 72 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 73 } 74 75 // Gross hack. 76 if (ct == 2) { 77 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 78 79 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); 80 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); 81 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE); 82 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 83 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); 84 85 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); 86 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); 87 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); 88 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); 89 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); 90 } 91 } 92 93 94 glActiveTexture(GL_TEXTURE0); 95} 96 97 98void ProgramFragment::bindTexture(uint32_t slot, Allocation *a) 99{ 100 if (slot >= MAX_TEXTURE) { 101 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE"); 102 return; 103 } 104 105 //LOGE("bindtex %i %p", slot, a); 106 mTextures[slot].set(a); 107} 108 109void ProgramFragment::bindSampler(uint32_t slot, Sampler *s) 110{ 111 if (slot >= MAX_TEXTURE) { 112 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE"); 113 return; 114 } 115 116 mSamplers[slot].set(s); 117} 118 119void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim) 120{ 121 if (slot >= MAX_TEXTURE) { 122 LOGE("Attempt to setType to a slot > MAX_TEXTURE"); 123 return; 124 } 125 126 if (dim >= 4) { 127 LOGE("Attempt to setType to a dimension > 3"); 128 return; 129 } 130 131 mTextureFormats[slot].set(e); 132 mTextureDimensions[slot] = dim; 133} 134 135void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env) 136{ 137 if (slot >= MAX_TEXTURE) { 138 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); 139 return; 140 } 141 142 mEnvModes[slot] = env; 143} 144 145void ProgramFragment::setTexEnable(uint32_t slot, bool enable) 146{ 147 if (slot >= MAX_TEXTURE) { 148 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); 149 return; 150 } 151 152 uint32_t bit = 1 << slot; 153 mTextureEnableMask &= ~bit; 154 if (enable) { 155 mTextureEnableMask |= bit; 156 } 157} 158 159 160 161ProgramFragmentState::ProgramFragmentState() 162{ 163 mPF = NULL; 164} 165 166ProgramFragmentState::~ProgramFragmentState() 167{ 168 delete mPF; 169 170} 171 172void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h) 173{ 174 ProgramFragment *pf = new ProgramFragment(NULL, NULL); 175 mDefault.set(pf); 176} 177 178 179namespace android { 180namespace renderscript { 181 182void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out) 183{ 184 delete rsc->mStateFragment.mPF; 185 rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out); 186} 187 188void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a) 189{ 190 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 191 pf->bindTexture(slot, static_cast<Allocation *>(a)); 192 if (pf == rsc->getFragment()) { 193 pf->setupGL(); 194 } 195} 196 197void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s) 198{ 199 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 200 pf->bindSampler(slot, static_cast<Sampler *>(s)); 201 202 if (pf == rsc->getFragment()) { 203 pf->setupGL(); 204 } 205} 206 207void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt) 208{ 209 const Type *t = static_cast<const Type *>(vt); 210 uint32_t dim = 1; 211 if (t->getDimY()) { 212 dim ++; 213 if (t->getDimZ()) { 214 dim ++; 215 } 216 } 217 218 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim); 219} 220 221void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env) 222{ 223 rsc->mStateFragment.mPF->setEnvMode(slot, env); 224} 225 226void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable) 227{ 228 rsc->mStateFragment.mPF->setTexEnable(slot, enable); 229} 230 231RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc) 232{ 233 ProgramFragment *pf = rsc->mStateFragment.mPF; 234 pf->incRef(); 235 rsc->mStateFragment.mPF = 0; 236 return pf; 237} 238 239void rsi_ProgramFragmentDestroy(Context *rsc, RsProgramFragment vpf) 240{ 241 ProgramFragment *pf = (ProgramFragment *)vpf; 242 if (pf->getName()) { 243 rsc->removeName(pf); 244 } 245 pf->decRef(); 246} 247 248 249} 250} 251 252