Performance improvements: Enable blending only when needed
Never draw the background image with blending.
Draw card images with blending only when requested. By
default, blending is enabled, but [MVC]CarouselView
subclasses can disable it.
Change-Id: Ia66f0fb7df45881481f0b782983402fcecb4a29a
diff --git a/carousel/java/com/android/ex/carousel/CarouselController.java b/carousel/java/com/android/ex/carousel/CarouselController.java
index ca0c5f8..9f3444e 100644
--- a/carousel/java/com/android/ex/carousel/CarouselController.java
+++ b/carousel/java/com/android/ex/carousel/CarouselController.java
@@ -64,6 +64,7 @@
private int mPrefetchCardCount = DEFAULT_PREFETCH_CARD_COUNT;
private boolean mDrawDetailBelowCard = false;
private boolean mDetailTexturesCentered = false;
+ private boolean mDrawCardsWithBlending = true;
private boolean mDrawRuler = true;
private float mStartAngle;
private float mRadius = DEFAULT_RADIUS;
@@ -227,6 +228,20 @@
}
/**
+ * Set whether blending is enabled while drawing the card textures. This should be true when
+ * translucent cards need to be supported, and false when all cards are fully opaque. Setting
+ * to false provides a performance boost.
+ *
+ * @param enabled True to enable blending, and false to disable it.
+ */
+ public void setDrawCardsWithBlending(boolean enabled) {
+ mDrawCardsWithBlending = enabled;
+ if (mRenderScript != null) {
+ mRenderScript.setDrawCardsWithBlending(enabled);
+ }
+ }
+
+ /**
* Set whether to draw a ruler from the card to the detail texture
*
* @param drawRuler True to draw a ruler, false to draw nothing where the ruler would go.
diff --git a/carousel/java/com/android/ex/carousel/CarouselRS.java b/carousel/java/com/android/ex/carousel/CarouselRS.java
index 134057c..dbc543f 100644
--- a/carousel/java/com/android/ex/carousel/CarouselRS.java
+++ b/carousel/java/com/android/ex/carousel/CarouselRS.java
@@ -20,16 +20,9 @@
import android.graphics.Bitmap;
import android.renderscript.*;
import android.renderscript.RenderScript.RSMessage;
-import android.renderscript.Sampler.Value;
-import android.renderscript.ProgramRaster.CullMode;
import android.util.Log;
-import com.android.internal.R;
-
import static android.renderscript.Element.*;
-import static android.renderscript.Sampler.Value.LINEAR;
-import static android.renderscript.Sampler.Value.WRAP;
-import static android.renderscript.Sampler.Value.CLAMP;
/**
* This is a support class for Carousel renderscript. It handles most of the low-level interactions
@@ -65,6 +58,7 @@
private ScriptField_Card mCards;
private ScriptField_FragmentShaderConstants_s mFSConst;
private ProgramStore mProgramStore;
+ private ProgramStore mProgramStoreOpaque;
private ProgramFragment mSingleTextureFragmentProgram;
private ProgramFragment mMultiTextureFragmentProgram;
private ProgramVertex mVertexProgram;
@@ -336,6 +330,11 @@
programStoreBuilder.setDepthMask(true);
mProgramStore = programStoreBuilder.create();
mScript.set_programStore(mProgramStore);
+
+ programStoreBuilder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
+ ProgramStore.BlendDstFunc.ZERO);
+ mProgramStoreOpaque = programStoreBuilder.create();
+ mScript.set_programStoreOpaque(mProgramStoreOpaque);
}
public void createCards(int count)
@@ -381,6 +380,10 @@
mScript.set_detailTexturesCentered(centered);
}
+ public void setDrawCardsWithBlending(boolean enabled) {
+ mScript.set_drawCardsWithBlending(enabled);
+ }
+
public void setDrawRuler(boolean drawRuler) {
mScript.set_drawRuler(drawRuler);
}
diff --git a/carousel/java/com/android/ex/carousel/CarouselView.java b/carousel/java/com/android/ex/carousel/CarouselView.java
index 7eaecec..f4bf569 100644
--- a/carousel/java/com/android/ex/carousel/CarouselView.java
+++ b/carousel/java/com/android/ex/carousel/CarouselView.java
@@ -73,6 +73,7 @@
private int mPrefetchCardCount = DEFAULT_PREFETCH_CARD_COUNT;
private boolean mDrawDetailBelowCard = false;
private boolean mDetailTexturesCentered = false;
+ private boolean mDrawCardsWithBlending = true;
private boolean mDrawRuler = true;
private float mStartAngle;
private float mRadius = DEFAULT_RADIUS;
@@ -287,6 +288,13 @@
}
}
+ public void setDrawCardsWithBlending(boolean enabled) {
+ mDrawCardsWithBlending = enabled;
+ if (mRenderScript != null) {
+ mRenderScript.setDrawCardsWithBlending(enabled);
+ }
+ }
+
/**
* Set whether to draw a ruler from the card to the detail texture
*
diff --git a/carousel/java/com/android/ex/carousel/MVCCarouselView.java b/carousel/java/com/android/ex/carousel/MVCCarouselView.java
index 2f022c1..8368242 100644
--- a/carousel/java/com/android/ex/carousel/MVCCarouselView.java
+++ b/carousel/java/com/android/ex/carousel/MVCCarouselView.java
@@ -217,6 +217,17 @@
}
/**
+ * Set whether blending is enabled while drawing the card textures. This should be true when
+ * translucent cards need to be supported, and false when all cards are fully opaque. Setting
+ * to false provides a performance boost.
+ *
+ * @param enabled True to enable blending, and false to disable it.
+ */
+ public void setDrawCardsWithBlending(boolean enabled) {
+ mController.setDrawCardsWithBlending(enabled);
+ }
+
+ /**
* Set whether to draw a ruler from the card to the detail texture
*
* @param drawRuler True to draw a ruler, false to draw nothing where the ruler would go.
diff --git a/carousel/java/com/android/ex/carousel/carousel.rs b/carousel/java/com/android/ex/carousel/carousel.rs
index 612ba92..7140edd 100644
--- a/carousel/java/com/android/ex/carousel/carousel.rs
+++ b/carousel/java/com/android/ex/carousel/carousel.rs
@@ -103,6 +103,7 @@
bool drawDetailBelowCard; // whether detail goes above (false) or below (true) the card
// TODO(jshuma): Replace detailTexturesCentered with a detailTextureAlignment mode enum
bool detailTexturesCentered; // line up detail center and card center (instead of left edges)
+bool drawCardsWithBlending; // Enable blending while drawing cards (for translucent card textures)
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
@@ -114,6 +115,7 @@
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
rs_program_store programStore;
+rs_program_store programStoreOpaque;
rs_program_fragment singleTextureFragmentProgram;
rs_program_fragment multiTextureFragmentProgram;
rs_program_vertex vertexProgram;
@@ -1226,7 +1228,6 @@
int64_t currentTime = rsUptimeMillis();
rsgBindProgramVertex(vertexProgram);
- rsgBindProgramStore(programStore);
rsgBindProgramRaster(rasterProgram);
rsgBindSampler(singleTextureFragmentProgram, 0, linearClamp);
rsgBindSampler(multiTextureFragmentProgram, 0, linearClamp);
@@ -1246,6 +1247,7 @@
}
rsgBindProgramFragment(singleTextureFragmentProgram);
+ rsgBindProgramStore(programStoreOpaque);
drawBackground();
updateCameraMatrix(rsgGetWidth(), rsgGetHeight());
@@ -1257,8 +1259,17 @@
updateCardResources(currentTime);
- stillAnimating |= drawCards(currentTime);
- stillAnimating |= drawDetails(currentTime);
+ // Draw cards opaque only if requested, and always draw detail textures with blending.
+ if (drawCardsWithBlending) {
+ rsgBindProgramStore(programStore);
+ stillAnimating |= drawCards(currentTime);
+ stillAnimating |= drawDetails(currentTime);
+ } else {
+ // programStoreOpaque is already bound
+ stillAnimating |= drawCards(currentTime);
+ rsgBindProgramStore(programStore);
+ stillAnimating |= drawDetails(currentTime);
+ }
if (debugPicking) {
renderWithRays();