summaryrefslogtreecommitdiffstats
path: root/libs/hwui/SkiaShader.cpp
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2010-10-06 16:57:29 -0700
committerRomain Guy <romainguy@google.com>2010-10-06 16:57:29 -0700
commite3095e0c1e2a4a4f34f741aa386eae56536ca5aa (patch)
tree6d2d7c5929bf73af2b0eeb07e757944db921c2de /libs/hwui/SkiaShader.cpp
parent572eab6f17a78a9483bbf4b3646aa5a6038ea210 (diff)
downloadframeworks_base-e3095e0c1e2a4a4f34f741aa386eae56536ca5aa.zip
frameworks_base-e3095e0c1e2a4a4f34f741aa386eae56536ca5aa.tar.gz
frameworks_base-e3095e0c1e2a4a4f34f741aa386eae56536ca5aa.tar.bz2
Apply 3D transformations to gradient shaders.
This fixes only linear gradients. Sweep and radial gradients, as well as bitmap shaders, will be fixed in a future commit. Change-Id: I4eee4ff62e9bbf3b9339fc111a780167449ecfef
Diffstat (limited to 'libs/hwui/SkiaShader.cpp')
-rw-r--r--libs/hwui/SkiaShader.cpp60
1 files changed, 41 insertions, 19 deletions
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 165c0da..83de2b2 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -153,11 +153,31 @@ void SkiaBitmapShader::updateTransforms(Program* program, const mat4& modelView,
// Linear gradient shader
///////////////////////////////////////////////////////////////////////////////
+static void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) {
+ SkVector vec = pts[1] - pts[0];
+ const float mag = vec.length();
+ const float inv = mag ? 1.0f / mag : 0;
+
+ vec.scale(inv);
+ matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
+ matrix->postTranslate(-pts[0].fX, -pts[0].fY);
+ matrix->postScale(inv, inv);
+}
+
SkiaLinearGradientShader::SkiaLinearGradientShader(float* bounds, uint32_t* colors,
float* positions, int count, SkShader* key, SkShader::TileMode tileMode,
SkMatrix* matrix, bool blend):
SkiaShader(kLinearGradient, key, tileMode, tileMode, matrix, blend),
mBounds(bounds), mColors(colors), mPositions(positions), mCount(count) {
+ SkPoint points[2];
+ points[0].set(bounds[0], bounds[1]);
+ points[1].set(bounds[2], bounds[3]);
+
+ SkMatrix unitMatrix;
+ toUnitMatrix(points, &unitMatrix);
+ mUnitMatrix.load(unitMatrix);
+
+ updateLocalMatrix(matrix);
}
SkiaLinearGradientShader::~SkiaLinearGradientShader() {
@@ -172,6 +192,23 @@ void SkiaLinearGradientShader::describe(ProgramDescription& description,
description.gradientType = ProgramDescription::kGradientLinear;
}
+void SkiaLinearGradientShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) {
+ screenSpace.loadMultiply(mUnitMatrix, mShaderMatrix);
+ screenSpace.multiply(modelView);
+}
+
+void SkiaLinearGradientShader::updateLocalMatrix(const SkMatrix* matrix) {
+ if (matrix) {
+ mat4 localMatrix(*matrix);
+ mShaderMatrix.loadInverse(localMatrix);
+ }
+}
+
+void SkiaLinearGradientShader::setMatrix(SkMatrix* matrix) {
+ SkiaShader::setMatrix(matrix);
+ updateLocalMatrix(matrix);
+}
+
void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView,
const Snapshot& snapshot, GLuint* textureUnit) {
GLuint textureSlot = (*textureUnit)++;
@@ -182,34 +219,19 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV
texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX);
}
- Rect start(mBounds[0], mBounds[1], mBounds[2], mBounds[3]);
- if (mMatrix) {
- mat4 shaderMatrix(*mMatrix);
- shaderMatrix.mapPoint(start.left, start.top);
- shaderMatrix.mapPoint(start.right, start.bottom);
- }
- snapshot.transform->mapRect(start);
-
- const float gradientX = start.right - start.left;
- const float gradientY = start.bottom - start.top;
-
- mat4 screenSpace(*snapshot.transform);
- screenSpace.multiply(modelView);
+ mat4 screenSpace;
+ computeScreenSpaceMatrix(screenSpace, modelView);
// Uniforms
bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
glUniform1i(program->getUniform("gradientSampler"), textureSlot);
- glUniform2f(program->getUniform("gradientStart"), start.left, start.top);
- glUniform2f(program->getUniform("gradient"), gradientX, gradientY);
- glUniform1f(program->getUniform("gradientLength"),
- 1.0f / (gradientX * gradientX + gradientY * gradientY));
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
}
void SkiaLinearGradientShader::updateTransforms(Program* program, const mat4& modelView,
const Snapshot& snapshot) {
- mat4 screenSpace(*snapshot.transform);
- screenSpace.multiply(modelView);
+ mat4 screenSpace;
+ computeScreenSpaceMatrix(screenSpace, modelView);
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
}