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