SkiaShader.cpp revision 24c00216687ac87fe531dc4d4168ac0c0ca04ea6
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 5024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guyvoid SkiaShader::copyFrom(const SkiaShader& shader) { 5124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mType = shader.mType; 5224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mKey = shader.mKey; 5324c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mTileX = shader.mTileX; 5424c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mTileY = shader.mTileY; 5524c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mBlend = shader.mBlend; 5624c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mUnitMatrix = shader.mUnitMatrix; 5724c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mShaderMatrix = shader.mShaderMatrix; 5824c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mGenerationId = shader.mGenerationId; 5924c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 6024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 6106f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, 6206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkShader::TileMode tileY, SkMatrix* matrix, bool blend): 6314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend) { 6414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy setMatrix(matrix); 6524c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy mGenerationId = 0; 6606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 6706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 6806f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaShader::~SkiaShader() { 6906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 7006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 7106f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaShader::describe(ProgramDescription& description, const Extensions& extensions) { 7206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 7306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 7406f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaShader::setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 7506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint* textureUnit) { 7606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 7706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 7801d065795794fa56be660d6346e4830eb7e90a41Romain Guyvoid SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) { 798164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy glBindTexture(GL_TEXTURE_2D, texture->id); 808164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy if (wrapS != texture->wrapS) { 818164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); 828164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy texture->wrapS = wrapS; 838164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy } 848164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy if (wrapT != texture->wrapT) { 858164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); 868164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy texture->wrapT = wrapT; 878164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy } 8806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 8906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 9014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guyvoid SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) { 9114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy screenSpace.loadMultiply(mUnitMatrix, mShaderMatrix); 9214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy screenSpace.multiply(modelView); 9314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 9414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 9506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 9606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Bitmap shader 9706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 9806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 9906f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, 10006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkShader::TileMode tileY, SkMatrix* matrix, bool blend): 1019cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy SkiaShader(kBitmap, key, tileX, tileY, matrix, blend), mBitmap(bitmap), mTexture(NULL) { 10214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy updateLocalMatrix(matrix); 10306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 10406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 10524c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain GuySkiaShader* SkiaBitmapShader::copy() { 10624c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy SkiaBitmapShader* copy = new SkiaBitmapShader(); 10724c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->copyFrom(*this); 10824c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mBitmap = mBitmap; 10924c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy return copy; 11024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 11124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 11206f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { 1138164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy Texture* texture = mTextureCache->get(mBitmap); 1149cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy if (!texture) return; 1159cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy mTexture = texture; 11606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 11706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float width = texture->width; 11806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float height = texture->height; 11906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 12006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.hasBitmap = true; 12106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // The driver does not support non-power of two mirrored/repeated 12206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // textures, so do it ourselves 12361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) && 12461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy (mTileX != SkShader::kClamp_TileMode || mTileY != SkShader::kClamp_TileMode)) { 12506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.isBitmapNpot = true; 12606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.bitmapWrapS = gTileModes[mTileX]; 12706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.bitmapWrapT = gTileModes[mTileY]; 12829d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy mWrapS = GL_CLAMP_TO_EDGE; 12929d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy mWrapT = GL_CLAMP_TO_EDGE; 13029d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy } else { 13129d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy mWrapS = gTileModes[mTileX]; 13229d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy mWrapT = gTileModes[mTileY]; 13306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 13406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 13506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 13606f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, 13706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 13806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint textureSlot = (*textureUnit)++; 13906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glActiveTexture(gTextureUnitsMap[textureSlot]); 1409cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy 1418164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy Texture* texture = mTexture; 1429cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy mTexture = NULL; 1439cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy if (!texture) return; 1449cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy const AutoTexture autoCleanup(texture); 14506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 14606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float width = texture->width; 14706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float height = texture->height; 14806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 14906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mat4 textureTransform; 15014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy computeScreenSpaceMatrix(textureTransform, modelView); 15106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 15206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // Uniforms 15301d065795794fa56be660d6346e4830eb7e90a41Romain Guy bindTexture(texture, mWrapS, mWrapT); 15406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform1i(program->getUniform("bitmapSampler"), textureSlot); 15506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 15606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_FALSE, &textureTransform.data[0]); 15706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height); 15806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 15906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 160759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guyvoid SkiaBitmapShader::updateTransforms(Program* program, const mat4& modelView, 161759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy const Snapshot& snapshot) { 162759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy mat4 textureTransform; 16314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy computeScreenSpaceMatrix(textureTransform, modelView); 164759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 165759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy GL_FALSE, &textureTransform.data[0]); 166759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy} 167759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy 16806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 16906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Linear gradient shader 17006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 17106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 172e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guystatic void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { 173e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkVector vec = pts[1] - pts[0]; 174e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float mag = vec.length(); 175e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float inv = mag ? 1.0f / mag : 0; 176e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 177e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy vec.scale(inv); 178e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 179e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postTranslate(-pts[0].fX, -pts[0].fY); 180e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postScale(inv, inv); 181e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy} 182e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 18306f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaLinearGradientShader::SkiaLinearGradientShader(float* bounds, uint32_t* colors, 18406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy float* positions, int count, SkShader* key, SkShader::TileMode tileMode, 18506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkMatrix* matrix, bool blend): 18606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader(kLinearGradient, key, tileMode, tileMode, matrix, blend), 18706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mBounds(bounds), mColors(colors), mPositions(positions), mCount(count) { 188e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkPoint points[2]; 189e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy points[0].set(bounds[0], bounds[1]); 190e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy points[1].set(bounds[2], bounds[3]); 191e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 192e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkMatrix unitMatrix; 193e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy toUnitMatrix(points, &unitMatrix); 194e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy mUnitMatrix.load(unitMatrix); 195e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 196e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy updateLocalMatrix(matrix); 19706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 19806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 19906f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaLinearGradientShader::~SkiaLinearGradientShader() { 20025ee037fee1607e8a77b1f2e259356e74dd6f645Romain Guy delete[] mBounds; 20125ee037fee1607e8a77b1f2e259356e74dd6f645Romain Guy delete[] mColors; 20225ee037fee1607e8a77b1f2e259356e74dd6f645Romain Guy delete[] mPositions; 20306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 20406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 20524c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain GuySkiaShader* SkiaLinearGradientShader::copy() { 20624c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy SkiaLinearGradientShader* copy = new SkiaLinearGradientShader(); 20724c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->copyFrom(*this); 20824c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mBounds = mBounds; 20924c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mColors = mColors; 21024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mPositions = mPositions; 21124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mCount = mCount; 21224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy return copy; 21324c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 21424c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 21506f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaLinearGradientShader::describe(ProgramDescription& description, 21606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Extensions& extensions) { 21706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.hasGradient = true; 218ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.gradientType = ProgramDescription::kGradientLinear; 21906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 22006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 22106f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView, 22206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 22306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint textureSlot = (*textureUnit)++; 22406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glActiveTexture(gTextureUnitsMap[textureSlot]); 22506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 22606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy Texture* texture = mGradientCache->get(mKey); 22706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (!texture) { 228ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX); 22906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 23006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 231e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy mat4 screenSpace; 232e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy computeScreenSpaceMatrix(screenSpace, modelView); 23306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 23406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // Uniforms 23501d065795794fa56be660d6346e4830eb7e90a41Romain Guy bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]); 23606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform1i(program->getUniform("gradientSampler"), textureSlot); 23706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 23806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 23906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 240759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guyvoid SkiaLinearGradientShader::updateTransforms(Program* program, const mat4& modelView, 241759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy const Snapshot& snapshot) { 242e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy mat4 screenSpace; 243e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy computeScreenSpaceMatrix(screenSpace, modelView); 244759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 245759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy} 246759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy 24706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 248ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy// Circular gradient shader 249ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy/////////////////////////////////////////////////////////////////////////////// 250ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 25114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toCircularUnitMatrix(const float x, const float y, const float radius, 25214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix* matrix) { 25314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy const float inv = 1.0f / radius; 25414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 25514830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->postScale(inv, inv); 25614830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 25714830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 258ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain GuySkiaCircularGradientShader::SkiaCircularGradientShader(float x, float y, float radius, 259ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, 260ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy SkMatrix* matrix, bool blend): 261ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy SkiaSweepGradientShader(kCircularGradient, x, y, colors, positions, count, key, 26214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy tileMode, matrix, blend) { 26314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix unitMatrix; 26414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy toCircularUnitMatrix(x, y, radius, &unitMatrix); 26514830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mUnitMatrix.load(unitMatrix); 26614830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 26714830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy updateLocalMatrix(matrix); 268ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy} 269ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 27024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain GuySkiaShader* SkiaCircularGradientShader::copy() { 27124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy SkiaCircularGradientShader* copy = new SkiaCircularGradientShader(); 27224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->copyFrom(*this); 27324c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mColors = mColors; 27424c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mPositions = mPositions; 27524c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mCount = mCount; 27624c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy return copy; 27724c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 27824c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 279ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guyvoid SkiaCircularGradientShader::describe(ProgramDescription& description, 280ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy const Extensions& extensions) { 281ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy description.hasGradient = true; 282ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy description.gradientType = ProgramDescription::kGradientCircular; 283ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy} 284ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 285ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy/////////////////////////////////////////////////////////////////////////////// 286ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy// Sweep gradient shader 287ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 288ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 28914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { 29014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 29114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 29214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 293ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain GuySkiaSweepGradientShader::SkiaSweepGradientShader(float x, float y, uint32_t* colors, 294ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy float* positions, int count, SkShader* key, SkMatrix* matrix, bool blend): 295ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy SkiaShader(kSweepGradient, key, SkShader::kClamp_TileMode, 296ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy SkShader::kClamp_TileMode, matrix, blend), 29714830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mColors(colors), mPositions(positions), mCount(count) { 29814830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix unitMatrix; 29914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy toSweepUnitMatrix(x, y, &unitMatrix); 30014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mUnitMatrix.load(unitMatrix); 30114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 30214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy updateLocalMatrix(matrix); 303ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 304ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 305ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain GuySkiaSweepGradientShader::SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, 306ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy float* positions, int count, SkShader* key, SkShader::TileMode tileMode, 307ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy SkMatrix* matrix, bool blend): 308ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy SkiaShader(type, key, tileMode, tileMode, matrix, blend), 30914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mColors(colors), mPositions(positions), mCount(count) { 310ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy} 311ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 312ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain GuySkiaSweepGradientShader::~SkiaSweepGradientShader() { 313ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy delete[] mColors; 314ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy delete[] mPositions; 315ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 316ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 31724c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain GuySkiaShader* SkiaSweepGradientShader::copy() { 31824c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy SkiaSweepGradientShader* copy = new SkiaSweepGradientShader(); 31924c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->copyFrom(*this); 32024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mColors = mColors; 32124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mPositions = mPositions; 32224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mCount = mCount; 32324c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy return copy; 32424c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 32524c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 326ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guyvoid SkiaSweepGradientShader::describe(ProgramDescription& description, 327ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const Extensions& extensions) { 328ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.hasGradient = true; 329ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.gradientType = ProgramDescription::kGradientSweep; 330ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 331ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 332ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guyvoid SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelView, 333ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 334ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy GLuint textureSlot = (*textureUnit)++; 335ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glActiveTexture(gTextureUnitsMap[textureSlot]); 336ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 337ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy Texture* texture = mGradientCache->get(mKey); 338ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy if (!texture) { 339ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount); 340ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy } 341ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 34214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mat4 screenSpace; 34314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy computeScreenSpaceMatrix(screenSpace, modelView); 344ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 345ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy // Uniforms 34601d065795794fa56be660d6346e4830eb7e90a41Romain Guy bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]); 347ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniform1i(program->getUniform("gradientSampler"), textureSlot); 348ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 349ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 350ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 351ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guyvoid SkiaSweepGradientShader::updateTransforms(Program* program, const mat4& modelView, 352ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const Snapshot& snapshot) { 35314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mat4 screenSpace; 35414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy computeScreenSpaceMatrix(screenSpace, modelView); 355ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 356ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 357ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 358ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 35906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Compose shader 36006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 36106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 36206f96e2652e4855b6520ad9dd70583677605b79aRomain GuySkiaComposeShader::SkiaComposeShader(SkiaShader* first, SkiaShader* second, 36306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkXfermode::Mode mode, SkShader* key): 36406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader(kCompose, key, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, 36506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy NULL, first->blend() || second->blend()), mFirst(first), mSecond(second), mMode(mode) { 36606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 36706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 36824c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain GuySkiaShader* SkiaComposeShader::copy() { 36924c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy SkiaComposeShader* copy = new SkiaComposeShader(); 37024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->copyFrom(*this); 37124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mFirst = mFirst; 37224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mSecond = mSecond; 37324c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy copy->mMode = mMode; 37424c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy return copy; 37524c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 37624c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 37706f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaComposeShader::set(TextureCache* textureCache, GradientCache* gradientCache) { 37806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader::set(textureCache, gradientCache); 37906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mFirst->set(textureCache, gradientCache); 38006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mSecond->set(textureCache, gradientCache); 38106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 38206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 38306f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaComposeShader::describe(ProgramDescription& description, const Extensions& extensions) { 38406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mFirst->describe(description, extensions); 38506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mSecond->describe(description, extensions); 38606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (mFirst->type() == kBitmap) { 38706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.isBitmapFirst = true; 38806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 38906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.shadersMode = mMode; 39006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 39106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 39206f96e2652e4855b6520ad9dd70583677605b79aRomain Guyvoid SkiaComposeShader::setupProgram(Program* program, const mat4& modelView, 39306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const Snapshot& snapshot, GLuint* textureUnit) { 39406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mFirst->setupProgram(program, modelView, snapshot, textureUnit); 39506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mSecond->setupProgram(program, modelView, snapshot, textureUnit); 39606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 39706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 39806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace uirenderer 39906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace android 400