rsProgramFragment.cpp revision 326e0ddf89e8df2837752fbfd7a014814b32082c
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 mSamplers[ct]->setupGL(); 66 } 67 glActiveTexture(GL_TEXTURE0); 68} 69 70 71void ProgramFragment::bindTexture(uint32_t slot, Allocation *a) 72{ 73 if (slot >= MAX_TEXTURE) { 74 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE"); 75 return; 76 } 77 78 mTextures[slot].set(a); 79} 80 81void ProgramFragment::bindSampler(uint32_t slot, Sampler *s) 82{ 83 if (slot >= MAX_TEXTURE) { 84 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE"); 85 return; 86 } 87 88 mSamplers[slot].set(s); 89} 90 91void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim) 92{ 93 if (slot >= MAX_TEXTURE) { 94 LOGE("Attempt to setType to a slot > MAX_TEXTURE"); 95 return; 96 } 97 98 if (dim >= 4) { 99 LOGE("Attempt to setType to a dimension > 3"); 100 return; 101 } 102 103 mTextureFormats[slot].set(e); 104 mTextureDimensions[slot] = dim; 105} 106 107void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env) 108{ 109 if (slot >= MAX_TEXTURE) { 110 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); 111 return; 112 } 113 114 mEnvModes[slot] = env; 115} 116 117void ProgramFragment::setTexEnable(uint32_t slot, bool enable) 118{ 119 if (slot >= MAX_TEXTURE) { 120 LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); 121 return; 122 } 123 124 uint32_t bit = 1 << slot; 125 mTextureEnableMask &= ~bit; 126 if (enable) { 127 mTextureEnableMask |= bit; 128 } 129} 130 131 132 133ProgramFragmentState::ProgramFragmentState() 134{ 135 mPF = NULL; 136} 137 138ProgramFragmentState::~ProgramFragmentState() 139{ 140 delete mPF; 141 142} 143 144 145 146namespace android { 147namespace renderscript { 148 149void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out) 150{ 151 delete rsc->mStateFragment.mPF; 152 rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out); 153} 154 155void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a) 156{ 157 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 158 pf->bindTexture(slot, static_cast<Allocation *>(a)); 159 160 //LOGE("%p %p", pf, rsc->getFragment()); 161 if (pf == rsc->getFragment()) { 162 pf->setupGL(); 163 } 164} 165 166void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s) 167{ 168 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 169 pf->bindSampler(slot, static_cast<Sampler *>(s)); 170 171 if (pf == rsc->getFragment()) { 172 pf->setupGL(); 173 } 174} 175 176void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt) 177{ 178 const Type *t = static_cast<const Type *>(vt); 179 uint32_t dim = 1; 180 if (t->getDimY()) { 181 dim ++; 182 if (t->getDimZ()) { 183 dim ++; 184 } 185 } 186 187 rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim); 188} 189 190void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env) 191{ 192 rsc->mStateFragment.mPF->setEnvMode(slot, env); 193} 194 195void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable) 196{ 197 rsc->mStateFragment.mPF->setTexEnable(slot, enable); 198} 199 200RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc) 201{ 202 ProgramFragment *pf = rsc->mStateFragment.mPF; 203 pf->incRef(); 204 rsc->mStateFragment.mPF = 0; 205 return pf; 206} 207 208 209 210} 211} 212 213