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