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