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/**
21 * @hide
22 * <p>ProgramStore contains a set of parameters that control how
23 * the graphics hardware handles writes to the framebuffer.
24 * It could be used to:</p>
25 * <ul>
26 *   <li>enable/disable depth testing</li>
27 *   <li>specify wheather depth writes are performed</li>
28 *   <li>setup various blending modes for use in effects like
29 *     transparency</li>
30 *   <li>define write masks for color components written into the
31 *     framebuffer</li>
32 *  </ul>
33 *
34 **/
35public class ProgramStore extends BaseObj {
36    /**
37    * Specifies the function used to determine whether a fragment
38    * will be drawn during the depth testing stage in the rendering
39    * pipeline by comparing its value with that already in the depth
40    * buffer. DepthFunc is only valid when depth buffer is present
41    * and depth testing is enabled
42    */
43    public enum DepthFunc {
44
45        /**
46        * Always drawn
47        */
48        ALWAYS (0),
49        /**
50        * Drawn if the incoming depth value is less than that in the
51        * depth buffer
52        */
53        LESS (1),
54        /**
55        * Drawn if the incoming depth value is less or equal to that in
56        * the depth buffer
57        */
58        LESS_OR_EQUAL (2),
59        /**
60        * Drawn if the incoming depth value is greater than that in the
61        * depth buffer
62        */
63        GREATER (3),
64        /**
65        * Drawn if the incoming depth value is greater or equal to that
66        * in the depth buffer
67        */
68        GREATER_OR_EQUAL (4),
69        /**
70        * Drawn if the incoming depth value is equal to that in the
71        * depth buffer
72        */
73        EQUAL (5),
74        /**
75        * Drawn if the incoming depth value is not equal to that in the
76        * depth buffer
77        */
78        NOT_EQUAL (6);
79
80        int mID;
81        DepthFunc(int id) {
82            mID = id;
83        }
84    }
85
86    /**
87    * Specifies the functions used to combine incoming pixels with
88    * those already in the frame buffer.
89    *
90    * BlendSrcFunc describes how the coefficient used to scale the
91    * source pixels during the blending operation is computed
92    *
93    */
94    public enum BlendSrcFunc {
95        ZERO (0),
96        ONE (1),
97        DST_COLOR (2),
98        ONE_MINUS_DST_COLOR (3),
99        SRC_ALPHA (4),
100        ONE_MINUS_SRC_ALPHA (5),
101        DST_ALPHA (6),
102        ONE_MINUS_DST_ALPHA (7),
103        SRC_ALPHA_SATURATE (8);
104
105        int mID;
106        BlendSrcFunc(int id) {
107            mID = id;
108        }
109    }
110
111    /**
112    * Specifies the functions used to combine incoming pixels with
113    * those already in the frame buffer.
114    *
115    * BlendDstFunc describes how the coefficient used to scale the
116    * pixels already in the framebuffer is computed during the
117    * blending operation
118    *
119    */
120    public enum BlendDstFunc {
121        ZERO (0),
122        ONE (1),
123        SRC_COLOR (2),
124        ONE_MINUS_SRC_COLOR (3),
125        SRC_ALPHA (4),
126        ONE_MINUS_SRC_ALPHA (5),
127        DST_ALPHA (6),
128        ONE_MINUS_DST_ALPHA (7);
129
130        int mID;
131        BlendDstFunc(int id) {
132            mID = id;
133        }
134    }
135
136    DepthFunc mDepthFunc;
137    boolean mDepthMask;
138    boolean mColorMaskR;
139    boolean mColorMaskG;
140    boolean mColorMaskB;
141    boolean mColorMaskA;
142    BlendSrcFunc mBlendSrc;
143    BlendDstFunc mBlendDst;
144    boolean mDither;
145
146    ProgramStore(long id, RenderScript rs) {
147        super(id, rs);
148    }
149
150    /**
151    * Returns the function used to test writing into the depth
152    * buffer
153    * @return depth function
154    */
155    public DepthFunc getDepthFunc() {
156        return mDepthFunc;
157    }
158
159    /**
160    * Queries whether writes are enabled into the depth buffer
161    * @return depth mask
162    */
163    public boolean isDepthMaskEnabled() {
164        return mDepthMask;
165    }
166
167    /**
168    * Queries whether red channel is written
169    * @return red color channel mask
170    */
171    public boolean isColorMaskRedEnabled() {
172        return mColorMaskR;
173    }
174
175    /**
176    * Queries whether green channel is written
177    * @return green color channel mask
178    */
179    public boolean isColorMaskGreenEnabled() {
180        return mColorMaskG;
181    }
182
183    /**
184    * Queries whether blue channel is written
185    * @return blue color channel mask
186    */
187    public boolean isColorMaskBlueEnabled() {
188        return mColorMaskB;
189    }
190
191    /**
192    * Queries whether alpha channel is written
193    * @return alpha channel mask
194    */
195    public boolean isColorMaskAlphaEnabled() {
196        return mColorMaskA;
197    }
198
199    /**
200    * Specifies how the source blending factor is computed
201    * @return source blend function
202    */
203    public BlendSrcFunc getBlendSrcFunc() {
204        return mBlendSrc;
205    }
206
207    /**
208    * Specifies how the destination blending factor is computed
209    * @return destination blend function
210    */
211    public BlendDstFunc getBlendDstFunc() {
212        return mBlendDst;
213    }
214
215    /**
216    * Specifies whether colors are dithered before writing into the
217    * framebuffer
218    * @return whether dither is enabled
219    */
220    public boolean isDitherEnabled() {
221        return mDither;
222    }
223
224    /**
225    * Returns a pre-defined program store object with the following
226    * characteristics:
227    *  - incoming pixels are drawn if their depth value is less than
228    *    the stored value in the depth buffer. If the pixel is
229    *    drawn, its value is also stored in the depth buffer
230    *  - incoming pixels override the value stored in the color
231    *    buffer if it passes the depth test
232    *
233    *  @param rs Context to which the program will belong.
234    **/
235    public static ProgramStore BLEND_NONE_DEPTH_TEST(RenderScript rs) {
236        if(rs.mProgramStore_BLEND_NONE_DEPTH_TEST == null) {
237            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
238            builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
239            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
240            builder.setDitherEnabled(false);
241            builder.setDepthMaskEnabled(true);
242            rs.mProgramStore_BLEND_NONE_DEPTH_TEST = builder.create();
243        }
244        return rs.mProgramStore_BLEND_NONE_DEPTH_TEST;
245    }
246    /**
247    * Returns a pre-defined program store object with the following
248    * characteristics:
249    *  - incoming pixels always pass the depth test and their value
250    *    is not stored in the depth buffer
251    *  - incoming pixels override the value stored in the color
252    *    buffer
253    *
254    *  @param rs Context to which the program will belong.
255    **/
256    public static ProgramStore BLEND_NONE_DEPTH_NONE(RenderScript rs) {
257        if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH == null) {
258            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
259            builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
260            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
261            builder.setDitherEnabled(false);
262            builder.setDepthMaskEnabled(false);
263            rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH = builder.create();
264        }
265        return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
266    }
267    /**
268    * Returns a pre-defined program store object with the following
269    * characteristics:
270    *  - incoming pixels are drawn if their depth value is less than
271    *    the stored value in the depth buffer. If the pixel is
272    *    drawn, its value is also stored in the depth buffer
273    *  - if the incoming (Source) pixel passes depth test, its value
274    *    is combined with the stored color (Dest) using the
275    *    following formula
276    *  Final.RGB = Source.RGB * Source.A + Dest.RGB * (1 - Source.A)
277    *
278    *  @param rs Context to which the program will belong.
279    **/
280    public static ProgramStore BLEND_ALPHA_DEPTH_TEST(RenderScript rs) {
281        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST == null) {
282            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
283            builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
284            builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
285            builder.setDitherEnabled(false);
286            builder.setDepthMaskEnabled(true);
287            rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST = builder.create();
288        }
289        return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST;
290    }
291    /**
292    * Returns a pre-defined program store object with the following
293    * characteristics:
294    *  - incoming pixels always pass the depth test and their value
295    *    is not stored in the depth buffer
296    *  - incoming pixel's value is combined with the stored color
297    *    (Dest) using the following formula
298    *  Final.RGB = Source.RGB * Source.A + Dest.RGB * (1 - Source.A)
299    *
300    *  @param rs Context to which the program will belong.
301    **/
302    public static ProgramStore BLEND_ALPHA_DEPTH_NONE(RenderScript rs) {
303        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH == null) {
304            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
305            builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
306            builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
307            builder.setDitherEnabled(false);
308            builder.setDepthMaskEnabled(false);
309            rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH = builder.create();
310        }
311        return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
312    }
313
314    /**
315    * Builder class for ProgramStore object. If the builder is left
316    * empty, the equivalent of BLEND_NONE_DEPTH_NONE would be
317    * returned
318    */
319    public static class Builder {
320        RenderScript mRS;
321        DepthFunc mDepthFunc;
322        boolean mDepthMask;
323        boolean mColorMaskR;
324        boolean mColorMaskG;
325        boolean mColorMaskB;
326        boolean mColorMaskA;
327        BlendSrcFunc mBlendSrc;
328        BlendDstFunc mBlendDst;
329        boolean mDither;
330
331        public Builder(RenderScript rs) {
332            mRS = rs;
333            mDepthFunc = DepthFunc.ALWAYS;
334            mDepthMask = false;
335            mColorMaskR = true;
336            mColorMaskG = true;
337            mColorMaskB = true;
338            mColorMaskA = true;
339            mBlendSrc = BlendSrcFunc.ONE;
340            mBlendDst = BlendDstFunc.ZERO;
341        }
342
343        /**
344        * Specifies the depth testing behavior
345        *
346        * @param func function used for depth testing
347        *
348        * @return this
349        */
350        public Builder setDepthFunc(DepthFunc func) {
351            mDepthFunc = func;
352            return this;
353        }
354
355        /**
356        * Enables writes into the depth buffer
357        *
358        * @param enable specifies whether depth writes are
359        *         enabled or disabled
360        *
361        * @return this
362        */
363        public Builder setDepthMaskEnabled(boolean enable) {
364            mDepthMask = enable;
365            return this;
366        }
367
368        /**
369        * Enables writes into the color buffer
370        *
371        * @param r specifies whether red channel is written
372        * @param g specifies whether green channel is written
373        * @param b specifies whether blue channel is written
374        * @param a specifies whether alpha channel is written
375        *
376        * @return this
377        */
378        public Builder setColorMaskEnabled(boolean r, boolean g, boolean b, boolean a) {
379            mColorMaskR = r;
380            mColorMaskG = g;
381            mColorMaskB = b;
382            mColorMaskA = a;
383            return this;
384        }
385
386        /**
387        * Specifies how incoming pixels are combined with the pixels
388        * stored in the framebuffer
389        *
390        * @param src specifies how the source blending factor is
391        *            computed
392        * @param dst specifies how the destination blending factor is
393        *            computed
394        *
395        * @return this
396        */
397        public Builder setBlendFunc(BlendSrcFunc src, BlendDstFunc dst) {
398            mBlendSrc = src;
399            mBlendDst = dst;
400            return this;
401        }
402
403        /**
404        * Enables dithering
405        *
406        * @param enable specifies whether dithering is enabled or
407        *               disabled
408        *
409        * @return this
410        */
411        public Builder setDitherEnabled(boolean enable) {
412            mDither = enable;
413            return this;
414        }
415
416        /**
417        * Creates a program store from the current state of the builder
418        */
419        public ProgramStore create() {
420            mRS.validate();
421            long id = mRS.nProgramStoreCreate(mColorMaskR, mColorMaskG, mColorMaskB, mColorMaskA,
422                                             mDepthMask, mDither,
423                                             mBlendSrc.mID, mBlendDst.mID, mDepthFunc.mID);
424            ProgramStore programStore = new ProgramStore(id, mRS);
425            programStore.mDepthFunc = mDepthFunc;
426            programStore.mDepthMask = mDepthMask;
427            programStore.mColorMaskR = mColorMaskR;
428            programStore.mColorMaskG = mColorMaskG;
429            programStore.mColorMaskB = mColorMaskB;
430            programStore.mColorMaskA = mColorMaskA;
431            programStore.mBlendSrc = mBlendSrc;
432            programStore.mBlendDst = mBlendDst;
433            programStore.mDither = mDither;
434            return programStore;
435        }
436    }
437
438}
439
440
441
442
443