SkiaShader.cpp revision 2dc236b2bae13b9a0ed9b3f7320502aecd7983b3
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 23a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy#include "Caches.h" 242dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "Extensions.h" 25d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Layer.h" 26d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Matrix.h" 2706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "SkiaShader.h" 2806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "Texture.h" 2906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3006f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace android { 3106f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace uirenderer { 3206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Support 3506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3706f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic const GLint gTileModes[] = { 3806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode 3906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_REPEAT, // == SkShader::kRepeat_Mode 4006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode 4106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; 4206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 4342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy/** 4442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy * This function does not work for n == 0. 4542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy */ 4642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guystatic inline bool isPowerOfTwo(unsigned int n) { 4742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy return !(n & (n - 1)); 4842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy} 4942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 5042e1e0d482d774cf18a55773e434f02edb9e4462Romain Guystatic inline void bindUniformColor(int slot, uint32_t color) { 51d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy const float a = ((color >> 24) & 0xff) / 255.0f; 5242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy glUniform4f(slot, 53d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a * ((color >> 16) & 0xff) / 255.0f, 54d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a * ((color >> 8) & 0xff) / 255.0f, 55d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a * ((color ) & 0xff) / 255.0f, 56d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a); 5742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy} 5842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 59d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) { 60d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->bindTexture(texture->id); 61d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III texture->setWrapST(wrapS, wrapT); 6224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 6324c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 64d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/** 65d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * Compute the matrix to transform to screen space. 66d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param screenSpace Output param for the computed matrix. 67d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param unitMatrix The unit matrix for gradient shaders, as returned by SkShader::asAGradient, 68d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * or identity. 69d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param localMatrix Local matrix, as returned by SkShader::getLocalMatrix(). 70d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param modelViewMatrix Model view matrix, as supplied by the OpenGLRenderer. 71d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III */ 72d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic void computeScreenSpaceMatrix(mat4& screenSpace, const SkMatrix& unitMatrix, 73d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkMatrix& localMatrix, const mat4& modelViewMatrix) { 74d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mat4 shaderMatrix; 75d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // uses implicit construction 76d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderMatrix.loadInverse(localMatrix); 77d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // again, uses implicit construction 78d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.loadMultiply(unitMatrix, shaderMatrix); 79d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.multiply(modelViewMatrix); 80d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 81d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 82d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III// Returns true if one is a bitmap and the other is a gradient 83d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool bitmapAndGradient(SkiaShaderType type1, SkiaShaderType type2) { 84d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return (type1 == kBitmap_SkiaShaderType && type2 == kGradient_SkiaShaderType) 85d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III || (type2 == kBitmap_SkiaShaderType && type1 == kGradient_SkiaShaderType); 86d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 87d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 88d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIISkiaShaderType SkiaShader::getType(const SkShader& shader) { 89d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // First check for a gradient shader. 90d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III switch (shader.asAGradient(NULL)) { 91d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kNone_GradientType: 92d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Not a gradient shader. Fall through to check for other types. 93d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 94d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kLinear_GradientType: 95d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kRadial_GradientType: 96d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kSweep_GradientType: 97d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kGradient_SkiaShaderType; 98d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III default: 99d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // This is a Skia gradient that has no SkiaShader equivalent. Return None to skip. 100d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kNone_SkiaShaderType; 101d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 1028aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 103d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // The shader is not a gradient. Check for a bitmap shader. 104d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType) { 105d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kBitmap_SkiaShaderType; 106d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 10706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 108d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Check for a ComposeShader. 109d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::ComposeRec rec; 110d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asACompose(&rec)) { 111d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkiaShaderType shaderAType = getType(*rec.fShaderA); 112d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkiaShaderType shaderBType = getType(*rec.fShaderB); 113d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 114d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Compose is only supported if one is a bitmap and the other is a 115d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // gradient. Otherwise, return None to skip. 116d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!bitmapAndGradient(shaderAType, shaderBType)) { 117d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kNone_SkiaShaderType; 118d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 119d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kCompose_SkiaShaderType; 120d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 12106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 122d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asACustomShader(NULL)) { 123d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kLayer_SkiaShaderType; 124d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 12506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 126d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kNone_SkiaShaderType; 12706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 12806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 129d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIItypedef void (*describeProc)(Caches* caches, ProgramDescription& description, 130d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader); 131d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 132d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIdescribeProc gDescribeProc[] = { 133d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III InvalidSkiaShader::describe, 134d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaBitmapShader::describe, 135d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaGradientShader::describe, 136d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaComposeShader::describe, 137d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaLayerShader::describe, 138d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III}; 139d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 140d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIItypedef void (*setupProgramProc)(Caches* caches, const mat4& modelViewMatrix, 141d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); 142d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 143d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIsetupProgramProc gSetupProgramProc[] = { 144d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III InvalidSkiaShader::setupProgram, 145d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaBitmapShader::setupProgram, 146d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaGradientShader::setupProgram, 147d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaComposeShader::setupProgram, 148d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaLayerShader::setupProgram, 149d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III}; 150d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 151d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaShader::describe(Caches* caches, ProgramDescription& description, 152d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 153d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gDescribeProc[getType(shader)](caches, description, extensions, shader); 15406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 15506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 156d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 157d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { 158d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 159d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gSetupProgramProc[getType(shader)](caches, modelViewMatrix, textureUnit, extensions, shader); 16014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 16114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 16206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 1633f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik// Layer shader 1643f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik/////////////////////////////////////////////////////////////////////////////// 1653f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 166d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaLayerShader::describe(Caches*, ProgramDescription& description, 167d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions&, const SkShader& shader) { 1683f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik description.hasBitmap = true; 1693f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik} 1703f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 171d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaLayerShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 172d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions&, const SkShader& shader) { 173d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Layer* layer; 174d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) { 175d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaLayerShader::setupProgram called on the wrong type of shader!"); 176d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 177d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 1783f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik GLuint textureSlot = (*textureUnit)++; 179d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->activeTexture(textureSlot); 1803f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 181d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const float width = layer->getWidth(); 182d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const float height = layer->getHeight(); 1833f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 1843f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik mat4 textureTransform; 185d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 186d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III modelViewMatrix); 187d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 1883f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 1893f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik // Uniforms 190d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III layer->bindTexture(); 191d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III layer->setWrap(GL_CLAMP_TO_EDGE); 192d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III layer->setFilter(GL_LINEAR); 1933f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 194d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Program* program = caches->currentProgram; 1953f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik glUniform1i(program->getUniform("bitmapSampler"), textureSlot); 1963f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 1973f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik GL_FALSE, &textureTransform.data[0]); 1983f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height); 1993f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik} 2003f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 2013f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik/////////////////////////////////////////////////////////////////////////////// 20206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Bitmap shader 20306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 20406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 205d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstruct BitmapShaderInfo { 206d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III float width; 207d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III float height; 208d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLenum wrapS; 209d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLenum wrapT; 210d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture; 211d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III}; 21224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 213d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool bitmapShaderHelper(Caches* caches, ProgramDescription* description, 214d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III BitmapShaderInfo* shaderInfo, 215d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, 216d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkBitmap& bitmap, SkShader::TileMode tileModes[2]) { 217d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture = caches->textureCache.get(&bitmap); 218d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!texture) return false; 21906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 22006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float width = texture->width; 22106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float height = texture->height; 222d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLenum wrapS, wrapT; 22306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 224d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (description) { 225d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->hasBitmap = true; 226d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 22706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // The driver does not support non-power of two mirrored/repeated 22806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // textures, so do it ourselves 22961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) && 230d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III (tileModes[0] != SkShader::kClamp_TileMode || 231d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III tileModes[1] != SkShader::kClamp_TileMode)) { 232d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (description) { 233d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->isBitmapNpot = true; 234d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->bitmapWrapS = gTileModes[tileModes[0]]; 235d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->bitmapWrapT = gTileModes[tileModes[1]]; 236d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 237d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapS = GL_CLAMP_TO_EDGE; 238d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapT = GL_CLAMP_TO_EDGE; 23929d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy } else { 240d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapS = gTileModes[tileModes[0]]; 241d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapT = gTileModes[tileModes[1]]; 242d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 243d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 244d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shaderInfo) { 245d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->width = width; 246d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->height = height; 247d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->wrapS = wrapS; 248d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->wrapT = wrapT; 249d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->texture = texture; 25006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 251d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return true; 25206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 25306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 254d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaBitmapShader::describe(Caches* caches, ProgramDescription& description, 255d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 256d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkBitmap bitmap; 257d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::TileMode xy[2]; 258d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { 259d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaBitmapShader::describe called with a different kind of shader!"); 260d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 261d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bitmapShaderHelper(caches, &description, NULL, extensions, bitmap, xy); 262d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 263d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 264d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 265d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { 266d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkBitmap bitmap; 267d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::TileMode xy[2]; 268d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { 269d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaBitmapShader::setupProgram called with a different kind of shader!"); 270d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 271d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 27206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint textureSlot = (*textureUnit)++; 273a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy Caches::getInstance().activeTexture(textureSlot); 2749cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy 275d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III BitmapShaderInfo shaderInfo; 276d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!bitmapShaderHelper(caches, NULL, &shaderInfo, extensions, bitmap, xy)) { 277d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return; 278d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 27906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 280d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Program* program = caches->currentProgram; 281d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture = shaderInfo.texture; 282d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 283d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const AutoTexture autoCleanup(texture); 28406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 28506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mat4 textureTransform; 286d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 287d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III modelViewMatrix); 28806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 28906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // Uniforms 290d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindTexture(caches, texture, shaderInfo.wrapS, shaderInfo.wrapT); 291d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy texture->setFilter(GL_LINEAR); 292e3c26851dc315b730ea0fe5ef35bb1db81f6d675Romain Guy 29306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform1i(program->getUniform("bitmapSampler"), textureSlot); 29406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 29506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_FALSE, &textureTransform.data[0]); 296d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III glUniform2f(program->getUniform("textureDimension"), 1.0f / shaderInfo.width, 297d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 1.0f / shaderInfo.height); 29806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 29906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 30006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 30106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Linear gradient shader 30206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 30306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 304e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guystatic void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { 305e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkVector vec = pts[1] - pts[0]; 306e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float mag = vec.length(); 307e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float inv = mag ? 1.0f / mag : 0; 308e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 309e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy vec.scale(inv); 310e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 311e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postTranslate(-pts[0].fX, -pts[0].fY); 312e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postScale(inv, inv); 313e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy} 314e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 31506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 316ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy// Circular gradient shader 317ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy/////////////////////////////////////////////////////////////////////////////// 318ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 31914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toCircularUnitMatrix(const float x, const float y, const float radius, 32014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix* matrix) { 32114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy const float inv = 1.0f / radius; 32214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 32314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->postScale(inv, inv); 32414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 32514830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 326ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy/////////////////////////////////////////////////////////////////////////////// 327ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy// Sweep gradient shader 328ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 329ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 33014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { 33114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 33214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 33314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 334d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 335d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III// Common gradient code 336d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 33724c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 338d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) { 339d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode; 340d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 341d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 342d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaGradientShader::describe(Caches*, ProgramDescription& description, 343d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 344d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::GradientInfo gradInfo; 345d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorCount = 0; 346d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColors = NULL; 347d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorOffsets = NULL; 348d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 349d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III switch (shader.asAGradient(&gradInfo)) { 350d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kLinear_GradientType: 351d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.gradientType = ProgramDescription::kGradientLinear; 352d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 353d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kRadial_GradientType: 354d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.gradientType = ProgramDescription::kGradientCircular; 355d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 356d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kSweep_GradientType: 357d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.gradientType = ProgramDescription::kGradientSweep; 358d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 359d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III default: 360d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Do nothing. This shader is unsupported. 361d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return; 362d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 363ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.hasGradient = true; 364d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.isSimpleGradient = isSimpleGradient(gradInfo); 365d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 366d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 367d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaGradientShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 368d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions&, const SkShader& shader) { 369d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // SkShader::GradientInfo.fColorCount is an in/out parameter. As input, it tells asAGradient 370d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // how much space has been allocated for fColors and fColorOffsets. 10 was chosen 371d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // arbitrarily, but should be >= 2. 372d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // As output, it tells the number of actual colors/offsets in the gradient. 373d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const int COLOR_COUNT = 10; 374d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkAutoSTMalloc<COLOR_COUNT, SkColor> colorStorage(COLOR_COUNT); 375d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkAutoSTMalloc<COLOR_COUNT, SkScalar> positionStorage(COLOR_COUNT); 376d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 377d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::GradientInfo gradInfo; 378d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorCount = COLOR_COUNT; 379d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColors = colorStorage.get(); 380d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorOffsets = positionStorage.get(); 381d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 382d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::GradientType gradType = shader.asAGradient(&gradInfo); 383d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 384d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Program* program = caches->currentProgram; 385d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (CC_UNLIKELY(!isSimpleGradient(gradInfo))) { 386d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (gradInfo.fColorCount > COLOR_COUNT) { 387d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // There was not enough room in our arrays for all the colors and offsets. Try again, 388d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // now that we know the true number of colors. 389d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColors = colorStorage.reset(gradInfo.fColorCount); 390d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorOffsets = positionStorage.reset(gradInfo.fColorCount); 391d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 392d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shader.asAGradient(&gradInfo); 393d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 39442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy GLuint textureSlot = (*textureUnit)++; 395d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->activeTexture(textureSlot); 396ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 397d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#ifndef SK_SCALAR_IS_FLOAT 398d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III #error Need to convert gradInfo.fColorOffsets to float! 399d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#endif 400d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture = caches->gradientCache.get(gradInfo.fColors, gradInfo.fColorOffsets, 401d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorCount); 40242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 40342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy // Uniforms 404d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindTexture(caches, texture, gTileModes[gradInfo.fTileMode], gTileModes[gradInfo.fTileMode]); 40542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy glUniform1i(program->getUniform("gradientSampler"), textureSlot); 40642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } else { 407d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindUniformColor(program->getUniform("startColor"), gradInfo.fColors[0]); 408d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindUniformColor(program->getUniform("endColor"), gradInfo.fColors[1]); 40942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } 410ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 411d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->dither.setupProgram(program, textureUnit); 412d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 413d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkMatrix unitMatrix; 414d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III switch (gradType) { 415d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kLinear_GradientType: 416d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III toUnitMatrix(gradInfo.fPoint, &unitMatrix); 417d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 418d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kRadial_GradientType: 419d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, 420d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fRadius[0], &unitMatrix); 421d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 422d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kSweep_GradientType: 423d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix); 424d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 425d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III default: 426d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("Invalid SkShader gradient type %d", gradType); 427d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 428211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 42914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mat4 screenSpace; 430d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(screenSpace, unitMatrix, shader.getLocalMatrix(), modelViewMatrix); 431ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 432ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 433ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 434ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 43506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Compose shader 43606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 43706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 438d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaComposeShader::describe(Caches* caches, ProgramDescription& description, 439d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 440d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::ComposeRec rec; 441d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!shader.asACompose(&rec)) { 442d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaComposeShader::describe called on the wrong shader type!"); 44343ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy } 444d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::describe(caches, description, extensions, *rec.fShaderA); 445d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::describe(caches, description, extensions, *rec.fShaderB); 446d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (SkiaShader::getType(*rec.fShaderA) == kBitmap_SkiaShaderType) { 44706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.isBitmapFirst = true; 44806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 449d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!SkXfermode::AsMode(rec.fMode, &description.shadersMode)) { 450d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // TODO: Support other modes. 451d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.shadersMode = SkXfermode::kSrcOver_Mode; 452d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 45306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 45406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 455d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaComposeShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 456d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { 457d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::ComposeRec rec; 458d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!shader.asACompose(&rec)) { 459d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaComposeShader::setupProgram called on the wrong shader type!"); 460d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 461d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 462d4289922ce772ed8e170a27d1c9521672b315698Romain Guy // Apply this compose shader's local transform and pass it down to 463d4289922ce772ed8e170a27d1c9521672b315698Romain Guy // the child shaders. They will in turn apply their local transform 464d4289922ce772ed8e170a27d1c9521672b315698Romain Guy // to this matrix. 465d4289922ce772ed8e170a27d1c9521672b315698Romain Guy mat4 transform; 466d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(transform, SkMatrix::I(), shader.getLocalMatrix(), 467d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III modelViewMatrix); 468d4289922ce772ed8e170a27d1c9521672b315698Romain Guy 469d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderA); 470d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderB); 47106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 47206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 47306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace uirenderer 47406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace android 475