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 
17 package androidx.renderscript;
18 
19 
20 import java.io.IOException;
21 import java.io.InputStream;
22 
23 import android.content.res.Resources;
24 import android.os.Bundle;
25 import android.util.Log;
26 
27 import android.graphics.Bitmap;
28 import 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  * androidx.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a
37  * Sampler on an {@link androidx.renderscript.Allocation} that was not
38  * created with
39  * {@link androidx.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is
40  * undefined.
41  **/
42 public 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;
Value(int id)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 
Sampler(long id, RenderScript rs)65     Sampler(long id, RenderScript rs) {
66         super(id, rs);
67     }
68 
69     /**
70      * @return minification setting for the sampler
71      */
getMinification()72     public Value getMinification() {
73         return mMin;
74     }
75 
76     /**
77      * @return magnification setting for the sampler
78      */
getMagnification()79     public Value getMagnification() {
80         return mMag;
81     }
82 
83     /**
84      * @return S wrapping mode for the sampler
85      */
getWrapS()86     public Value getWrapS() {
87         return mWrapS;
88     }
89 
90     /**
91      * @return T wrapping mode for the sampler
92      */
getWrapT()93     public Value getWrapT() {
94         return mWrapT;
95     }
96 
97     /**
98      * @return anisotropy setting for the sampler
99      */
getAnisotropy()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      */
CLAMP_NEAREST(RenderScript rs)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      */
CLAMP_LINEAR(RenderScript rs)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      */
CLAMP_LINEAR_MIP_LINEAR(RenderScript rs)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      */
WRAP_NEAREST(RenderScript rs)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      */
WRAP_LINEAR(RenderScript rs)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      */
WRAP_LINEAR_MIP_LINEAR(RenderScript rs)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      */
MIRRORED_REPEAT_NEAREST(RenderScript rs)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      */
MIRRORED_REPEAT_LINEAR(RenderScript rs)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 
Builder(RenderScript rs)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 
setMinification(Value v)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 
setMagnification(Value v)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 
setWrapS(Value v)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 
setWrapT(Value v)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 
setAnisotropy(float v)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 
create()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