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 
17 package 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  **/
35 public 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;
DepthFunc(int id)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;
BlendSrcFunc(int id)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;
BlendDstFunc(int id)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 
ProgramStore(long id, RenderScript rs)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     */
getDepthFunc()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     */
isDepthMaskEnabled()163     public boolean isDepthMaskEnabled() {
164         return mDepthMask;
165     }
166 
167     /**
168     * Queries whether red channel is written
169     * @return red color channel mask
170     */
isColorMaskRedEnabled()171     public boolean isColorMaskRedEnabled() {
172         return mColorMaskR;
173     }
174 
175     /**
176     * Queries whether green channel is written
177     * @return green color channel mask
178     */
isColorMaskGreenEnabled()179     public boolean isColorMaskGreenEnabled() {
180         return mColorMaskG;
181     }
182 
183     /**
184     * Queries whether blue channel is written
185     * @return blue color channel mask
186     */
isColorMaskBlueEnabled()187     public boolean isColorMaskBlueEnabled() {
188         return mColorMaskB;
189     }
190 
191     /**
192     * Queries whether alpha channel is written
193     * @return alpha channel mask
194     */
isColorMaskAlphaEnabled()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     */
getBlendSrcFunc()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     */
getBlendDstFunc()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     */
isDitherEnabled()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     **/
BLEND_NONE_DEPTH_TEST(RenderScript rs)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     **/
BLEND_NONE_DEPTH_NONE(RenderScript rs)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     **/
BLEND_ALPHA_DEPTH_TEST(RenderScript rs)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     **/
BLEND_ALPHA_DEPTH_NONE(RenderScript rs)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 
Builder(RenderScript rs)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         */
setDepthFunc(DepthFunc func)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         */
setDepthMaskEnabled(boolean enable)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         */
setColorMaskEnabled(boolean r, boolean g, boolean b, boolean a)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         */
setBlendFunc(BlendSrcFunc src, BlendDstFunc dst)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         */
setDitherEnabled(boolean enable)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         */
create()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