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