diff options
Diffstat (limited to 'libs/hwui/SkiaShader.cpp')
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 88 |
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]); |