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