1/*
2 * Copyright (C) 2008 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.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     * Retrieve a sampler with min and mag set to linear and wrap modes set to
264     * mirrored repeat.
265     *
266     * @param rs Context to which the sampler will belong.
267     *
268     * @return Sampler
269     */
270    public static Sampler MIRRORED_REPEAT_LINEAR_MIP_LINEAR(RenderScript rs) {
271        if(rs.mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR == null) {
272            Builder b = new Builder(rs);
273            b.setMinification(Value.LINEAR_MIP_LINEAR);
274            b.setMagnification(Value.LINEAR);
275            b.setWrapS(Value.MIRRORED_REPEAT);
276            b.setWrapT(Value.MIRRORED_REPEAT);
277            rs.mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR = b.create();
278        }
279        return rs.mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
280    }
281
282    /**
283     * Builder for creating non-standard samplers.  This is only necessary if
284     * a Sampler with different min and mag modes is desired.
285     */
286    public static class Builder {
287        RenderScript mRS;
288        Value mMin;
289        Value mMag;
290        Value mWrapS;
291        Value mWrapT;
292        Value mWrapR;
293        float mAniso;
294
295        public Builder(RenderScript rs) {
296            mRS = rs;
297            mMin = Value.NEAREST;
298            mMag = Value.NEAREST;
299            mWrapS = Value.WRAP;
300            mWrapT = Value.WRAP;
301            mWrapR = Value.WRAP;
302            mAniso = 1.0f;
303        }
304
305        public void setMinification(Value v) {
306            if (v == Value.NEAREST ||
307                v == Value.LINEAR ||
308                v == Value.LINEAR_MIP_LINEAR ||
309                v == Value.LINEAR_MIP_NEAREST) {
310                mMin = v;
311            } else {
312                throw new IllegalArgumentException("Invalid value");
313            }
314        }
315
316        public void setMagnification(Value v) {
317            if (v == Value.NEAREST || v == Value.LINEAR) {
318                mMag = v;
319            } else {
320                throw new IllegalArgumentException("Invalid value");
321            }
322        }
323
324        public void setWrapS(Value v) {
325            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
326                mWrapS = v;
327            } else {
328                throw new IllegalArgumentException("Invalid value");
329            }
330        }
331
332        public void setWrapT(Value v) {
333            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
334                mWrapT = v;
335            } else {
336                throw new IllegalArgumentException("Invalid value");
337            }
338        }
339
340        public void setAnisotropy(float v) {
341            if(v >= 0.0f) {
342                mAniso = v;
343            } else {
344                throw new IllegalArgumentException("Invalid value");
345            }
346        }
347
348        public Sampler create() {
349            mRS.validate();
350            int id = mRS.nSamplerCreate(mMag.mID, mMin.mID,
351                                        mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
352            Sampler sampler = new Sampler(id, mRS);
353            sampler.mMin = mMin;
354            sampler.mMag = mMag;
355            sampler.mWrapS = mWrapS;
356            sampler.mWrapT = mWrapT;
357            sampler.mWrapR = mWrapR;
358            sampler.mAniso = mAniso;
359            return sampler;
360        }
361    }
362
363}
364
365