summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Romain Guy <romainguy@google.com> 2012-08-29 21:49:00 -0700
committer Romain Guy <romainguy@google.com> 2012-08-29 21:56:18 -0700
commitd679b57ef279239cf11bb6c9bd14fb99b07971c9 (patch)
tree8755627bed9d9ffc8045cdd06e54d729f6cab5f3
parent2c577f1777a9227c581d41d5c08d674740e39ea9 (diff)
Pre-multiply color components for 2-stop gradients
Bug #7033344 Change-Id: Ia168501f1dc56ba7a1bb0c55078320432309a66a
-rw-r--r--core/java/android/view/View.java22
-rw-r--r--libs/hwui/GradientCache.cpp10
-rw-r--r--libs/hwui/SkiaShader.cpp35
-rw-r--r--libs/hwui/SkiaShader.h7
4 files changed, 24 insertions, 50 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b1f5e9e58d36..b8db585c27bb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17610,23 +17610,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// use use a height of 1, and then wack the matrix each time we
// actually use it.
shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
-
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+
this.host = host;
}
public void setFadeColor(int color) {
- if (color != 0 && color != mLastColor) {
+ if (color != mLastColor) {
mLastColor = color;
- color |= 0xFF000000;
-
- shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
- color & 0x00FFFFFF, Shader.TileMode.CLAMP);
- paint.setShader(shader);
- // Restore the default transfer mode (src_over)
- paint.setXfermode(null);
+ if (color != 0) {
+ shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
+ color & 0x00FFFFFF, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ // Restore the default transfer mode (src_over)
+ paint.setXfermode(null);
+ } else {
+ shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+ }
}
}
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 726b57c792bb..2e4e3492df03 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -217,10 +217,12 @@ void GradientCache::generateTexture(uint32_t* colors, float* positions,
float amount = (pos - start) / distance;
float oppAmount = 1.0f - amount;
- *p++ = uint8_t(startR * oppAmount + endR * amount);
- *p++ = uint8_t(startG * oppAmount + endG * amount);
- *p++ = uint8_t(startB * oppAmount + endB * amount);
- *p++ = uint8_t(startA * oppAmount + endA * amount);
+ const float alpha = startA * oppAmount + endA * amount;
+ const float a = alpha / 255.0f;
+ *p++ = uint8_t(a * (startR * oppAmount + endR * amount));
+ *p++ = uint8_t(a * (startG * oppAmount + endG * amount));
+ *p++ = uint8_t(a * (startB * oppAmount + endB * amount));
+ *p++ = uint8_t(alpha);
}
for (int i = 1; i < GRADIENT_TEXTURE_HEIGHT; i++) {
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 8916efd0f75b..9013fd5f9fed 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -46,11 +46,12 @@ static inline bool isPowerOfTwo(unsigned int n) {
}
static inline void bindUniformColor(int slot, uint32_t color) {
+ const float a = ((color >> 24) & 0xff) / 255.0f;
glUniform4f(slot,
- ((color >> 16) & 0xff) / 255.0f,
- ((color >> 8) & 0xff) / 255.0f,
- ((color ) & 0xff) / 255.0f,
- ((color >> 24) & 0xff) / 255.0f);
+ a * ((color >> 16) & 0xff) / 255.0f,
+ a * ((color >> 8) & 0xff) / 255.0f,
+ a * ((color ) & 0xff) / 255.0f,
+ a);
}
///////////////////////////////////////////////////////////////////////////////
@@ -154,10 +155,6 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
// Uniforms
bindTexture(texture, mWrapS, mWrapT);
- // Assume linear here; we should really check the transform in
- // ::updateTransforms() but we don't have the texture object
- // available at that point. The optimization is not worth the
- // effort for now.
texture->setFilter(GL_LINEAR);
glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
@@ -166,14 +163,6 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height);
}
-void SkiaBitmapShader::updateTransforms(Program* program, const mat4& modelView,
- const Snapshot& snapshot) {
- mat4 textureTransform;
- computeScreenSpaceMatrix(textureTransform, modelView);
- glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
- GL_FALSE, &textureTransform.data[0]);
-}
-
///////////////////////////////////////////////////////////////////////////////
// Linear gradient shader
///////////////////////////////////////////////////////////////////////////////
@@ -257,13 +246,6 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
}
-void SkiaLinearGradientShader::updateTransforms(Program* program, const mat4& modelView,
- const Snapshot& snapshot) {
- mat4 screenSpace;
- computeScreenSpaceMatrix(screenSpace, modelView);
- glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
-}
-
///////////////////////////////////////////////////////////////////////////////
// Circular gradient shader
///////////////////////////////////////////////////////////////////////////////
@@ -384,13 +366,6 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
}
-void SkiaSweepGradientShader::updateTransforms(Program* program, const mat4& modelView,
- const Snapshot& snapshot) {
- mat4 screenSpace;
- computeScreenSpaceMatrix(screenSpace, modelView);
- glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
-}
-
///////////////////////////////////////////////////////////////////////////////
// Compose shader
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index a710b8602f8f..26875928cf98 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -82,10 +82,6 @@ struct SkiaShader {
mGradientCache = gradientCache;
}
- virtual void updateTransforms(Program* program, const mat4& modelView,
- const Snapshot& snapshot) {
- }
-
uint32_t getGenerationId() {
return mGenerationId;
}
@@ -148,7 +144,6 @@ struct SkiaBitmapShader: public SkiaShader {
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
GLuint* textureUnit);
- void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
private:
SkiaBitmapShader() {
@@ -172,7 +167,6 @@ struct SkiaLinearGradientShader: public SkiaShader {
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
GLuint* textureUnit);
- void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
private:
SkiaLinearGradientShader() {
@@ -197,7 +191,6 @@ struct SkiaSweepGradientShader: public SkiaShader {
virtual void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
GLuint* textureUnit);
- void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
protected:
SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,