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