CarouselRS.java revision a9e9c4bef076e718094786edfe0290f798e1db4b
1a3ab4494b72d9daf66f45db4d7c43677d1968a55Eric Fischer/* 21866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * Copyright (C) 2010 The Android Open Source Project 31866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * 41866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 51866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * you may not use this file except in compliance with the License. 61866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * You may obtain a copy of the License at 71866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * 81866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 91866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * 101866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * Unless required by applicable law or agreed to in writing, software 111866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 121866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * See the License for the specific language governing permissions and 141866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * limitations under the License. 151866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root */ 161866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root 171866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Rootpackage com.android.ex.carousel; 181866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root 191866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Rootimport android.content.res.Resources; 20a3ab4494b72d9daf66f45db4d7c43677d1968a55Eric Fischerimport android.graphics.Bitmap; 21a3ab4494b72d9daf66f45db4d7c43677d1968a55Eric Fischerimport android.renderscript.*; 22a3ab4494b72d9daf66f45db4d7c43677d1968a55Eric Fischerimport android.renderscript.RenderScript.RSMessage; 23e04cc8b826a8d77c62b4377beaa7ba8879f9551esatokimport android.renderscript.Sampler.Value; 2449761501db2bcb25673e635897b7b4dfd4b655d2Eric Fischerimport android.renderscript.ProgramRaster.CullMode; 25e04cc8b826a8d77c62b4377beaa7ba8879f9551esatokimport android.util.Log; 26566c45eddfaff94f82008fa767d262ce57885a7dEric Fischer 2774d36bc8af35422688f582b68c0526fd1ccf0afaEric Fischerimport com.android.internal.R; 2877541fc92e1d244bb21827715f159e6197c92133Eric Fischer 2977541fc92e1d244bb21827715f159e6197c92133Eric Fischerimport static android.renderscript.Element.*; 301f891474931c89bd575df70cbc06df45f8e5cfb8Eric Fischerimport static android.renderscript.Sampler.Value.LINEAR; 3107af2249bbaa59bc1cd282f6cbdc31d90b24bdd7Eric Fischerimport static android.renderscript.Sampler.Value.WRAP; 3207af2249bbaa59bc1cd282f6cbdc31d90b24bdd7Eric Fischerimport static android.renderscript.Sampler.Value.CLAMP; 335a323e65d06575ccf948a868d18578d8d749e738Eric Fischer 345a323e65d06575ccf948a868d18578d8d749e738Eric Fischer/** 35566c45eddfaff94f82008fa767d262ce57885a7dEric Fischer * This is a support class for Carousel renderscript. It handles most of the low-level interactions 362ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer * with Renderscript as well as dispatching events. 3780bcf30dd6dabb56076c7dc246eaa54fd43d783cEric Fischer * 3880bcf30dd6dabb56076c7dc246eaa54fd43d783cEric Fischer */ 39144e97f154ef27c48ac9030980ebb6f3ae959369Eric Fischerpublic class CarouselRS { 40482e0ef983e47f3b2958d8173fbe6dbf34a00bfeEric Fischer private static final int DEFAULT_VISIBLE_SLOTS = 1; 411cbd8d09ddf8160f1961d4869fb900a85a385526Eric Fischer private static final int DEFAULT_CARD_COUNT = 1; 422e66afcc107e14b6c5f9ec1d0ccfd252798c13d7Eric Fischer 432e66afcc107e14b6c5f9ec1d0ccfd252798c13d7Eric Fischer // Client messages *** THIS LIST MUST MATCH THOSE IN carousel.rs *** 4432c465ec4d4ba4781e75b0f2fcf12b9cd2655be6Ying Wang public static final int CMD_CARD_SELECTED = 100; 45144e97f154ef27c48ac9030980ebb6f3ae959369Eric Fischer public static final int CMD_REQUEST_TEXTURE = 200; 46144e97f154ef27c48ac9030980ebb6f3ae959369Eric Fischer public static final int CMD_INVALIDATE_TEXTURE = 210; 47ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer public static final int CMD_REQUEST_GEOMETRY = 300; 48ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer public static final int CMD_INVALIDATE_GEOMETRY = 310; 495de658603639105ce0f9cd7878868848af39cf15Eric Fischer public static final int CMD_ANIMATION_STARTED = 400; 505de658603639105ce0f9cd7878868848af39cf15Eric Fischer public static final int CMD_ANIMATION_FINISHED = 500; 5132c465ec4d4ba4781e75b0f2fcf12b9cd2655be6Ying Wang public static final int CMD_REQUEST_DETAIL_TEXTURE = 600; 5232c465ec4d4ba4781e75b0f2fcf12b9cd2655be6Ying Wang public static final int CMD_INVALIDATE_DETAIL_TEXTURE = 610; 53991a4737079f59cc973327b31bf11b46c301c62dEric Fischer public static final int CMD_REPORT_FIRST_CARD_POSITION = 700; 542ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer public static final int CMD_PING = 1000; // for debugging 552ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer 562ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer private static final String TAG = "CarouselRS"; 572ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer private static final int DEFAULT_SLOT_COUNT = 10; 582ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer private static final boolean MIPMAP = false; 592ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer private static final boolean DBG = false; 6032c465ec4d4ba4781e75b0f2fcf12b9cd2655be6Ying Wang 612ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer private RenderScriptGL mRS; 622ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer private Resources mRes; 632ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer private ScriptC_carousel mScript; 64ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer private ScriptField_Card mCards; 65fad6a2625b86c924f56ab8d4ac51a6ee3e76de64Eric Fischer private ScriptField_FragmentShaderConstants_s mFSConst; 66fad6a2625b86c924f56ab8d4ac51a6ee3e76de64Eric Fischer private ProgramStore mProgramStore; 67fad6a2625b86c924f56ab8d4ac51a6ee3e76de64Eric Fischer private ProgramFragment mSingleTextureFragmentProgram; 6880bcf30dd6dabb56076c7dc246eaa54fd43d783cEric Fischer private ProgramFragment mMultiTextureFragmentProgram; 695a323e65d06575ccf948a868d18578d8d749e738Eric Fischer private ProgramVertex mVertexProgram; 705a323e65d06575ccf948a868d18578d8d749e738Eric Fischer private ProgramRaster mRasterProgram; 715a323e65d06575ccf948a868d18578d8d749e738Eric Fischer private CarouselCallback mCallback; 72b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer private float[] mEyePoint = new float[3]; 735a323e65d06575ccf948a868d18578d8d749e738Eric Fischer private float[] mAtPoint = new float[3]; 745a323e65d06575ccf948a868d18578d8d749e738Eric Fischer private float[] mUp = new float[3]; 752ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer 76bf8aa9d3489973718625206064c35fdf129c3150Eric Fischer private static final String mSingleTextureShader = new String( 7780d6f6716ef04aa086fe96a6fff310e7c094df3dEric Fischer "varying vec4 varTex0;" + 78af63f0663ac699926f33ea70e12c9dc72656109fEric Fischer "void main() {" + 79af63f0663ac699926f33ea70e12c9dc72656109fEric Fischer "vec2 t0 = varTex0.xy;" + 80d707eeceb558dcb68c30a23d644efe425601b438Eric Fischer "vec4 col = texture2D(UNI_Tex0, t0);" + 81ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer "gl_FragColor = col; " + 82ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer "}"); 83ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer 84ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer private static final String mMultiTextureShader = new String( 85b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer "varying vec4 varTex0;" + 86b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer "void main() {" + 87ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer "vec2 t0 = varTex0.xy;" + 88ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer "vec4 col = texture2D(UNI_Tex0, t0);" + 89ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer "vec4 col2 = texture2D(UNI_Tex1, t0);" + 90ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer "gl_FragColor = mix(col, col2, UNI_fadeAmount);}"); 91ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer 92ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer public static interface CarouselCallback { 93ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer /** 94ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer * Called when a card is selected 95ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer * @param n the id of the card 96ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer */ 972efdf6a09f9c29122f2aa8504b792c3932ca287aEric Fischer void onCardSelected(int n); 98897d1302f5f7eada34cedb6a736a8bb268b85410Eric Fischer 99b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer /** 100b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer * Called when texture is needed for card n. This happens when the given card becomes 101b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer * visible. 102b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer * @param n the id of the card 103b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer */ 104b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer void onRequestTexture(int n); 105b396ea9ede34a64437f0accc5d394640f75ffa4bEric Fischer 1065de658603639105ce0f9cd7878868848af39cf15Eric Fischer /** 1072ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer * Called when a texture is no longer needed for card n. This happens when the card 1082ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer * goes out of view. 1092ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer * @param n the id of the card 11032c465ec4d4ba4781e75b0f2fcf12b9cd2655be6Ying Wang */ 1112ca4e9ae8aaae5f30147f1b96fa27ae690cb4637Eric Fischer void onInvalidateTexture(int n); 11285427b3d8e25b36f8c0575d292348c861de40ed9Eric Fischer 113df4db224498035ac00eee7215026ec85a1dc6e7cEric Fischer /** 114a953a3c137be344b73ae8918de0e5c8afd4a1a13Eric Fischer * Called when detail texture is needed for card n. This happens when the given card 11574d36bc8af35422688f582b68c0526fd1ccf0afaEric Fischer * becomes visible. 11674d36bc8af35422688f582b68c0526fd1ccf0afaEric Fischer * @param n the id of the card 11774d36bc8af35422688f582b68c0526fd1ccf0afaEric Fischer */ 11874d36bc8af35422688f582b68c0526fd1ccf0afaEric Fischer void onRequestDetailTexture(int n); 11974d36bc8af35422688f582b68c0526fd1ccf0afaEric Fischer 12074d36bc8af35422688f582b68c0526fd1ccf0afaEric Fischer /** 1215de658603639105ce0f9cd7878868848af39cf15Eric Fischer * Called when a detail texture is no longer needed for card n. This happens when the card 1221cbd8d09ddf8160f1961d4869fb900a85a385526Eric Fischer * goes out of view. 1231866d9ec83dcbc69a2c5ba2b6129ed4ce7f9f665Kenny Root * @param n the id of the card 124566c45eddfaff94f82008fa767d262ce57885a7dEric Fischer */ 125566c45eddfaff94f82008fa767d262ce57885a7dEric Fischer void onInvalidateDetailTexture(int n); 126ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer 127790c77fdc5125c972b8ee7971738b31bf7e286adEric Fischer /** 128df4db224498035ac00eee7215026ec85a1dc6e7cEric Fischer * Called when geometry is needed for card n. 1294c4fd10d911931351ad9fb6d99015f9e3fb5f64aEric Fischer * @param n the id of the card. 1304c4fd10d911931351ad9fb6d99015f9e3fb5f64aEric Fischer */ 131b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer void onRequestGeometry(int n); 132fad6a2625b86c924f56ab8d4ac51a6ee3e76de64Eric Fischer 13319b30243d70164d3a04c3d96ab7fcc6efdbc1ec8Eric Fischer /** 13419b30243d70164d3a04c3d96ab7fcc6efdbc1ec8Eric Fischer * Called when geometry is no longer needed for card n. This happens when the card goes 13519b30243d70164d3a04c3d96ab7fcc6efdbc1ec8Eric Fischer * out of view. 13619b30243d70164d3a04c3d96ab7fcc6efdbc1ec8Eric Fischer * @param n the id of the card 13719b30243d70164d3a04c3d96ab7fcc6efdbc1ec8Eric Fischer */ 138b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer void onInvalidateGeometry(int n); 139b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer 140b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer /** 141b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer * Called when card animation (e.g. a fling) has started. 142b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer */ 143b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer void onAnimationStarted(); 144b4f5c9c08894d1e465d8dbe0b1ea9f8a3b6dfd5fEric Fischer 1453b4d2725f4e677ad7307f82fa9a4ad7cec24009dEric Fischer /** 1463b4d2725f4e677ad7307f82fa9a4ad7cec24009dEric Fischer * Called when card animation has stopped. 1473b4d2725f4e677ad7307f82fa9a4ad7cec24009dEric Fischer */ 1483b4d2725f4e677ad7307f82fa9a4ad7cec24009dEric Fischer void onAnimationFinished(); 149ff53f0fd9788c6e57f6ba658cfc3908619592b9cEric Fischer 150d707eeceb558dcb68c30a23d644efe425601b438Eric Fischer /** 151d707eeceb558dcb68c30a23d644efe425601b438Eric Fischer * Called when the current position has been requested. 152a3ab4494b72d9daf66f45db4d7c43677d1968a55Eric Fischer */ 153 void onReportFirstCardPosition(int n); 154 }; 155 156 private RSMessage mRsMessage = new RSMessage() { 157 public void run() { 158 if (mCallback == null) return; 159 switch (mID) { 160 case CMD_CARD_SELECTED: 161 mCallback.onCardSelected(mData[0]); 162 break; 163 164 case CMD_REQUEST_TEXTURE: 165 mCallback.onRequestTexture(mData[0]); 166 break; 167 168 case CMD_INVALIDATE_TEXTURE: 169 setTexture(mData[0], null); 170 mCallback.onInvalidateTexture(mData[0]); 171 break; 172 173 case CMD_REQUEST_DETAIL_TEXTURE: 174 mCallback.onRequestDetailTexture(mData[0]); 175 break; 176 177 case CMD_INVALIDATE_DETAIL_TEXTURE: 178 setDetailTexture(mData[0], 0, 0, null); 179 mCallback.onInvalidateDetailTexture(mData[0]); 180 break; 181 182 case CMD_REQUEST_GEOMETRY: 183 mCallback.onRequestGeometry(mData[0]); 184 break; 185 186 case CMD_INVALIDATE_GEOMETRY: 187 setGeometry(mData[0], null); 188 mCallback.onInvalidateGeometry(mData[0]); 189 break; 190 191 case CMD_ANIMATION_STARTED: 192 mCallback.onAnimationStarted(); 193 break; 194 195 case CMD_ANIMATION_FINISHED: 196 mCallback.onAnimationFinished(); 197 break; 198 199 case CMD_REPORT_FIRST_CARD_POSITION: 200 mCallback.onReportFirstCardPosition(mData[0]); 201 break; 202 203 case CMD_PING: 204 if (DBG) Log.v(TAG, "PING..."); 205 break; 206 207 default: 208 Log.e(TAG, "Unknown RSMessage: " + mID); 209 } 210 } 211 }; 212 213 public void init(RenderScriptGL rs, Resources res, int resId) { 214 mRS = rs; 215 mRes = res; 216 217 // create the script object 218 mScript = new ScriptC_carousel(mRS, mRes, resId, true); 219 mRS.mMessageCallback = mRsMessage; 220 221 initProgramStore(); 222 initFragmentProgram(); 223 initRasterProgram(); 224 initVertexProgram(); 225 226 setSlotCount(DEFAULT_SLOT_COUNT); 227 setVisibleSlots(DEFAULT_VISIBLE_SLOTS); 228 createCards(DEFAULT_CARD_COUNT); 229 230 setStartAngle(0.0f); 231 setRadius(1.0f); 232 233 // update the camera 234 boolean pcam = true; 235 if (pcam) { 236 float eye[] = { 20.6829f, 2.77081f, 16.7314f }; 237 float at[] = { 14.7255f, -3.40001f, -1.30184f }; 238 float up[] = { 0.0f, 1.0f, 0.0f }; 239 setLookAt(eye, at, up); 240 setRadius(20.0f); 241 // Fov: 25 242 } else { 243 mScript.invoke_lookAt(2.5f, 2.0f, 2.5f, 0.0f, -0.75f, 0.0f, 0.0f, 1.0f, 0.0f); 244 mScript.set_cardRotation(0.0f); 245 setRadius(1.5f); 246 } 247 248 resumeRendering(); 249 } 250 251 public void setLookAt(float[] eye, float[] at, float[] up) { 252 for (int i = 0; i < 3; i++) { 253 mEyePoint[i] = eye[i]; 254 mAtPoint[i] = at[i]; 255 mUp[i] = up[i]; 256 } 257 mScript.invoke_lookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], up[0], up[1], up[2]); 258 } 259 260 public void setRadius(float radius) { 261 mScript.set_radius(radius); 262 } 263 264 public void setCardRotation(float cardRotation) { 265 mScript.set_cardRotation(cardRotation); 266 } 267 268 public void setSwaySensitivity(float swaySensitivity) { 269 mScript.set_swaySensitivity(swaySensitivity); 270 } 271 272 public void setFrictionCoefficient(float frictionCoeff) { 273 mScript.set_frictionCoeff(frictionCoeff); 274 } 275 276 public void setDragFactor(float dragFactor) { 277 mScript.set_dragFactor(dragFactor); 278 } 279 280 private void initVertexProgram() { 281 ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); 282 mVertexProgram = pvb.create(); 283 ProgramVertex.MatrixAllocation pva = new ProgramVertex.MatrixAllocation(mRS); 284 mVertexProgram.bindAllocation(pva); 285 pva.setupProjectionNormalized(1, 1); 286 mScript.set_vertexProgram(mVertexProgram); 287 } 288 289 private void initRasterProgram() { 290 ProgramRaster.Builder programRasterBuilder = new ProgramRaster.Builder(mRS); 291 mRasterProgram = programRasterBuilder.create(); 292 //mRasterProgram.setCullMode(CullMode.NONE); 293 mScript.set_rasterProgram(mRasterProgram); 294 } 295 296 private void initFragmentProgram() { 297 // 298 // Single texture program 299 // 300 ProgramFragment.ShaderBuilder pfbSingle = new ProgramFragment.ShaderBuilder(mRS); 301 // Specify the resource that contains the shader string 302 pfbSingle.setShader(mSingleTextureShader); 303 // Tell the builder how many textures we have 304 pfbSingle.setTextureCount(1); 305 mSingleTextureFragmentProgram = pfbSingle.create(); 306 // Bind the source of constant data 307 mSingleTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); 308 309 // 310 // Multi texture program 311 // 312 mFSConst = new ScriptField_FragmentShaderConstants_s(mRS, 1); 313 mScript.bind_shaderConstants(mFSConst); 314 ProgramFragment.ShaderBuilder pfbMulti = new ProgramFragment.ShaderBuilder(mRS); 315 // Specify the resource that contains the shader string 316 pfbMulti.setShader(mMultiTextureShader); 317 // Tell the builder how many textures we have 318 pfbMulti.setTextureCount(2); 319 // Define the constant input layout 320 pfbMulti.addConstant(mFSConst.getAllocation().getType()); 321 mMultiTextureFragmentProgram = pfbMulti.create(); 322 // Bind the source of constant data 323 mMultiTextureFragmentProgram.bindConstants(mFSConst.getAllocation(), 0); 324 mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); 325 mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 1); 326 327 mScript.set_linearClamp(Sampler.CLAMP_LINEAR(mRS)); 328 mScript.set_singleTextureFragmentProgram(mSingleTextureFragmentProgram); 329 mScript.set_multiTextureFragmentProgram(mMultiTextureFragmentProgram); 330 } 331 332 private void initProgramStore() { 333 ProgramStore.Builder programStoreBuilder = new ProgramStore.Builder(mRS, null, null); 334 programStoreBuilder.setDepthFunc(ProgramStore.DepthFunc.LESS); 335 programStoreBuilder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, 336 ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); 337 programStoreBuilder.setDitherEnable(true); 338 programStoreBuilder.setDepthMask(true); 339 mProgramStore = programStoreBuilder.create(); 340 mScript.set_programStore(mProgramStore); 341 } 342 343 public void createCards(int count) 344 { 345 // Because RenderScript can't have allocations with 0 dimensions, we always create 346 // an allocation of at least one card. This relies on invoke_createCards() to keep 347 // track of when the allocation is not valid. 348 if (mCards != null) { 349 // resize the array 350 ScriptField_Card tmpcards = new ScriptField_Card(mRS, count > 0 ? count : 1); 351 mScript.bind_tmpCards(tmpcards); 352 mScript.invoke_copyCards(); 353 mScript.bind_cards(tmpcards); 354 mScript.bind_tmpCards(null); 355 mCards = tmpcards; 356 } else { 357 // create array from scratch 358 mCards = new ScriptField_Card(mRS, count > 0 ? count : 1); 359 mScript.bind_cards(mCards); 360 mScript.invoke_createCards(count); 361 } 362 } 363 364 public void setVisibleSlots(int count) 365 { 366 mScript.set_visibleSlotCount(count); 367 } 368 369 public void setVisibleDetails(int count) { 370 mScript.set_visibleDetailCount(count); 371 } 372 373 public void setDrawDetailBelowCard(boolean below) { 374 mScript.set_drawDetailBelowCard(below); 375 } 376 377 public void setDrawRuler(boolean drawRuler) { 378 mScript.set_drawRuler(drawRuler); 379 } 380 381 public void setDefaultBitmap(Bitmap bitmap) 382 { 383 mScript.set_defaultTexture(allocationFromBitmap(bitmap, MIPMAP)); 384 } 385 386 public void setLoadingBitmap(Bitmap bitmap) 387 { 388 mScript.set_loadingTexture(allocationFromBitmap(bitmap, MIPMAP)); 389 } 390 391 public void setDefaultGeometry(Mesh mesh) 392 { 393 mScript.set_defaultGeometry(mesh); 394 } 395 396 public void setLoadingGeometry(Mesh mesh) 397 { 398 mScript.set_loadingGeometry(mesh); 399 } 400 401 public void setStartAngle(float theta) 402 { 403 mScript.set_startAngle(theta); 404 } 405 406 public void setCallback(CarouselCallback callback) 407 { 408 mCallback = callback; 409 } 410 411 private Allocation allocationFromBitmap(Bitmap bitmap, boolean mipmap) 412 { 413 if (bitmap == null) return null; 414 Allocation allocation = Allocation.createFromBitmap(mRS, bitmap, 415 elementForBitmap(bitmap, Bitmap.Config.ARGB_4444), mipmap); 416 allocation.uploadToTexture(0); 417 return allocation; 418 } 419 420 public void setTexture(int n, Bitmap bitmap) 421 { 422 if (n < 0) throw new IllegalArgumentException("Index cannot be negative"); 423 424 synchronized(this) { 425 ScriptField_Card.Item item = mCards.get(n); 426 if (item == null) { 427 if (DBG) Log.v(TAG, "setTexture(): no item at index " + n); 428 item = new ScriptField_Card.Item(); 429 } 430 if (bitmap != null) { 431 if (DBG) Log.v(TAG, "creating new bitmap"); 432 item.texture = Allocation.createFromBitmap(mRS, bitmap, 433 elementForBitmap(bitmap, Bitmap.Config.ARGB_4444), MIPMAP); 434 if (DBG) Log.v(TAG, "uploadToTexture(" + n + ")"); 435 item.texture.uploadToTexture(0); 436 if (DBG) Log.v(TAG, "done..."); 437 } else { 438 if (item.texture != null) { 439 if (DBG) Log.v(TAG, "unloading texture " + n); 440 // Don't wait for GC to free native memory. 441 // Only works if textures are not shared. 442 item.texture.destroy(); 443 item.texture = null; 444 } 445 } 446 mCards.set(item, n, false); // This is primarily used for reference counting. 447 mScript.invoke_setTexture(n, item.texture); 448 } 449 } 450 451 void setDetailTexture(int n, float offx, float offy, Bitmap bitmap) 452 { 453 if (n < 0) throw new IllegalArgumentException("Index cannot be negative"); 454 455 synchronized(this) { 456 ScriptField_Card.Item item = mCards.get(n); 457 if (item == null) { 458 if (DBG) Log.v(TAG, "setDetailTexture(): no item at index " + n); 459 item = new ScriptField_Card.Item(); 460 } 461 float width = 0.0f; 462 float height = 0.0f; 463 if (bitmap != null) { 464 item.detailTexture = Allocation.createFromBitmap(mRS, bitmap, 465 elementForBitmap(bitmap, Bitmap.Config.ARGB_4444), MIPMAP); 466 item.detailTexture.uploadToTexture(0); 467 width = bitmap.getWidth(); 468 height = bitmap.getHeight(); 469 } else { 470 if (item.detailTexture != null) { 471 if (DBG) Log.v(TAG, "unloading texture " + n); 472 // Don't wait for GC to free native memory. 473 // Only works if textures are not shared. 474 item.detailTexture.destroy(); 475 item.detailTexture = null; 476 } 477 } 478 mCards.set(item, n, false); // This is primarily used for reference counting. 479 mScript.invoke_setDetailTexture(n, offx, offy, item.detailTexture); 480 } 481 } 482 483 public void setGeometry(int n, Mesh geometry) 484 { 485 if (n < 0) throw new IllegalArgumentException("Index cannot be negative"); 486 487 synchronized(this) { 488 final boolean mipmap = false; 489 ScriptField_Card.Item item = mCards.get(n); 490 if (item == null) { 491 if (DBG) Log.v(TAG, "setGeometry(): no item at index " + n); 492 item = new ScriptField_Card.Item(); 493 } 494 if (geometry != null) { 495 item.geometry = geometry; 496 } else { 497 if (DBG) Log.v(TAG, "unloading geometry " + n); 498 if (item.geometry != null) { 499 // item.geometry.destroy(); 500 item.geometry = null; 501 } 502 } 503 mCards.set(item, n, false); 504 mScript.invoke_setGeometry(n, item.geometry); 505 } 506 } 507 508 public void setBackgroundColor(Float4 color) { 509 mScript.set_backgroundColor(color); 510 } 511 512 public void setBackgroundTexture(Bitmap bitmap) { 513 Allocation texture = null; 514 if (bitmap != null) { 515 texture = Allocation.createFromBitmap(mRS, bitmap, 516 elementForBitmap(bitmap, Bitmap.Config.RGB_565), MIPMAP); 517 texture.uploadToTexture(0); 518 } 519 mScript.set_backgroundTexture(texture); 520 } 521 522 public void setDetailLineTexture(Bitmap bitmap) { 523 Allocation texture = null; 524 if (bitmap != null) { 525 texture = Allocation.createFromBitmap(mRS, bitmap, 526 elementForBitmap(bitmap, Bitmap.Config.ARGB_4444), MIPMAP); 527 texture.uploadToTexture(0); 528 } 529 mScript.set_detailLineTexture(texture); 530 } 531 532 public void setDetailLoadingTexture(Bitmap bitmap) { 533 Allocation texture = null; 534 if (bitmap != null) { 535 texture = Allocation.createFromBitmap(mRS, bitmap, 536 elementForBitmap(bitmap, Bitmap.Config.ARGB_4444), MIPMAP); 537 texture.uploadToTexture(0); 538 } 539 mScript.set_detailLoadingTexture(texture); 540 } 541 542 public void pauseRendering() { 543 // Used to update multiple states at once w/o redrawing for each. 544 mRS.contextBindRootScript(null); 545 } 546 547 public void resumeRendering() { 548 mRS.contextBindRootScript(mScript); 549 } 550 551 public void doMotion(float x, float y) { 552 mScript.invoke_doMotion(x,y); 553 } 554 555 public void doSelection(float x, float y) { 556 mScript.invoke_doSelection(x, y); 557 } 558 559 public void doStart(float x, float y) { 560 mScript.invoke_doStart(x, y); 561 } 562 563 public void doStop(float x, float y) { 564 mScript.invoke_doStop(x, y); 565 } 566 567 public void setSlotCount(int n) { 568 mScript.set_slotCount(n); 569 } 570 571 public void requestFirstCardPosition() { 572 mScript.invoke_requestFirstCardPosition(); 573 } 574 575 public void setRezInCardCount(float alpha) { 576 mScript.set_rezInCardCount(alpha); 577 } 578 579 public void setFadeInDuration(long t) { 580 mScript.set_fadeInDuration((int)t); // TODO: Remove cast when RS supports exporting longs 581 } 582 583 private Element elementForBitmap(Bitmap bitmap, Bitmap.Config defaultConfig) { 584 Bitmap.Config config = bitmap.getConfig(); 585 if (config == null) { 586 config = defaultConfig; 587 } 588 if (config == Bitmap.Config.ALPHA_8) { 589 return A_8(mRS); 590 } else if (config == Bitmap.Config.RGB_565) { 591 return RGB_565(mRS); 592 } else if (config == Bitmap.Config.ARGB_4444) { 593 return RGBA_4444(mRS); 594 } else if (config == Bitmap.Config.ARGB_8888) { 595 return RGBA_8888(mRS); 596 } else { 597 throw new IllegalArgumentException("Unknown configuration"); 598 } 599 } 600} 601