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