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