diff options
Diffstat (limited to 'libs/rs/rsProgramFragment.cpp')
-rw-r--r-- | libs/rs/rsProgramFragment.cpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp new file mode 100644 index 0000000..3d316ea --- /dev/null +++ b/libs/rs/rsProgramFragment.cpp @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rsContext.h" +#include "rsProgramFragment.h" + +using namespace android; +using namespace android::renderscript; + + +ProgramFragment::ProgramFragment(Element *in, Element *out) : + Program(in, out) +{ + for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { + mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE; + mTextureDimensions[ct] = 2; + } + mTextureEnableMask = 0; +} + +ProgramFragment::~ProgramFragment() +{ +} + +void ProgramFragment::setupGL() +{ + for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { + glActiveTexture(GL_TEXTURE0 + ct); + if (!(mTextureEnableMask & (1 << ct)) || + //!mSamplers[ct].get() || + !mTextures[ct].get()) { + + glDisable(GL_TEXTURE_2D); + continue; + } + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); + + switch(mEnvModes[ct]) { + case RS_TEX_ENV_MODE_REPLACE: + glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE); + break; + case RS_TEX_ENV_MODE_MODULATE: + glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); + break; + case RS_TEX_ENV_MODE_DECAL: + glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_DECAL); + break; + } + + if (mSamplers[ct].get()) { + mSamplers[ct]->setupGL(); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + } + glActiveTexture(GL_TEXTURE0); +} + + +void ProgramFragment::bindTexture(uint32_t slot, Allocation *a) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE"); + return; + } + + mTextures[slot].set(a); +} + +void ProgramFragment::bindSampler(uint32_t slot, Sampler *s) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE"); + return; + } + + mSamplers[slot].set(s); +} + +void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to setType to a slot > MAX_TEXTURE"); + return; + } + + if (dim >= 4) { + LOGE("Attempt to setType to a dimension > 3"); + return; + } + + mTextureFormats[slot].set(e); + mTextureDimensions[slot] = dim; +} + +void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); + return; + } + + mEnvModes[slot] = env; +} + +void ProgramFragment::setTexEnable(uint32_t slot, bool enable) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); + return; + } + + uint32_t bit = 1 << slot; + mTextureEnableMask &= ~bit; + if (enable) { + mTextureEnableMask |= bit; + } +} + + + +ProgramFragmentState::ProgramFragmentState() +{ + mPF = NULL; +} + +ProgramFragmentState::~ProgramFragmentState() +{ + delete mPF; + +} + + + +namespace android { +namespace renderscript { + +void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out) +{ + delete rsc->mStateFragment.mPF; + rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out); +} + +void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a) +{ + ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); + pf->bindTexture(slot, static_cast<Allocation *>(a)); + + //LOGE("%p %p", pf, rsc->getFragment()); + if (pf == rsc->getFragment()) { + pf->setupGL(); + } +} + +void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s) +{ + ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); + pf->bindSampler(slot, static_cast<Sampler *>(s)); + + if (pf == rsc->getFragment()) { + pf->setupGL(); + } +} + +void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt) +{ + const Type *t = static_cast<const Type *>(vt); + uint32_t dim = 1; + if (t->getDimY()) { + dim ++; + if (t->getDimZ()) { + dim ++; + } + } + + rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim); +} + +void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env) +{ + rsc->mStateFragment.mPF->setEnvMode(slot, env); +} + +void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable) +{ + rsc->mStateFragment.mPF->setTexEnable(slot, enable); +} + +RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc) +{ + ProgramFragment *pf = rsc->mStateFragment.mPF; + pf->incRef(); + rsc->mStateFragment.mPF = 0; + return pf; +} + + + +} +} + |