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