summaryrefslogtreecommitdiffstats
path: root/libs/hwui/SkiaShader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/SkiaShader.cpp')
-rw-r--r--libs/hwui/SkiaShader.cpp88
1 files changed, 52 insertions, 36 deletions
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 66993a4..9013fd5 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -38,6 +38,22 @@ static const GLint gTileModes[] = {
GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode
};
+/**
+ * This function does not work for n == 0.
+ */
+static inline bool isPowerOfTwo(unsigned int n) {
+ return !(n & (n - 1));
+}
+
+static inline void bindUniformColor(int slot, uint32_t color) {
+ const float a = ((color >> 24) & 0xff) / 255.0f;
+ glUniform4f(slot,
+ a * ((color >> 16) & 0xff) / 255.0f,
+ a * ((color >> 8) & 0xff) / 255.0f,
+ a * ((color ) & 0xff) / 255.0f,
+ a);
+}
+
///////////////////////////////////////////////////////////////////////////////
// Base shader
///////////////////////////////////////////////////////////////////////////////
@@ -139,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);
@@ -151,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
///////////////////////////////////////////////////////////////////////////////
@@ -188,6 +192,8 @@ SkiaLinearGradientShader::SkiaLinearGradientShader(float* bounds, uint32_t* colo
mUnitMatrix.load(unitMatrix);
updateLocalMatrix(matrix);
+
+ mIsSimple = count == 2 && tileMode == SkShader::kClamp_TileMode;
}
SkiaLinearGradientShader::~SkiaLinearGradientShader() {
@@ -206,6 +212,7 @@ SkiaShader* SkiaLinearGradientShader::copy() {
copy->mPositions = new float[mCount];
memcpy(copy->mPositions, mPositions, sizeof(float) * mCount);
copy->mCount = mCount;
+ copy->mIsSimple = mIsSimple;
return copy;
}
@@ -213,26 +220,27 @@ void SkiaLinearGradientShader::describe(ProgramDescription& description,
const Extensions& extensions) {
description.hasGradient = true;
description.gradientType = ProgramDescription::kGradientLinear;
+ description.isSimpleGradient = mIsSimple;
}
void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView,
const Snapshot& snapshot, GLuint* textureUnit) {
- GLuint textureSlot = (*textureUnit)++;
- Caches::getInstance().activeTexture(textureSlot);
+ if (CC_UNLIKELY(!mIsSimple)) {
+ GLuint textureSlot = (*textureUnit)++;
+ Caches::getInstance().activeTexture(textureSlot);
- Texture* texture = mGradientCache->get(mColors, mPositions, mCount, mTileX);
+ Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
- mat4 screenSpace;
- computeScreenSpaceMatrix(screenSpace, modelView);
+ // Uniforms
+ bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
+ glUniform1i(program->getUniform("gradientSampler"), textureSlot);
+ } else {
+ bindUniformColor(program->getUniform("startColor"), mColors[0]);
+ bindUniformColor(program->getUniform("endColor"), mColors[1]);
+ }
- // Uniforms
- bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
- glUniform1i(program->getUniform("gradientSampler"), textureSlot);
- glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
-}
+ Caches::getInstance().dither.setupProgram(program, textureUnit);
-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]);
@@ -269,6 +277,7 @@ SkiaShader* SkiaCircularGradientShader::copy() {
copy->mPositions = new float[mCount];
memcpy(copy->mPositions, mPositions, sizeof(float) * mCount);
copy->mCount = mCount;
+ copy->mIsSimple = mIsSimple;
return copy;
}
@@ -276,6 +285,7 @@ void SkiaCircularGradientShader::describe(ProgramDescription& description,
const Extensions& extensions) {
description.hasGradient = true;
description.gradientType = ProgramDescription::kGradientCircular;
+ description.isSimpleGradient = mIsSimple;
}
///////////////////////////////////////////////////////////////////////////////
@@ -296,6 +306,8 @@ SkiaSweepGradientShader::SkiaSweepGradientShader(float x, float y, uint32_t* col
mUnitMatrix.load(unitMatrix);
updateLocalMatrix(matrix);
+
+ mIsSimple = count == 2;
}
SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors,
@@ -303,6 +315,8 @@ SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, float x, float y, ui
SkMatrix* matrix, bool blend):
SkiaShader(type, key, tileMode, tileMode, matrix, blend),
mColors(colors), mPositions(positions), mCount(count) {
+
+ mIsSimple = count == 2 && tileMode == SkShader::kClamp_TileMode;
}
SkiaSweepGradientShader::~SkiaSweepGradientShader() {
@@ -318,6 +332,7 @@ SkiaShader* SkiaSweepGradientShader::copy() {
copy->mPositions = new float[mCount];
memcpy(copy->mPositions, mPositions, sizeof(float) * mCount);
copy->mCount = mCount;
+ copy->mIsSimple = mIsSimple;
return copy;
}
@@ -325,26 +340,27 @@ void SkiaSweepGradientShader::describe(ProgramDescription& description,
const Extensions& extensions) {
description.hasGradient = true;
description.gradientType = ProgramDescription::kGradientSweep;
+ description.isSimpleGradient = mIsSimple;
}
void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelView,
const Snapshot& snapshot, GLuint* textureUnit) {
- GLuint textureSlot = (*textureUnit)++;
- Caches::getInstance().activeTexture(textureSlot);
+ if (CC_UNLIKELY(!mIsSimple)) {
+ GLuint textureSlot = (*textureUnit)++;
+ Caches::getInstance().activeTexture(textureSlot);
- Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
+ Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
- mat4 screenSpace;
- computeScreenSpaceMatrix(screenSpace, modelView);
+ // Uniforms
+ bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
+ glUniform1i(program->getUniform("gradientSampler"), textureSlot);
+ } else {
+ bindUniformColor(program->getUniform("startColor"), mColors[0]);
+ bindUniformColor(program->getUniform("endColor"), mColors[1]);
+ }
- // Uniforms
- bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
- glUniform1i(program->getUniform("gradientSampler"), textureSlot);
- glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
-}
+ Caches::getInstance().dither.setupProgram(program, textureUnit);
-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]);