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