Sampler.java revision 099deb8fb1715e62bcb24513f8e9305ab4f7743a
1/*
2 * Copyright (C) 2012 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
17package android.support.v8.renderscript;
18
19
20import java.io.IOException;
21import java.io.InputStream;
22
23import android.content.res.Resources;
24import android.os.Bundle;
25import android.util.Log;
26
27import android.graphics.Bitmap;
28import android.graphics.BitmapFactory;
29
30/**
31 * Sampler object which defines how data is extracted from textures. Samplers
32 * are attached to Program objects (currently only ProgramFragment) when those objects
33 * need to access texture data.
34 **/
35public class Sampler extends BaseObj {
36    public enum Value {
37        NEAREST (0),
38        LINEAR (1),
39        LINEAR_MIP_LINEAR (2),
40        LINEAR_MIP_NEAREST (5),
41        WRAP (3),
42        CLAMP (4),
43        MIRRORED_REPEAT (6);
44
45        int mID;
46        Value(int id) {
47            mID = id;
48        }
49    }
50
51    Value mMin;
52    Value mMag;
53    Value mWrapS;
54    Value mWrapT;
55    Value mWrapR;
56    float mAniso;
57
58    Sampler(int id, RenderScript rs) {
59        super(id, rs);
60    }
61
62    /**
63     * @return minification setting for the sampler
64     */
65    public Value getMinification() {
66        return mMin;
67    }
68
69    /**
70     * @return magnification setting for the sampler
71     */
72    public Value getMagnification() {
73        return mMag;
74    }
75
76    /**
77     * @return S wrapping mode for the sampler
78     */
79    public Value getWrapS() {
80        return mWrapS;
81    }
82
83    /**
84     * @return T wrapping mode for the sampler
85     */
86    public Value getWrapT() {
87        return mWrapT;
88    }
89
90    /**
91     * @return anisotropy setting for the sampler
92     */
93    public float getAnisotropy() {
94        return mAniso;
95    }
96
97    /**
98     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
99     * clamp.
100     *
101     * @param rs Context to which the sampler will belong.
102     *
103     * @return Sampler
104     */
105    public static Sampler CLAMP_NEAREST(RenderScript rs) {
106        if(rs.mSampler_CLAMP_NEAREST == null) {
107            Builder b = new Builder(rs);
108            b.setMinification(Value.NEAREST);
109            b.setMagnification(Value.NEAREST);
110            b.setWrapS(Value.CLAMP);
111            b.setWrapT(Value.CLAMP);
112            rs.mSampler_CLAMP_NEAREST = b.create();
113        }
114        return rs.mSampler_CLAMP_NEAREST;
115    }
116
117    /**
118     * Retrieve a sampler with min and mag set to linear and wrap modes set to
119     * clamp.
120     *
121     * @param rs Context to which the sampler will belong.
122     *
123     * @return Sampler
124     */
125    public static Sampler CLAMP_LINEAR(RenderScript rs) {
126        if(rs.mSampler_CLAMP_LINEAR == null) {
127            Builder b = new Builder(rs);
128            b.setMinification(Value.LINEAR);
129            b.setMagnification(Value.LINEAR);
130            b.setWrapS(Value.CLAMP);
131            b.setWrapT(Value.CLAMP);
132            rs.mSampler_CLAMP_LINEAR = b.create();
133        }
134        return rs.mSampler_CLAMP_LINEAR;
135    }
136
137    /**
138     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
139     * wrap modes set to clamp.
140     *
141     * @param rs Context to which the sampler will belong.
142     *
143     * @return Sampler
144     */
145    public static Sampler CLAMP_LINEAR_MIP_LINEAR(RenderScript rs) {
146        if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) {
147            Builder b = new Builder(rs);
148            b.setMinification(Value.LINEAR_MIP_LINEAR);
149            b.setMagnification(Value.LINEAR);
150            b.setWrapS(Value.CLAMP);
151            b.setWrapT(Value.CLAMP);
152            rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
153        }
154        return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
155    }
156
157    /**
158     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
159     * wrap.
160     *
161     * @param rs Context to which the sampler will belong.
162     *
163     * @return Sampler
164     */
165    public static Sampler WRAP_NEAREST(RenderScript rs) {
166        if(rs.mSampler_WRAP_NEAREST == null) {
167            Builder b = new Builder(rs);
168            b.setMinification(Value.NEAREST);
169            b.setMagnification(Value.NEAREST);
170            b.setWrapS(Value.WRAP);
171            b.setWrapT(Value.WRAP);
172            rs.mSampler_WRAP_NEAREST = b.create();
173        }
174        return rs.mSampler_WRAP_NEAREST;
175    }
176
177    /**
178     * Retrieve a sampler with min and mag set to linear and wrap modes set to
179     * wrap.
180     *
181     * @param rs Context to which the sampler will belong.
182     *
183     * @return Sampler
184     */
185    public static Sampler WRAP_LINEAR(RenderScript rs) {
186        if(rs.mSampler_WRAP_LINEAR == null) {
187            Builder b = new Builder(rs);
188            b.setMinification(Value.LINEAR);
189            b.setMagnification(Value.LINEAR);
190            b.setWrapS(Value.WRAP);
191            b.setWrapT(Value.WRAP);
192            rs.mSampler_WRAP_LINEAR = b.create();
193        }
194        return rs.mSampler_WRAP_LINEAR;
195    }
196
197    /**
198     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
199     * wrap modes set to wrap.
200     *
201     * @param rs Context to which the sampler will belong.
202     *
203     * @return Sampler
204     */
205    public static Sampler WRAP_LINEAR_MIP_LINEAR(RenderScript rs) {
206        if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) {
207            Builder b = new Builder(rs);
208            b.setMinification(Value.LINEAR_MIP_LINEAR);
209            b.setMagnification(Value.LINEAR);
210            b.setWrapS(Value.WRAP);
211            b.setWrapT(Value.WRAP);
212            rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
213        }
214        return rs.mSampler_WRAP_LINEAR_MIP_LINEAR;
215    }
216
217    /**
218     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
219     * mirrored repeat.
220     *
221     * @param rs Context to which the sampler will belong.
222     *
223     * @return Sampler
224     */
225    public static Sampler MIRRORED_REPEAT_NEAREST(RenderScript rs) {
226        if(rs.mSampler_MIRRORED_REPEAT_NEAREST == null) {
227            Builder b = new Builder(rs);
228            b.setMinification(Value.NEAREST);
229            b.setMagnification(Value.NEAREST);
230            b.setWrapS(Value.MIRRORED_REPEAT);
231            b.setWrapT(Value.MIRRORED_REPEAT);
232            rs.mSampler_MIRRORED_REPEAT_NEAREST = b.create();
233        }
234        return rs.mSampler_MIRRORED_REPEAT_NEAREST;
235    }
236
237    /**
238     * Retrieve a sampler with min and mag set to linear and wrap modes set to
239     * mirrored repeat.
240     *
241     * @param rs Context to which the sampler will belong.
242     *
243     * @return Sampler
244     */
245    public static Sampler MIRRORED_REPEAT_LINEAR(RenderScript rs) {
246        if(rs.mSampler_MIRRORED_REPEAT_LINEAR == null) {
247            Builder b = new Builder(rs);
248            b.setMinification(Value.LINEAR);
249            b.setMagnification(Value.LINEAR);
250            b.setWrapS(Value.MIRRORED_REPEAT);
251            b.setWrapT(Value.MIRRORED_REPEAT);
252            rs.mSampler_MIRRORED_REPEAT_LINEAR = b.create();
253        }
254        return rs.mSampler_MIRRORED_REPEAT_LINEAR;
255    }
256
257    /**
258     * Builder for creating non-standard samplers.  Usefull if mix and match of
259     * wrap modes is necesary or if anisotropic filtering is desired.
260     *
261     */
262    public static class Builder {
263        RenderScript mRS;
264        Value mMin;
265        Value mMag;
266        Value mWrapS;
267        Value mWrapT;
268        Value mWrapR;
269        float mAniso;
270
271        public Builder(RenderScript rs) {
272            mRS = rs;
273            mMin = Value.NEAREST;
274            mMag = Value.NEAREST;
275            mWrapS = Value.WRAP;
276            mWrapT = Value.WRAP;
277            mWrapR = Value.WRAP;
278            mAniso = 1.0f;
279        }
280
281        public void setMinification(Value v) {
282            if (v == Value.NEAREST ||
283                v == Value.LINEAR ||
284                v == Value.LINEAR_MIP_LINEAR ||
285                v == Value.LINEAR_MIP_NEAREST) {
286                mMin = v;
287            } else {
288                throw new IllegalArgumentException("Invalid value");
289            }
290        }
291
292        public void setMagnification(Value v) {
293            if (v == Value.NEAREST || v == Value.LINEAR) {
294                mMag = v;
295            } else {
296                throw new IllegalArgumentException("Invalid value");
297            }
298        }
299
300        public void setWrapS(Value v) {
301            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
302                mWrapS = v;
303            } else {
304                throw new IllegalArgumentException("Invalid value");
305            }
306        }
307
308        public void setWrapT(Value v) {
309            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
310                mWrapT = v;
311            } else {
312                throw new IllegalArgumentException("Invalid value");
313            }
314        }
315
316        public void setAnisotropy(float v) {
317            if(v >= 0.0f) {
318                mAniso = v;
319            } else {
320                throw new IllegalArgumentException("Invalid value");
321            }
322        }
323
324        public Sampler create() {
325            if (mRS.isNative) {
326                RenderScriptThunker rst = (RenderScriptThunker)mRS;
327                SamplerThunker.Builder b = new SamplerThunker.Builder(rst);
328                b.setMinification(mMin);
329                b.setMagnification(mMag);
330                b.setWrapS(mWrapS);
331                b.setWrapT(mWrapT);
332                b.setAnisotropy(mAniso);
333                return b.create();
334            }
335            mRS.validate();
336            int id = mRS.nSamplerCreate(mMag.mID, mMin.mID,
337                                        mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
338            Sampler sampler = new Sampler(id, mRS);
339            sampler.mMin = mMin;
340            sampler.mMag = mMag;
341            sampler.mWrapS = mWrapS;
342            sampler.mWrapT = mWrapT;
343            sampler.mWrapR = mWrapR;
344            sampler.mAniso = mAniso;
345            return sampler;
346        }
347    }
348
349}
350
351