diff options
| author | Jim Shuma <jshuma@google.com> | 2010-12-16 19:26:16 -0800 |
|---|---|---|
| committer | Jim Shuma <jshuma@google.com> | 2010-12-16 20:03:05 -0800 |
| commit | 3adf712e636f67265da7a6ff425c87e63fc20884 (patch) | |
| tree | 378166e11d32d364051f2610fda4d1e28b611062 /carousel | |
| parent | 77bf0562976f0571861012c8506517914efa2bbe (diff) | |
| download | android_frameworks_ex-3adf712e636f67265da7a6ff425c87e63fc20884.tar.gz android_frameworks_ex-3adf712e636f67265da7a6ff425c87e63fc20884.tar.bz2 android_frameworks_ex-3adf712e636f67265da7a6ff425c87e63fc20884.zip | |
Allow fading of the entire card
Give cards an overall timestamp, separate from the texture
timestamp. This allows cards to fade in before their
texture has been set.
Bug: 3281327
Change-Id: I9405636ebcbfc2c27d777d435f3abf24265dfbe9
Diffstat (limited to 'carousel')
3 files changed, 115 insertions, 17 deletions
diff --git a/carousel/java/com/android/ex/carousel/CarouselController.java b/carousel/java/com/android/ex/carousel/CarouselController.java index 762fa58..4b774aa 100644 --- a/carousel/java/com/android/ex/carousel/CarouselController.java +++ b/carousel/java/com/android/ex/carousel/CarouselController.java @@ -85,6 +85,7 @@ public class CarouselController { private CarouselCallback mCarouselCallback; private float mRezInCardCount = 0.0f; private long mFadeInDuration = 250L; + private long mCardCreationFadeDuration = 0L; private Bitmap mDetailLoadingBitmap = Bitmap.createBitmap( new int[] {0}, 0, 1, 1, 1, Bitmap.Config.ARGB_4444); private int mDragModel = CarouselRS.DRAG_MODEL_SCREEN_DELTA; @@ -136,6 +137,7 @@ public class CarouselController { setLookAt(mEye, mAt, mUp); setRezInCardCount(mRezInCardCount); setFadeInDuration(mFadeInDuration); + setCardCreationFadeDuration(mCardCreationFadeDuration); setDetailLoadingBitmap(mDetailLoadingBitmap); setStoreConfigs(mStoreConfigs); } @@ -679,7 +681,7 @@ public class CarouselController { * until all of the cards have faded in. Note: using large values will extend the * animation until all cards have faded in. * - * @param t + * @param t The time, in milliseconds */ public void setFadeInDuration(long t) { mFadeInDuration = t; @@ -689,6 +691,19 @@ public class CarouselController { } /** + * This sets the duration (in ms) that a card takes to fade in when it is initially created, + * such as when it is added or when the application starts. The timer starts at the moment + * when the card is first created. Replacing a card's contents does not affect the timer. + * @param t The time, in milliseconds + */ + public void setCardCreationFadeDuration(long t) { + mCardCreationFadeDuration = t; + if (mRenderScript != null) { + mRenderScript.setCardCreationFadeDuration(t); + } + } + + /** * Tells the carousel that a touch event has started at the designated location. * @param x The number of pixels from the left edge that the event occurred * @param y The number of pixels from the top edge that the event occurred diff --git a/carousel/java/com/android/ex/carousel/CarouselRS.java b/carousel/java/com/android/ex/carousel/CarouselRS.java index fca1791..a9dfc89 100644 --- a/carousel/java/com/android/ex/carousel/CarouselRS.java +++ b/carousel/java/com/android/ex/carousel/CarouselRS.java @@ -71,7 +71,9 @@ public class CarouselRS { private ScriptField_FragmentShaderConstants_s mFSConst; private ScriptField_ProgramStore_s mProgramStoresCard; private ProgramFragment mSingleTextureFragmentProgram; + private ProgramFragment mSingleTextureBlendingFragmentProgram; private ProgramFragment mMultiTextureFragmentProgram; + private ProgramFragment mMultiTextureBlendingFragmentProgram; private ProgramVertex mVertexProgram; private ProgramRaster mRasterProgram; private Allocation[] mAllocationPool; @@ -92,6 +94,14 @@ public class CarouselRS { "gl_FragColor = col; " + "}"); + private static final String mSingleTextureBlendingShader = new String( + "varying vec2 varTex0;" + + "void main() {" + + "vec2 t0 = varTex0.xy;" + + "vec4 col = texture2D(UNI_Tex0, t0);" + + "gl_FragColor = col * UNI_overallAlpha; " + + "}"); + private static final String mMultiTextureShader = new String( "varying vec2 varTex0;" + "void main() {" + @@ -100,6 +110,16 @@ public class CarouselRS { "vec4 col2 = texture2D(UNI_Tex1, t0);" + "gl_FragColor = mix(col, col2, UNI_fadeAmount);}"); + private static final String mMultiTextureBlendingShader = new String( + "varying vec2 varTex0;" + + "void main() {" + + "vec2 t0 = varTex0.xy;" + + "vec4 col = texture2D(UNI_Tex0, t0);" + + "vec4 col2 = texture2D(UNI_Tex1, t0);" + + "gl_FragColor = mix(col, col2, UNI_fadeAmount) * UNI_overallAlpha;" + + "}" + ); + public static interface CarouselCallback { /** * Called when a card is selected @@ -355,10 +375,25 @@ public class CarouselRS { mSingleTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); // - // Multi texture program + // Single texture program, plus blending // mFSConst = new ScriptField_FragmentShaderConstants_s(mRS, 1); mScript.bind_shaderConstants(mFSConst); + ProgramFragment.ShaderBuilder pfbSingleBlend = new ProgramFragment.ShaderBuilder(mRS); + // Specify the resource that contains the shader string + pfbSingleBlend.setShader(mSingleTextureBlendingShader); + // Tell the builder how many textures we have + pfbSingleBlend.setTextureCount(1); + // Define the constant input layout + pfbSingleBlend.addConstant(mFSConst.getAllocation().getType()); + mSingleTextureBlendingFragmentProgram = pfbSingleBlend.create(); + // Bind the source of constant data + mSingleTextureBlendingFragmentProgram.bindConstants(mFSConst.getAllocation(), 0); + mSingleTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); + + // + // Multi texture program + // ProgramFragment.ShaderBuilder pfbMulti = new ProgramFragment.ShaderBuilder(mRS); // Specify the resource that contains the shader string pfbMulti.setShader(mMultiTextureShader); @@ -372,9 +407,27 @@ public class CarouselRS { mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 1); + // + // Multi texture program, plus blending + // + ProgramFragment.ShaderBuilder pfbMultiBlend = new ProgramFragment.ShaderBuilder(mRS); + // Specify the resource that contains the shader string + pfbMultiBlend.setShader(mMultiTextureBlendingShader); + // Tell the builder how many textures we have + pfbMultiBlend.setTextureCount(2); + // Define the constant input layout + pfbMultiBlend.addConstant(mFSConst.getAllocation().getType()); + mMultiTextureBlendingFragmentProgram = pfbMultiBlend.create(); + // Bind the source of constant data + mMultiTextureBlendingFragmentProgram.bindConstants(mFSConst.getAllocation(), 0); + mMultiTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); + mMultiTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 1); + mScript.set_linearClamp(Sampler.CLAMP_LINEAR(mRS)); mScript.set_singleTextureFragmentProgram(mSingleTextureFragmentProgram); + mScript.set_singleTextureBlendingFragmentProgram(mSingleTextureBlendingFragmentProgram); mScript.set_multiTextureFragmentProgram(mMultiTextureFragmentProgram); + mScript.set_multiTextureBlendingFragmentProgram(mMultiTextureBlendingFragmentProgram); } private void initProgramStore() { @@ -801,6 +854,10 @@ public class CarouselRS { mScript.set_fadeInDuration((int)t); // TODO: Remove cast when RS supports exporting longs } + public void setCardCreationFadeDuration(long t) { + mScript.set_cardCreationFadeDuration((int)t); + } + private Element elementForBitmap(Bitmap bitmap, Bitmap.Config defaultConfig) { Bitmap.Config config = bitmap.getConfig(); if (config == null) { diff --git a/carousel/java/com/android/ex/carousel/carousel.rs b/carousel/java/com/android/ex/carousel/carousel.rs index 4de05d9..5c9ae5b 100644 --- a/carousel/java/com/android/ex/carousel/carousel.rs +++ b/carousel/java/com/android/ex/carousel/carousel.rs @@ -34,8 +34,9 @@ typedef struct __attribute__((aligned(4))) Card { int geometryState; // whether or not geometry is loaded int cardVisible; // not bool because of packing bug? int detailVisible; // not bool because of packing bug? - int64_t textureTimeStamp; // time when this texture was last updated, in seconds - int64_t detailTextureTimeStamp; // time when this texture was last updated, in seconds + int64_t textureTimeStamp; // time when this texture was last updated, in ms + int64_t detailTextureTimeStamp; // time when this texture was last updated, in ms + int64_t geometryTimeStamp; // time when the card itself was last updated, in ms } Card_t; typedef struct Ray_s { @@ -70,6 +71,7 @@ typedef struct ProgramStore_s { typedef struct FragmentShaderConstants_s { float fadeAmount; + float overallAlpha; } FragmentShaderConstants; // Request states. Used for loading 3D object properties from the Java client. @@ -170,6 +172,7 @@ float swaySensitivity; // how much to rotate cards in relation to the rotation v float frictionCoeff; // how much to slow down the carousel over time float dragFactor; // a scale factor for how sensitive the carousel is to user dragging int fadeInDuration; // amount of time (in ms) for smoothly switching out textures +int cardCreationFadeDuration; // amount of time (in ms) to fade while initially showing a card float rezInCardCount; // this controls how rapidly distant card textures will be rez-ed in float detailFadeRate; // rate at which details fade as they move into the distance float4 backgroundColor; @@ -183,7 +186,9 @@ ProgramStore_t *programStoresCard; rs_program_store programStoreBackground; rs_program_store programStoreDetail; rs_program_fragment singleTextureFragmentProgram; +rs_program_fragment singleTextureBlendingFragmentProgram; rs_program_fragment multiTextureFragmentProgram; +rs_program_fragment multiTextureBlendingFragmentProgram; rs_program_vertex vertexProgram; rs_program_raster rasterProgram; rs_allocation defaultTexture; // shown when no other texture is assigned @@ -321,6 +326,7 @@ static void initCard(Card_t* card) card->detailVisible = false; card->textureTimeStamp = 0; card->detailTextureTimeStamp = 0; + card->geometryTimeStamp = rsUptimeMillis(); } void createCards(int start, int total) @@ -343,10 +349,10 @@ void createCards(int start, int total) } // Computes an alpha value for a card using elapsed time and constant fadeInDuration -static float getAnimatedAlpha(int64_t startTime, int64_t currentTime) +static float getAnimatedAlpha(int64_t startTime, int64_t currentTime, int64_t duration) { double timeElapsed = (double) (currentTime - startTime); // in ms - double alpha = (double) timeElapsed / fadeInDuration; + double alpha = duration > 0 ? (double) timeElapsed / duration : 1.0; return min(1.0f, (float) alpha); } @@ -514,6 +520,7 @@ void setGeometry(int n, rs_mesh geometry) cards[n].geometryState = STATE_LOADED; else cards[n].geometryState = STATE_INVALID; + cards[n].geometryTimeStamp = rsUptimeMillis(); } void setProgramStoresCard(int n, rs_program_store programStore) @@ -640,8 +647,11 @@ static bool drawCards(int64_t currentTime) for (int i = cardCount-1; i >= 0; i--) { if (cards[i].cardVisible) { // If this card was recently loaded, this will be < 1.0f until the animation completes - float animatedAlpha = getAnimatedAlpha(cards[i].textureTimeStamp, currentTime); - if (animatedAlpha < 1.0f) { + float animatedAlpha = getAnimatedAlpha(cards[i].textureTimeStamp, currentTime, + fadeInDuration); + float overallAlpha = getAnimatedAlpha(cards[i].geometryTimeStamp, currentTime, + cardCreationFadeDuration); + if (animatedAlpha < 1.0f || overallAlpha < 1.0f) { stillAnimating = true; } @@ -656,6 +666,7 @@ static bool drawCards(int64_t currentTime) // Set alpha for blending between the textures shaderConstants->fadeAmount = min(1.0f, animatedAlpha * positionAlpha); + shaderConstants->overallAlpha = overallAlpha; rsAllocationMarkDirty(rsGetAllocation(shaderConstants)); // Bind the appropriate shader network. If there's no alpha blend, then @@ -664,15 +675,29 @@ static bool drawCards(int64_t currentTime) const bool loaded = (state == STATE_LOADED) || (state == STATE_STALE) || (state == STATE_UPDATING); if (shaderConstants->fadeAmount == 1.0f || shaderConstants->fadeAmount < 0.01f) { - rsgBindProgramFragment(singleTextureFragmentProgram); - rsgBindTexture(singleTextureFragmentProgram, 0, - (loaded && shaderConstants->fadeAmount == 1.0f) ? - cards[i].texture : loadingTexture); + if (overallAlpha < 1.0) { + rsgBindProgramFragment(singleTextureBlendingFragmentProgram); + rsgBindTexture(singleTextureBlendingFragmentProgram, 0, + (loaded && shaderConstants->fadeAmount == 1.0f) ? + cards[i].texture : loadingTexture); + } else { + rsgBindProgramFragment(singleTextureFragmentProgram); + rsgBindTexture(singleTextureFragmentProgram, 0, + (loaded && shaderConstants->fadeAmount == 1.0f) ? + cards[i].texture : loadingTexture); + } } else { - rsgBindProgramFragment(multiTextureFragmentProgram); - rsgBindTexture(multiTextureFragmentProgram, 0, loadingTexture); - rsgBindTexture(multiTextureFragmentProgram, 1, loaded ? - cards[i].texture : loadingTexture); + if (overallAlpha < 1.0) { + rsgBindProgramFragment(multiTextureBlendingFragmentProgram); + rsgBindTexture(multiTextureBlendingFragmentProgram, 0, loadingTexture); + rsgBindTexture(multiTextureBlendingFragmentProgram, 1, loaded ? + cards[i].texture : loadingTexture); + } else { + rsgBindProgramFragment(multiTextureFragmentProgram); + rsgBindTexture(multiTextureFragmentProgram, 0, loadingTexture); + rsgBindTexture(multiTextureFragmentProgram, 1, loaded ? + cards[i].texture : loadingTexture); + } } // Draw geometry @@ -815,7 +840,8 @@ static bool drawDetails(int64_t currentTime) // Compute alpha for gradually fading in details. Applied to both line and // detail texture. TODO: use a separate background texture for line. - float animatedAlpha = getAnimatedAlpha(cards[i].detailTextureTimeStamp, currentTime); + float animatedAlpha = getAnimatedAlpha(cards[i].detailTextureTimeStamp, + currentTime, fadeInDuration); if (animatedAlpha < 1.0f) { stillAnimating = true; } |
