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