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 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
44        int mID;
45        Value(int id) {
46            mID = id;
47        }
48    }
49
50    Value mMin;
51    Value mMag;
52    Value mWrapS;
53    Value mWrapT;
54    Value mWrapR;
55    float mAniso;
56
57    Sampler(int id, RenderScript rs) {
58        super(id, rs);
59    }
60
61    /**
62     * @return minification setting for the sampler
63     */
64    public Value getMinification() {
65        return mMin;
66    }
67
68    /**
69     * @return magnification setting for the sampler
70     */
71    public Value getMagnification() {
72        return mMag;
73    }
74
75    /**
76     * @return S wrapping mode for the sampler
77     */
78    public Value getWrapS() {
79        return mWrapS;
80    }
81
82    /**
83     * @return T wrapping mode for the sampler
84     */
85    public Value getWrapT() {
86        return mWrapT;
87    }
88
89    /**
90     * @return anisotropy setting for the sampler
91     */
92    public float getAnisotropy() {
93        return mAniso;
94    }
95
96    /**
97     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
98     * clamp.
99     *
100     * @param rs Context to which the sampler will belong.
101     *
102     * @return Sampler
103     */
104    public static Sampler CLAMP_NEAREST(RenderScript rs) {
105        if(rs.mSampler_CLAMP_NEAREST == null) {
106            Builder b = new Builder(rs);
107            b.setMinification(Value.NEAREST);
108            b.setMagnification(Value.NEAREST);
109            b.setWrapS(Value.CLAMP);
110            b.setWrapT(Value.CLAMP);
111            rs.mSampler_CLAMP_NEAREST = b.create();
112        }
113        return rs.mSampler_CLAMP_NEAREST;
114    }
115
116    /**
117     * Retrieve a sampler with min and mag set to linear and wrap modes set to
118     * clamp.
119     *
120     * @param rs Context to which the sampler will belong.
121     *
122     * @return Sampler
123     */
124    public static Sampler CLAMP_LINEAR(RenderScript rs) {
125        if(rs.mSampler_CLAMP_LINEAR == null) {
126            Builder b = new Builder(rs);
127            b.setMinification(Value.LINEAR);
128            b.setMagnification(Value.LINEAR);
129            b.setWrapS(Value.CLAMP);
130            b.setWrapT(Value.CLAMP);
131            rs.mSampler_CLAMP_LINEAR = b.create();
132        }
133        return rs.mSampler_CLAMP_LINEAR;
134    }
135
136    /**
137     * Retrieve a sampler with ag set to linear, min linear mipmap linear, and
138     * to and wrap modes set to clamp.
139     *
140     * @param rs Context to which the sampler will belong.
141     *
142     * @return Sampler
143     */
144    public static Sampler CLAMP_LINEAR_MIP_LINEAR(RenderScript rs) {
145        if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) {
146            Builder b = new Builder(rs);
147            b.setMinification(Value.LINEAR_MIP_LINEAR);
148            b.setMagnification(Value.LINEAR);
149            b.setWrapS(Value.CLAMP);
150            b.setWrapT(Value.CLAMP);
151            rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
152        }
153        return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
154    }
155
156    /**
157     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
158     * wrap.
159     *
160     * @param rs Context to which the sampler will belong.
161     *
162     * @return Sampler
163     */
164    public static Sampler WRAP_NEAREST(RenderScript rs) {
165        if(rs.mSampler_WRAP_NEAREST == null) {
166            Builder b = new Builder(rs);
167            b.setMinification(Value.NEAREST);
168            b.setMagnification(Value.NEAREST);
169            b.setWrapS(Value.WRAP);
170            b.setWrapT(Value.WRAP);
171            rs.mSampler_WRAP_NEAREST = b.create();
172        }
173        return rs.mSampler_WRAP_NEAREST;
174    }
175
176    /**
177     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
178     * wrap.
179     *
180     * @param rs Context to which the sampler will belong.
181     *
182     * @return Sampler
183     */
184    public static Sampler WRAP_LINEAR(RenderScript rs) {
185        if(rs.mSampler_WRAP_LINEAR == null) {
186            Builder b = new Builder(rs);
187            b.setMinification(Value.LINEAR);
188            b.setMagnification(Value.LINEAR);
189            b.setWrapS(Value.WRAP);
190            b.setWrapT(Value.WRAP);
191            rs.mSampler_WRAP_LINEAR = b.create();
192        }
193        return rs.mSampler_WRAP_LINEAR;
194    }
195
196    /**
197     * Retrieve a sampler with ag set to linear, min linear mipmap linear, and
198     * to and wrap modes set to wrap.
199     *
200     * @param rs Context to which the sampler will belong.
201     *
202     * @return Sampler
203     */
204    public static Sampler WRAP_LINEAR_MIP_LINEAR(RenderScript rs) {
205        if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) {
206            Builder b = new Builder(rs);
207            b.setMinification(Value.LINEAR_MIP_LINEAR);
208            b.setMagnification(Value.LINEAR);
209            b.setWrapS(Value.WRAP);
210            b.setWrapT(Value.WRAP);
211            rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
212        }
213        return rs.mSampler_WRAP_LINEAR_MIP_LINEAR;
214    }
215
216
217    /**
218     * Builder for creating non-standard samplers.  Usefull if mix and match of
219     * wrap modes is necesary or if anisotropic filtering is desired.
220     *
221     */
222    public static class Builder {
223        RenderScript mRS;
224        Value mMin;
225        Value mMag;
226        Value mWrapS;
227        Value mWrapT;
228        Value mWrapR;
229        float mAniso;
230
231        public Builder(RenderScript rs) {
232            mRS = rs;
233            mMin = Value.NEAREST;
234            mMag = Value.NEAREST;
235            mWrapS = Value.WRAP;
236            mWrapT = Value.WRAP;
237            mWrapR = Value.WRAP;
238            mAniso = 1.0f;
239        }
240
241        public void setMinification(Value v) {
242            if (v == Value.NEAREST ||
243                v == Value.LINEAR ||
244                v == Value.LINEAR_MIP_LINEAR ||
245                v == Value.LINEAR_MIP_NEAREST) {
246                mMin = v;
247            } else {
248                throw new IllegalArgumentException("Invalid value");
249            }
250        }
251
252        public void setMagnification(Value v) {
253            if (v == Value.NEAREST || v == Value.LINEAR) {
254                mMag = v;
255            } else {
256                throw new IllegalArgumentException("Invalid value");
257            }
258        }
259
260        public void setWrapS(Value v) {
261            if (v == Value.WRAP || v == Value.CLAMP) {
262                mWrapS = v;
263            } else {
264                throw new IllegalArgumentException("Invalid value");
265            }
266        }
267
268        public void setWrapT(Value v) {
269            if (v == Value.WRAP || v == Value.CLAMP) {
270                mWrapT = v;
271            } else {
272                throw new IllegalArgumentException("Invalid value");
273            }
274        }
275
276        public void setAnisotropy(float v) {
277            if(v >= 0.0f) {
278                mAniso = v;
279            } else {
280                throw new IllegalArgumentException("Invalid value");
281            }
282        }
283
284        public Sampler create() {
285            mRS.validate();
286            int id = mRS.nSamplerCreate(mMag.mID, mMin.mID,
287                                        mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
288            Sampler sampler = new Sampler(id, mRS);
289            sampler.mMin = mMin;
290            sampler.mMag = mMag;
291            sampler.mWrapS = mWrapS;
292            sampler.mWrapT = mWrapT;
293            sampler.mWrapR = mWrapR;
294            sampler.mAniso = mAniso;
295            return sampler;
296        }
297    }
298
299}
300
301