summaryrefslogtreecommitdiffstats
path: root/carousel
diff options
context:
space:
mode:
authorJim Shuma <jshuma@google.com>2010-12-11 18:03:44 -0800
committerJim Shuma <jshuma@google.com>2010-12-14 21:33:08 -0800
commitf664659f79399e92025e1dfe1ffbb682ff05613c (patch)
treee7da57b25273a1d2d8feba8ccf9299427dfc3028 /carousel
parent1a5b4d109397ea175b5cbaa7490ca18e78eb040f (diff)
downloadandroid_frameworks_ex-f664659f79399e92025e1dfe1ffbb682ff05613c.tar.gz
android_frameworks_ex-f664659f79399e92025e1dfe1ffbb682ff05613c.tar.bz2
android_frameworks_ex-f664659f79399e92025e1dfe1ffbb682ff05613c.zip
Allow specifying configurations for mesh primitives
This lets you specify separate alpha, depth read, and depth write behaviors for each primitive in your mesh. It will be used by Books to allow drawing shadows separately from the main model. Change-Id: I9351f720e6e09260b5bcd335e305922ff48cb373
Diffstat (limited to 'carousel')
-rw-r--r--carousel/java/com/android/ex/carousel/CarouselController.java37
-rw-r--r--carousel/java/com/android/ex/carousel/CarouselRS.java137
-rw-r--r--carousel/java/com/android/ex/carousel/carousel.rs69
3 files changed, 185 insertions, 58 deletions
diff --git a/carousel/java/com/android/ex/carousel/CarouselController.java b/carousel/java/com/android/ex/carousel/CarouselController.java
index b722583..fd94a7d 100644
--- a/carousel/java/com/android/ex/carousel/CarouselController.java
+++ b/carousel/java/com/android/ex/carousel/CarouselController.java
@@ -19,9 +19,7 @@ package com.android.ex.carousel;
import com.android.ex.carousel.CarouselRS.CarouselCallback;
import com.android.ex.carousel.CarouselView.DetailAlignment;
-import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.renderscript.FileA3D;
import android.renderscript.Float4;
import android.renderscript.Mesh;
import android.renderscript.RenderScriptGL;
@@ -724,4 +722,39 @@ public class CarouselController {
public void onTouchStopped(float x, float y, long t) {
mRenderScript.doStop(x, y, t);
}
+
+ /**
+ * Whether to use alpha when drawing a primitive: on for translucent, off for opaque.
+ */
+ public static final int STORE_CONFIG_ALPHA = 1;
+
+ /**
+ * Whether to read from the depth buffer when rendering. Determines with glDepthFunc()
+ * is given GL_LESS or GL_ALWAYS. On for GL_LESS, off for GL_ALWAYS.
+ */
+ public static final int STORE_CONFIG_DEPTH_READS = 2;
+
+ /**
+ * Whether to write to the depth buffer when rendering. Passed to glDepthMask().
+ */
+ public static final int STORE_CONFIG_DEPTH_WRITES = 4;
+
+ /**
+ * Set the StoreConfig parameters that will be used for each mesh primitive.
+ *
+ * Each integer in the array is a bitfield composed of
+ * {@link CarouselController#STORE_CONFIG_ALPHA},
+ * {@link CarouselController#STORE_CONFIG_DEPTH_READS}, and
+ * {@link CarouselController#STORE_CONFIG_DEPTH_WRITES}.
+ *
+ * These parameters MUST correspond to primitives in geometry previously set in
+ * {@link CarouselController#setDefaultGeometry(int)} or
+ * {@link CarouselController#setLoadingGeometry(int)} or
+ * {@link CarouselController#setGeometryForItem(int,Mesh)}.
+ *
+ * @param configs An array, each element of which corresponds to an ordered mesh primitive
+ */
+ public void setStoreConfigs(int configs[]) {
+ mRenderScript.setStoreConfigs(configs);
+ }
}
diff --git a/carousel/java/com/android/ex/carousel/CarouselRS.java b/carousel/java/com/android/ex/carousel/CarouselRS.java
index ea4be35..4b41d7c 100644
--- a/carousel/java/com/android/ex/carousel/CarouselRS.java
+++ b/carousel/java/com/android/ex/carousel/CarouselRS.java
@@ -68,15 +68,13 @@ public class CarouselRS {
private ScriptC_carousel mScript;
private ScriptField_Card mCards;
private ScriptField_FragmentShaderConstants_s mFSConst;
- private ProgramStore mProgramStoreAlphaZ;
- private ProgramStore mProgramStoreAlphaNoZ;
- private ProgramStore mProgramStoreNoAlphaZ;
- private ProgramStore mProgramStoreNoAlphaNoZ;
+ private ScriptField_ProgramStore_s mProgramStoresCard;
private ProgramFragment mSingleTextureFragmentProgram;
private ProgramFragment mMultiTextureFragmentProgram;
private ProgramVertex mVertexProgram;
private ProgramRaster mRasterProgram;
private Allocation[] mAllocationPool;
+ private boolean mForceBlendCardsWithZ;
private int mVisibleSlots;
private int mRowCount;
private int mPrefetchCardCount;
@@ -379,40 +377,37 @@ public class CarouselRS {
}
private void initProgramStore() {
+ resizeProgramStoresCard(1);
+
final boolean dither = true;
- mProgramStoreAlphaZ = new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
- ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
- .setDitherEnable(dither)
- .setDepthFunc(ProgramStore.DepthFunc.LESS)
- .setDepthMask(true)
- .create();
- mScript.set_programStoreAlphaZ(mProgramStoreAlphaZ);
-
- mProgramStoreAlphaNoZ = new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
- ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
- .setDitherEnable(dither)
- .setDepthFunc(ProgramStore.DepthFunc.ALWAYS)
- .setDepthMask(false)
- .create();
- mScript.set_programStoreAlphaNoZ(mProgramStoreAlphaNoZ);
-
- mProgramStoreNoAlphaZ = new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ZERO)
- .setDitherEnable(dither)
- .setDepthFunc(ProgramStore.DepthFunc.LESS)
- .setDepthMask(true)
- .create();
- mScript.set_programStoreNoAlphaZ(mProgramStoreNoAlphaZ);
-
- mProgramStoreNoAlphaNoZ = new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ZERO)
- .setDitherEnable(dither)
- .setDepthFunc(ProgramStore.DepthFunc.ALWAYS)
- .setDepthMask(false)
- .create();
- mScript.set_programStoreNoAlphaNoZ(mProgramStoreNoAlphaNoZ);
+ final ProgramStore.DepthFunc depthFunc = mForceBlendCardsWithZ ?
+ ProgramStore.DepthFunc.LESS : ProgramStore.DepthFunc.ALWAYS;
+
+ // Background: Alpha disabled, depth optional
+ mScript.set_programStoreBackground(new ProgramStore.Builder(mRS)
+ .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ZERO)
+ .setDitherEnable(dither)
+ .setDepthFunc(depthFunc)
+ .setDepthMask(mForceBlendCardsWithZ)
+ .create());
+
+ // Card: Alpha enabled, depth optional
+ setProgramStoreCard(0, new ProgramStore.Builder(mRS)
+ .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
+ ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
+ .setDitherEnable(dither)
+ .setDepthFunc(depthFunc)
+ .setDepthMask(mForceBlendCardsWithZ)
+ .create());
+
+ // Detail: Alpha enabled, depth disabled
+ mScript.set_programStoreDetail(new ProgramStore.Builder(mRS)
+ .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
+ ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
+ .setDitherEnable(dither)
+ .setDepthFunc(ProgramStore.DepthFunc.ALWAYS)
+ .setDepthMask(false)
+ .create());
}
public void createCards(int count)
@@ -466,8 +461,74 @@ public class CarouselRS {
mScript.set_detailTextureAlignment(alignment);
}
+ private void resizeProgramStoresCard(int count) {
+ // enableResize works around a Renderscript bug that keeps resizes from being propagated.
+ // TODO(jshuma): Remove enableResize once the Renderscript bug is fixed
+ final boolean enableResize = false;
+
+ if (mProgramStoresCard != null && enableResize) {
+ int newSize = count > 0 ? count : 1;
+ mProgramStoresCard.resize(newSize);
+ } else {
+ mProgramStoresCard = new ScriptField_ProgramStore_s(mRS, count > 0 ? count : 1);
+ mScript.bind_programStoresCard(mProgramStoresCard);
+ }
+ }
+
+ private void setProgramStoreCard(int n, ProgramStore programStore) {
+ ScriptField_ProgramStore_s.Item item = mProgramStoresCard.get(n);
+ if (item == null) {
+ item = new ScriptField_ProgramStore_s.Item();
+ }
+ item.programStore = programStore;
+ mProgramStoresCard.set(item, n, false);
+ mScript.invoke_setProgramStoresCard(n, programStore);
+ }
+
+ public void setStoreConfigs(int configs[]) {
+ final int count = configs.length;
+
+ resizeProgramStoresCard(count);
+ for (int i=0; i<count; ++i) {
+ final int config = configs[i];
+
+ final boolean alpha = (config & CarouselController.STORE_CONFIG_ALPHA) != 0;
+ final boolean depthReads = (config & CarouselController.STORE_CONFIG_DEPTH_READS) != 0;
+ final boolean depthWrites =
+ (config & CarouselController.STORE_CONFIG_DEPTH_WRITES) != 0;
+
+ final boolean dither = true;
+ final ProgramStore.BlendDstFunc dstFunc = alpha ?
+ ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA :
+ ProgramStore.BlendDstFunc.ZERO;
+ final ProgramStore.DepthFunc depthFunc = depthReads ?
+ ProgramStore.DepthFunc.LESS :
+ ProgramStore.DepthFunc.ALWAYS;
+
+ final ProgramStore ps = new ProgramStore.Builder(mRS)
+ .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, dstFunc)
+ .setDitherEnable(dither)
+ .setDepthFunc(depthFunc)
+ .setDepthMask(depthWrites)
+ .create();
+
+ setProgramStoreCard(i, ps);
+ }
+ }
+
+ /**
+ * Sets whether the background texture and default card geometry are to be drawn with respect
+ * to the depth buffer (both reading from it and writing to it).
+ *
+ * This method is a specialization of functionality that can be done with greater flexibility
+ * by setStoreConfigs. Calling setForceBlendCardsWithZ() after calling setStoreConfigs()
+ * results in the values set in setStoreConfigs() being discarded.
+ *
+ * @param enabled true to read from and write to the depth buffer, false to ignore it
+ */
public void setForceBlendCardsWithZ(boolean enabled) {
- mScript.set_forceBlendCardsWithZ(enabled);
+ mForceBlendCardsWithZ = enabled;
+ initProgramStore();
}
public void setDrawRuler(boolean drawRuler) {
diff --git a/carousel/java/com/android/ex/carousel/carousel.rs b/carousel/java/com/android/ex/carousel/carousel.rs
index e35cc1a..4de05d9 100644
--- a/carousel/java/com/android/ex/carousel/carousel.rs
+++ b/carousel/java/com/android/ex/carousel/carousel.rs
@@ -64,6 +64,10 @@ typedef struct PerspectiveCamera_s {
float far;
} PerspectiveCamera;
+typedef struct ProgramStore_s {
+ rs_program_store programStore;
+} ProgramStore_t;
+
typedef struct FragmentShaderConstants_s {
float fadeAmount;
} FragmentShaderConstants;
@@ -153,11 +157,11 @@ Card_t *cards; // array of cards to draw
float startAngle; // position of initial card, in radians
int slotCount; // number of positions where a card can be
int cardCount; // number of cards in stack
+int programStoresCardCount; // number of program fragment stores
int visibleSlotCount; // number of visible slots (for culling)
int visibleDetailCount; // number of visible detail textures to show
int prefetchCardCount; // how many cards to keep in memory
int detailTextureAlignment; // How to align detail texture with respect to card
-bool forceBlendCardsWithZ; // Enable depth buffer while blending
bool drawRuler; // whether to draw a ruler from the card to the detail texture
float radius; // carousel radius. Cards will be centered on a circle with this radius
float cardRotation; // rotation of card in XY plane relative to Z=1
@@ -175,10 +179,9 @@ bool firstCardTop; // set true for first card on top row when multiple rows used
int dragModel = DRAG_MODEL_SCREEN_DELTA;
int fillDirection; // the order in which to lay out cards: +1 for CCW (default), -1 for CW
-rs_program_store programStoreAlphaZ;
-rs_program_store programStoreAlphaNoZ;
-rs_program_store programStoreNoAlphaZ;
-rs_program_store programStoreNoAlphaNoZ;
+ProgramStore_t *programStoresCard;
+rs_program_store programStoreBackground;
+rs_program_store programStoreDetail;
rs_program_fragment singleTextureFragmentProgram;
rs_program_fragment multiTextureFragmentProgram;
rs_program_vertex vertexProgram;
@@ -224,9 +227,10 @@ static Cylinder carouselCylinder = {
};
// Because allocations can't have 0 dimensions, we have to track whether or not
-// cards are valid separately.
+// cards and program stores are valid separately.
// TODO: Remove this dependency once allocations can have a zero dimension.
static bool cardAllocationValid = false;
+static bool programStoresAllocationValid = false;
// Default geometry when card.geometry is not set.
static const float3 cardVertices[4] = {
@@ -273,6 +277,7 @@ void init() {
updateCamera = true;
backgroundColor = (float4) { 0.0f, 0.0f, 0.0f, 1.0f };
cardAllocationValid = false;
+ programStoresAllocationValid = false;
cardCount = 0;
rowCount = 1;
rowSpacing = 0.0f;
@@ -283,12 +288,18 @@ void init() {
rsMatrixLoadIdentity(&defaultCardMatrix);
}
-static void updateAllocationVars(Card_t* newcards)
+static void updateAllocationVars()
{
// Cards
rs_allocation cardAlloc;
- rsSetObject(&cardAlloc, rsGetAllocation(newcards));
+ rsSetObject(&cardAlloc, rsGetAllocation(cards));
cardCount = (cardAllocationValid && rsIsObject(cardAlloc)) ? rsAllocationGetDimX(cardAlloc) : 0;
+
+ // Program stores
+ rs_allocation psAlloc;
+ rsSetObject(&psAlloc, rsGetAllocation(programStoresCard));
+ programStoresCardCount = (programStoresAllocationValid && rsIsObject(psAlloc) ?
+ rsAllocationGetDimX(psAlloc) : 0);
}
void setRadius(float rad)
@@ -505,6 +516,12 @@ void setGeometry(int n, rs_mesh geometry)
cards[n].geometryState = STATE_INVALID;
}
+void setProgramStoresCard(int n, rs_program_store programStore)
+{
+ rsSetObject(&programStoresCard[n].programStore, programStore);
+ programStoresAllocationValid = true;
+}
+
void setCarouselRotationAngle(float carouselRotationAngle) {
bias = carouselRotationAngleToRadians(carouselRotationAngle);
}
@@ -592,6 +609,26 @@ static bool getMatrixForCard(rs_matrix4x4* matrix, int i, bool enableSway)
}
/*
+ * Draws the requested mesh, with the appropriate program store in effect.
+ */
+static void drawMesh(rs_mesh mesh)
+{
+ if (programStoresCardCount == 1) {
+ // Draw the entire mesh, with the only available program store
+ rsgBindProgramStore(programStoresCard[0].programStore);
+ rsgDrawMesh(mesh);
+ } else {
+ // Draw each primitive in the mesh with the corresponding program store
+ for (int i=0; i<programStoresCardCount; ++i) {
+ if (programStoresCard[i].programStore.p != 0) {
+ rsgBindProgramStore(programStoresCard[i].programStore);
+ rsgDrawMesh(mesh, i);
+ }
+ }
+ }
+}
+
+/*
* Draws cards around the Carousel.
* Returns true if we're still animating any property of the cards (e.g. fades).
*/
@@ -643,13 +680,14 @@ static bool drawCards(int64_t currentTime)
stillAnimating |= getMatrixForCard(&matrix, i, true);
rsgProgramVertexLoadModelMatrix(&matrix);
if (cards[i].geometryState == STATE_LOADED && cards[i].geometry.p != 0) {
- rsgDrawMesh(cards[i].geometry);
+ drawMesh(cards[i].geometry);
} else if (cards[i].geometryState == STATE_LOADING && loadingGeometry.p != 0) {
- rsgDrawMesh(loadingGeometry);
+ drawMesh(loadingGeometry);
} else if (defaultGeometry.p != 0) {
- rsgDrawMesh(defaultGeometry);
+ drawMesh(defaultGeometry);
} else {
// Draw place-holder geometry
+ rsgBindProgramStore(programStoresCard[0].programStore);
rsgDrawQuad(
cardVertices[0].x, cardVertices[0].y, cardVertices[0].z,
cardVertices[1].x, cardVertices[1].y, cardVertices[1].z,
@@ -1565,7 +1603,7 @@ int root() {
// the mask is disabled. We may want to change the following to always draw w/o Z for
// the background if we can guarantee the depth buffer will get cleared and
// there's a performance advantage.
- rsgBindProgramStore(forceBlendCardsWithZ ? programStoreNoAlphaZ : programStoreNoAlphaNoZ);
+ rsgBindProgramStore(programStoreBackground);
drawBackground();
updateCameraMatrix(rsgGetWidth(), rsgGetHeight());
@@ -1583,13 +1621,8 @@ int root() {
updateCardResources(currentTime);
// Draw cards opaque only if requested, and always draw detail textures with blending.
- if (forceBlendCardsWithZ) {
- rsgBindProgramStore(programStoreAlphaZ);
- } else {
- rsgBindProgramStore(programStoreAlphaNoZ);
- }
stillAnimating |= drawCards(currentTime);
- rsgBindProgramStore(programStoreAlphaNoZ);
+ rsgBindProgramStore(programStoreDetail);
stillAnimating |= drawDetails(currentTime);
if (stillAnimating != animating) {