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