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