SkiaShader.cpp revision ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6f
106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/* 206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * Copyright (C) 2010 The Android Open Source Project 306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * 406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * you may not use this file except in compliance with the License. 606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * You may obtain a copy of the License at 706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * 806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * 1006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * Unless required by applicable law or agreed to in writing, software 1106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 1206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * See the License for the specific language governing permissions and 1406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy * limitations under the License. 1506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy */ 1606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 1706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#define LOG_TAG "OpenGLRenderer" 1806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 1906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include <utils/Log.h> 2006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 2106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include <SkMatrix.h> 2206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 2306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "SkiaShader.h" 2406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "Texture.h" 2506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "Matrix.h" 2606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 2706f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace android { 2806f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace uirenderer { 2906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Support 3206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3406f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic const GLenum gTextureUnitsMap[] = { 3506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_TEXTURE0, 3606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_TEXTURE1, 3706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_TEXTURE2 3806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; 3906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 4006f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic const GLint gTileModes[] = { 4106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode 4206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_REPEAT, // == SkShader::kRepeat_Mode 4306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode 4406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; 4506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 4606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 4706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Base shader 4806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 4906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 5006f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, 5106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkShader::TileMode tileY, SkMatrix* matrix, bool blend): 5206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mMatrix(matrix), mBlend(blend) { 5306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 5406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 5506f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaShader::~SkiaShader() { 5606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 5706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 5806f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaShader::describe(ProgramDescription& description, const Extensions& extensions) { 5906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 6006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 6106f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaShader::setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 6206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint* textureUnit) { 6306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 6406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 6506f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { 6606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glActiveTexture(gTextureUnitsMap[textureUnit]); 6706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glBindTexture(GL_TEXTURE_2D, texture); 6806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); 6906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); 7006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 7106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 7206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 7306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Bitmap shader 7406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 7506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 7606f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, 7706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkShader::TileMode tileY, SkMatrix* matrix, bool blend): 789cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy SkiaShader(kBitmap, key, tileX, tileY, matrix, blend), mBitmap(bitmap), mTexture(NULL) { 7906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 8006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 8106f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { 8206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Texture* texture = mTextureCache->get(mBitmap); 839cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy if (!texture) return; 849cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy mTexture = texture; 8506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 8606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float width = texture->width; 8706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float height = texture->height; 8806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 8906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.hasBitmap = true; 9006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // The driver does not support non-power of two mirrored/repeated 9106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // textures, so do it ourselves 9261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) && 9361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy (mTileX != SkShader::kClamp_TileMode || mTileY != SkShader::kClamp_TileMode)) { 9406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.isBitmapNpot = true; 9506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.bitmapWrapS = gTileModes[mTileX]; 9606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.bitmapWrapT = gTileModes[mTileY]; 9706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 9806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 9906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 10006f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, 10106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 10206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint textureSlot = (*textureUnit)++; 10306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glActiveTexture(gTextureUnitsMap[textureSlot]); 1049cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy 1059cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy const Texture* texture = mTexture; 1069cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy mTexture = NULL; 1079cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy if (!texture) return; 1089cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy const AutoTexture autoCleanup(texture); 10906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 11006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float width = texture->width; 11106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float height = texture->height; 11206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 11306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mat4 textureTransform; 11406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (mMatrix) { 11506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkMatrix inverse; 11606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mMatrix->invert(&inverse); 11706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy textureTransform.load(inverse); 11806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy textureTransform.multiply(modelView); 11906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } else { 12006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy textureTransform.load(modelView); 12106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 12206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 12306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // Uniforms 12406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); 12506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform1i(program->getUniform("bitmapSampler"), textureSlot); 12606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 12706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_FALSE, &textureTransform.data[0]); 12806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height); 12906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 13006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 131759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guyvoid SkiaBitmapShader::updateTransforms(Program* program, const mat4& modelView, 132759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy const Snapshot& snapshot) { 133759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy mat4 textureTransform; 134759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy if (mMatrix) { 135759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy SkMatrix inverse; 136759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy mMatrix->invert(&inverse); 137759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy textureTransform.load(inverse); 138759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy textureTransform.multiply(modelView); 139759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy } else { 140759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy textureTransform.load(modelView); 141759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy } 142759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy 143759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 144759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy GL_FALSE, &textureTransform.data[0]); 145759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy} 146759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy 14706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 14806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Linear gradient shader 14906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 15006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 15106f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaLinearGradientShader::SkiaLinearGradientShader(float* bounds, uint32_t* colors, 15206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy float* positions, int count, SkShader* key, SkShader::TileMode tileMode, 15306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkMatrix* matrix, bool blend): 15406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader(kLinearGradient, key, tileMode, tileMode, matrix, blend), 15506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mBounds(bounds), mColors(colors), mPositions(positions), mCount(count) { 15606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 15706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 15806f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaLinearGradientShader::~SkiaLinearGradientShader() { 15925ee037fee1607e8a77b1f2e259356e74dd6f645Romain Guy delete[] mBounds; 16025ee037fee1607e8a77b1f2e259356e74dd6f645Romain Guy delete[] mColors; 16125ee037fee1607e8a77b1f2e259356e74dd6f645Romain Guy delete[] mPositions; 16206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 16306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 16406f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaLinearGradientShader::describe(ProgramDescription& description, 16506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Extensions& extensions) { 16606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.hasGradient = true; 167ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.gradientType = ProgramDescription::kGradientLinear; 16806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 16906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 17006f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView, 17106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 17206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint textureSlot = (*textureUnit)++; 17306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glActiveTexture(gTextureUnitsMap[textureSlot]); 17406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 17506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy Texture* texture = mGradientCache->get(mKey); 17606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (!texture) { 177ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX); 17806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 17906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 18006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy Rect start(mBounds[0], mBounds[1], mBounds[2], mBounds[3]); 18106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (mMatrix) { 18206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mat4 shaderMatrix(*mMatrix); 1830ba681bce12d522c5575dfccb5a6ca12f0fba746Romain Guy shaderMatrix.mapPoint(start.left, start.top); 1840ba681bce12d522c5575dfccb5a6ca12f0fba746Romain Guy shaderMatrix.mapPoint(start.right, start.bottom); 18506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 1868aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy snapshot.transform->mapRect(start); 18706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 18806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float gradientX = start.right - start.left; 18906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float gradientY = start.bottom - start.top; 19006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 1918aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy mat4 screenSpace(*snapshot.transform); 19206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy screenSpace.multiply(modelView); 19306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 19406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // Uniforms 19506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); 19606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform1i(program->getUniform("gradientSampler"), textureSlot); 19706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform2f(program->getUniform("gradientStart"), start.left, start.top); 19806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform2f(program->getUniform("gradient"), gradientX, gradientY); 19906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform1f(program->getUniform("gradientLength"), 20006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 1.0f / (gradientX * gradientX + gradientY * gradientY)); 20106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 20206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 20306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 204759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guyvoid SkiaLinearGradientShader::updateTransforms(Program* program, const mat4& modelView, 205759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy const Snapshot& snapshot) { 206759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy mat4 screenSpace(*snapshot.transform); 207759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy screenSpace.multiply(modelView); 208759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 209759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy} 210759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy 21106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 212ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy// Sweep gradient shader 213ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 214ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 215ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain GuySkiaSweepGradientShader::SkiaSweepGradientShader(float x, float y, uint32_t* colors, 216ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy float* positions, int count, SkShader* key, SkMatrix* matrix, bool blend): 217ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy SkiaShader(kSweepGradient, key, SkShader::kClamp_TileMode, 218ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy SkShader::kClamp_TileMode, matrix, blend), 219ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy mX(x), mY(y), mColors(colors), mPositions(positions), mCount(count) { 220ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 221ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 222ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain GuySkiaSweepGradientShader::~SkiaSweepGradientShader() { 223ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy delete[] mColors; 224ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy delete[] mPositions; 225ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 226ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 227ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guyvoid SkiaSweepGradientShader::describe(ProgramDescription& description, 228ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const Extensions& extensions) { 229ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.hasGradient = true; 230ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.gradientType = ProgramDescription::kGradientSweep; 231ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 232ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 233ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guyvoid SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelView, 234ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 235ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy GLuint textureSlot = (*textureUnit)++; 236ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glActiveTexture(gTextureUnitsMap[textureSlot]); 237ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 238ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy Texture* texture = mGradientCache->get(mKey); 239ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy if (!texture) { 240ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount); 241ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy } 242ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 243ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy float left = mX; 244ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy float top = mY; 245ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 246ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy if (mMatrix) { 247ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy mat4 shaderMatrix(*mMatrix); 248ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy shaderMatrix.mapPoint(left, top); 249ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy } 250ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy snapshot.transform->mapPoint(left, top); 251ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 252ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy mat4 screenSpace(*snapshot.transform); 253ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy screenSpace.multiply(modelView); 254ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 255ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy // Uniforms 256ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); 257ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniform1i(program->getUniform("gradientSampler"), textureSlot); 258ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniform2f(program->getUniform("gradientStart"), left, top); 259ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 260ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 261ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 262ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guyvoid SkiaSweepGradientShader::updateTransforms(Program* program, const mat4& modelView, 263ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const Snapshot& snapshot) { 264ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy mat4 screenSpace(*snapshot.transform); 265ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy screenSpace.multiply(modelView); 266ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 267ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 268ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 269ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 27006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Compose shader 27106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 27206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 27306f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaComposeShader::SkiaComposeShader(SkiaShader* first, SkiaShader* second, 27406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkXfermode::Mode mode, SkShader* key): 27506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader(kCompose, key, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, 27606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy NULL, first->blend() || second->blend()), mFirst(first), mSecond(second), mMode(mode) { 27706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 27806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 27906f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaComposeShader::set(TextureCache* textureCache, GradientCache* gradientCache) { 28006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader::set(textureCache, gradientCache); 28106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mFirst->set(textureCache, gradientCache); 28206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mSecond->set(textureCache, gradientCache); 28306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 28406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 28506f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaComposeShader::describe(ProgramDescription& description, const Extensions& extensions) { 28606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mFirst->describe(description, extensions); 28706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mSecond->describe(description, extensions); 28806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (mFirst->type() == kBitmap) { 28906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.isBitmapFirst = true; 29006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 29106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.shadersMode = mMode; 29206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 29306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 29406f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaComposeShader::setupProgram(Program* program, const mat4& modelView, 29506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 29606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mFirst->setupProgram(program, modelView, snapshot, textureUnit); 29706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mSecond->setupProgram(program, modelView, snapshot, textureUnit); 29806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 29906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 30006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace uirenderer 30106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace android 302