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